Dockerのコンテナ、ネットワークについて
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コマンドでポートを設定しなくても互いにすべてやりとりできる
- Dockerの仮想ネットワークとHost(PC)の間には、NAT(Firewall)が存在する
Virtual Network | Firewall | Host
- bridge1で
docker container run -p 8080:80 httpd
を実行すると、
bridge1にhttpdのContainerが作成され、そのContainerの80番ポートとHostの8080番ポートを接続する
bridge1のhttpd(80) | Firewall | Host(8080)
- 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)
- 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) ブリッジにどのコンテナが含まれているかなど
Discussion