Dockerのコンテナ、ネットワークについて

4 min read読了の目安(約3800字

2年ほど前にDockerを雰囲気で触ったことはあるのですが、Dockerfileを自分で作ったりしっかり学習したことはなかったので今回勉強してみることにしました。
まずは使えるようにざっくりとした理解から入りたいので、正しくない点が多いと思います。
そういう意味では完全に初心者向けの内容となっておりますので、あしからず。

勉強したこと

1. コンテナについて
2. ネットワークについて

コンテナについて

用語

イメージ  
  バイナリファイル(kernelのモジュール)で、kernelによって実行される
  コンテナのもととなるもの

コンテナ  
  イメージを基に作成される
  イメージがプロセスとして実行されているときのインスタンス  


コンテナのコマンド

docker container run

内部操作

1. nginxのイメージをローカルキャッシュから探す
   => なければDocker Hubから最新版をダウンロード
2. イメージから新しいコンテナを作成
3. Docker内の仮想ネットワークに仮想IPを付与する
4. 80番のポートをホスト/コンテナ両方に開く(nginxのデフォルトが80番)
5. Dockerfile内のコマンドを使ってコンテナを起動する

オプション

1. --publish(-p) HOST_IP:CONTAINER_IP
  CONTAINER_IPをHOST_IPに割り当てることができる
2. --detach(-d)
  バックグラウンドで実行できる
3. --name
  特定の名前をつけることができる
4. -it
   ssh接続のように、ターミナルを起動して操作する  
   ubuntuやcentOSはこのコマンドで起動
5. --rm
  exit終了時、コンテナも削除する
6. --net NETWORK_NAME
  あるネットワーク(bridge)上のコンテナとして起動する
7. --net-alias DNS_DOMAIN_NAME
  そのコンテナのDNS(DOMAIN_NAME)を指定する

ex) docker container run -p 9090:80 --name webhost -d nginx

1. ホストの9090ポート(localhost:9090)にアクセスするとコンテナの80番ポート(nginx)に接続できる(-p)
2. このコンテナの名前はwebhostになる(--name)
3. バックグラウンドで実行される(-d)

-itオプションについて

 -t => ターミナルを起動する
 -i => ターミナルの入力を受けるためにセッションをキープする

よって

 -it => ターミナルを起動して操作する=対話的(interactively)

docker container ls OR docker ps

起動中のコンテナ一覧を確認する

docker container stop CONTAINER_ID_OR_NAME

起動中のコンテナをstopする
※CONTAINER_IDの頭数桁を指定すればOK

docker container ls -a OR docker ps -a

起動中・停止中すべてのコンテナを表示する

docker container runとdocker container startの違い

docker container run   => 必ず新しいコンテナ(インスタンス)を作成する
docker container start => 既に作成されているコンテナ(インスタンス)を起動する

docker container rm CONTAINER_ID1, CONTAINER_ID2, ...

停止中のコンテナを削除する(-fで起動中も削除できる)

docker container top CONTAINER_NAME

そのコンテナ内のプロセス一覧を表示する

docker container inspect CONTAINER_NAME

コンテナの設定を表示する

docker container stats (CONTAINER_NAME)

コンテナのパフォーマンスを表示する
CONTAINER_NAMEは省略可能

docker container exec -it

1. 既存のコンテナ内で追加のプロセスを実行する
2. コンテナ内でプロセスを実行するので、exitでプロセスを終了させたとしても
   mysql daemonのrootプロセスには影響を与えない

docker container port NAME

ポート設定を確認できる


ネットワークについて

Docker内部のネットワークは仮想ネットワーク

用語

仮想ネットワーク  
  Docker内で構築されるネットワーク

ブリッジ  
  プライベートな仮想ネットワーク  
  複数のブリッジをもつことができる
  異なるブリッジ同士は互いに通信できない

仮想ネットワーク内にブリッジが複数あるイメージ


異なるbridge間の通信について

仮想ネットワーク上のContainerのIPはファイアウォールを介してHostのIPにルーティングされる
同じbridge上のコンテナは-pコマンドでポートを設定しなくても互いにすべてやりとりできる

  1. Dockerの仮想ネットワークとHost(PC)の間には、NAT(Firewall)が存在する
Virtual Network | Firewall | Host
  1. bridge1でdocker container run -p 8080:80 httpdを実行すると、
    bridge1にhttpdのContainerが作成され、そのContainerの80番ポートとHostの8080番ポートを接続する
bridge1のhttpd(80) | Firewall | Host(8080)
  1. bridge2でdocker container run -p 3306:3306 mysqlを実行すると、
    bridge2にmysqlのContainerが作成され、そのContainerの3306ポートとHostの3306番ポートを接続する
bridge2のmysql(3306) | Firewall | Host(3306)

まとめて書くと、

bridge1のhttpd(80), bridge2のmysql(3306) | Firewall | Host(8080, 3306)
  1. bridge1とbridge2は別の仮想ネットワークで、互いに接続できないので
    Hostのポートを介して接続する必要がある
ex) bridge2のmysqlからbridge1のhttpdに接続する場合

bridge2のmysql(3306) => Host(3306) => Host(8080) => bridge1のhttpd(80)

DNS

ネットワーク間で通信する際、お互いのIPアドレスで通信するのはアンチパターンとされている
=> IPアドレスで通信していると、IPアドレスが変更されたときに通信できなくなる
=> DNS(Domain Network System)を使う

DNSはドメインとIPアドレスを対応付けて管理するシステム

DockerではデフォルトでHOST_NAME == CONTAINER_NAMEとなる


ネットワークのコマンド

docker network ls

ネットワーク一覧(bridge, hostなど)

docker network create

仮想ネットワーク上にネットワーク(bridgeなど)を作成できる

docker network connect(disconnect) NETWORK_NAME CONTAINER_NAME

指定したNETWORKにContainerを接続できる
docker container run --net NETWORK_NAMEと同様の動作

docker network inspect NETWORK_NAME

ネットワークの設定を確認できる
ex) ブリッジにどのコンテナが含まれているかなど