Docker/Kubernetes 実践コンテナ開発入門 Ch.3 実用的なコンテナの構築とデプロイ
コンテナ配置戦略
- 複数ホスト上にコンテナを配置する
Docker Swarm
- コンテナオーケストレーションシステム
- 複数のDockerホストを束ねてクラスタ化する
- スケーラビリティのあるアプリケーション構築に不可欠
- どこのDockerホストにコンテナを配置するか
- ホストをまたいだコンテナ同士の通信
- 複数のホストを意識せずに透過的に操作できる
名称 | 役割 | 対応するコマンド |
---|---|---|
Compose | 複数コンテナを使うDockerアプリケーションの管理(単ホスト) | docker-compose |
Swarm | クラスタの構築や管理(複数ホスト) | docker swarm |
Service | Swarm前提、クラスタ内のService(単一種コンテナの1つ以上の集まり)を管理する | docker service |
Stack | Swarm前提、複数のServiceをまとめたアプリケーション全体の管理 | docker stack |
複数のDockerホストを用意し、Swarmクラスタを構築する
- dindを使ってやってみる
./docker-compose.yml
version: "3" services: registry: container_name: registry image: registry:2.6 ports: - 5000:5000 volumes: - "./registry-data:/var/lib/registry" manager: container_name: manager image: docker:18.05.0-ce-dind privileged: true tty: true ports: - 8000:80 - 9000:9000 depends_on: - registry expose: - 3375 command: "--insecure-registry registry:5000" volumes: - "./stack:/stack" worker01: container_name: worker01 image: docker:18.05.0-ce-dind privileged: true tty: true depends_on: - manager - registry expose: - 7946 - 7946/udp - 4789/udp command: "--insecure-registry registry:5000" worker02: container_name: worker02 image: docker:18.05.0-ce-dind privileged: true tty: true depends_on: - manager - registry expose: - 7946 - 7946/udp - 4789/udp command: "--insecure-registry registry:5000" worker03: container_name: worker03 image: docker:18.05.0-ce-dind privileged: true tty: true depends_on: - manager - registry expose: - 7946 - 7946/udp - 4789/udp command: "--insecure-registry registry:5000"
docker-compose up -d
docker-compose ps
Name Command State Ports -------------------------------------------------------------------------------------------------------------------- manager dockerd-entrypoint.sh --in ... Up 2375/tcp, 3375/tcp, 0.0.0.0:8000->80/tcp, 0.0.0.0:9000->9000/tcp registry /entrypoint.sh /etc/docker ... Up 0.0.0.0:5000->5000/tcp worker01 dockerd-entrypoint.sh --in ... Up 2375/tcp, 4789/udp, 7946/tcp, 7946/udp worker02 dockerd-entrypoint.sh --in ... Up 2375/tcp, 4789/udp, 7946/tcp, 7946/udp worker03 dockerd-entrypoint.sh --in ... Up 2375/tcp, 4789/udp, 7946/tcp, 7946/udp
- これだけでは、まだクラスタとして協調動作はしない
- managerコンテナをSwarmのmanagerに設定
docker-compose exec manager docker swarm init
Swarm initialized: current node (teeifjlt3m3tgsihtsub4bsix) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-1c4pyx2ti6q9sps42wixflkfzy3ri5oiie36cnij69kubhylwo-eesmg5op9uq1xht2namli0cza 172.18.0.3:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
docker-compose exec worker01 docker swarm join --token SWMTKN-1-1c4pyx2ti6q9sps42wixflkfzy3ri5oiie36cnij69kubhylwo-eesmg5op9uq1xht2namli0cza manager:2377 docker-compose exec worker02 docker swarm join --token SWMTKN-1-1c4pyx2ti6q9sps42wixflkfzy3ri5oiie36cnij69kubhylwo-eesmg5op9uq1xht2namli0cza manager:2377 docker-compose exec worker03 docker swarm join --token SWMTKN-1-1c4pyx2ti6q9sps42wixflkfzy3ri5oiie36cnij69kubhylwo-eesmg5op9uq1xht2namli0cza manager:2377
- 登録確認
docker-compose exec manager docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION qo2h97erczjn5j5ov3na06903 9fd11f79ab8f Ready Active 18.05.0-ce yv7223kcy5snyuagksznhn4s5 112feaeada15 Ready Active 18.05.0-ce teeifjlt3m3tgsihtsub4bsix * 924cf340028b Ready Active Leader 18.05.0-ce kpv8c0m96r2koqlklbhqyl09k c22aa67570ce Ready Active 18.05.0-ce
DockerレジストリにイメージをPushする
[push先のレジストリのホスト/]リポジトリ名/イメージ名:タグ
という書式でタグ付け
docker image tag example/echo:latest localhost:5000/example/echo:latest
REPOSITORY TAG IMAGE ID CREATED SIZE example/echo latest bd8704147da5 10 days ago 750MB localhost:5000/example/echo latest bd8704147da5 10 days ago 750MB
- registryサーバにexample/echoをpush
docker image push localhost:5000/example/echo:latest
The push refers to repository [localhost:5000/example/echo] 7dc016053afb: Pushed 7040a361c2a2: Pushed 186d94bd2c62: Pushed 24a9d20e5bee: Pushed e7dc337030ba: Pushed 920961b94eb3: Pushed fa0c3f992cbd: Pushed ce6466f43b11: Pushed 719d45669b35: Pushed 3b10514a95be: Pushed latest: digest: sha256:264bb0a99867a71ee02b21009e9042d6ef3c12d474ee77ad9f36b2cbe5b48a71 size: 2417
- workerからpull
docker-compose exec worker01 docker image pull registry:5000/example/echo:latest
latest: Pulling from example/echo 55cbf04beb70: Pull complete 1607093a898c: Pull complete 9a8ea045c926: Pull complete d4eee24d4dac: Pull complete 9c35c9787a2f: Pull complete 8b376bbb244f: Pull complete 0d4eafcc732a: Pull complete 186b06a99029: Pull complete d8ad46f9ce62: Pull complete a6235c996378: Pull complete Digest: sha256:264bb0a99867a71ee02b21009e9042d6ef3c12d474ee77ad9f36b2cbe5b48a71 Status: Downloaded newer image for registry:5000/example/echo:latest
- イメージ確認
docker-compose exec worker01 docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE registry:5000/example/echo latest bd8704147da5 10 days ago 750MB
Service
- コンテナのデプロイの方法がこれまでとは違うよ、という話
- docker run
- docker-compose up
- アプリケーションの構成はいろいろ
- 1つのコンテナ?
- 複数種のコンテナ?
- それらのレプリカ?
- Serviceとは、アプリケーションを構成する一部のコンテナを制御するための単位
docker-compose exec manager docker service create --replicas 1 --publish 8000:8080 --name echo registry:5000/example/echo:latest
qq7iamln8e127hxun243c2t5w overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged
- サービス一覧の確認
docker-compose exec manager docker service ls
ID NAME MODE REPLICAS IMAGE PORTS qq7iamln8e12 echo replicated 1/1 registry:5000/example/echo:latest *:8000->8080/tcp
- 動いているechoコンテナの確認
docker-compose exec manager docker service ps echo
- ホスト
924cf340028b
上でIDr85omi5kh6pf
コンテナが動いているようだ
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS r85omi5kh6pf echo.1 registry:5000/example/echo:latest 924cf340028b Running Running 3 minutes ago
- ホスト
924cf340028b
ってどれ
docker-compose exec manager docker node ls
- managerだったみたい
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION qo2h97erczjn5j5ov3na06903 9fd11f79ab8f Ready Active 18.05.0-ce yv7223kcy5snyuagksznhn4s5 112feaeada15 Ready Active 18.05.0-ce teeifjlt3m3tgsihtsub4bsix * 924cf340028b Ready Active Leader 18.05.0-ce kpv8c0m96r2koqlklbhqyl09k c22aa67570ce Ready Active 18.05.0-ce
- manager上でechoコンテナが動いていることを確認する
docker-compose exec manager docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 50cf158d7e84 registry:5000/example/echo:latest "go run /echo/main.go" 6 minutes ago Up 6 minutes echo.1.r85omi5kh6pf4pjgs2l9ls4ym
- スケールアウトしてみる
docker-compose exec manager docker service scale echo=6
echo scaled to 6 overall progress: 6 out of 6 tasks 1/6: running [==================================================>] 2/6: running [==================================================>] 3/6: running [==================================================>] 4/6: running [==================================================>] 5/6: running [==================================================>] 6/6: running [==================================================>] verify: Service converged
- 動いているコンテナの確認
docker-compose exec manager docker service ps echo
- 増えている
- 各ノードに分散している
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS r85omi5kh6pf echo.1 registry:5000/example/echo:latest 924cf340028b Running Running 10 minutes ago udilbue6ii39 echo.2 registry:5000/example/echo:latest 9fd11f79ab8f Running Running 42 seconds ago qauesniepz6i echo.3 registry:5000/example/echo:latest 112feaeada15 Running Running about a minute ago neo55v2bdnkz echo.4 registry:5000/example/echo:latest 112feaeada15 Running Running about a minute ago q14potoogtbo echo.5 registry:5000/example/echo:latest 924cf340028b Running Running about a minute ago 1jcjv5h3s5ea echo.6 registry:5000/example/echo:latest c22aa67570ce Running Running 43 seconds ago
docker-compose exec manager docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 83ab8bd3e4ef registry:5000/example/echo:latest "go run /echo/main.go" 4 minutes ago Up 4 minutes echo.5.q14potoogtbofxpw9xppsby2q 50cf158d7e84 registry:5000/example/echo:latest "go run /echo/main.go" 12 minutes ago Up 12 minutes echo.1.r85omi5kh6pf4pjgs2l9ls4ym docker-compose exec worker01 docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4b7ae592fe90 registry:5000/example/echo:latest "go run /echo/main.go" 4 minutes ago Up 4 minutes echo.4.neo55v2bdnkziimrogflxdgu0 7254ab456f46 registry:5000/example/echo:latest "go run /echo/main.go" 4 minutes ago Up 4 minutes echo.3.qauesniepz6i4clrhwqgri654 docker-compose exec worker02 docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ce5f5bc0ba9e registry:5000/example/echo:latest "go run /echo/main.go" 3 minutes ago Up 3 minutes echo.2.udilbue6ii39pz8w5851hbp7q docker-compose exec worker03 docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3bf3289be3a0 registry:5000/example/echo:latest "go run /echo/main.go" 4 minutes ago Up 3 minutes echo.6.1jcjv5h3s5eamod6e6rxwr8ck
- Service消す
docker-compose exec manager docker service rm echo docker-compose exec manager docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
- Serviceにレプリカ数の制御を指示すると、自動でコンテナを複製し、複数のノードにまたがって適切に配置してくれる
- Serviceなしで行うのは無理ゲー
Stack
- 複数のServiceをグルーピングした、アプリケーション全体の構成管理
- ServiceのCompose版という感じ
- Swarm上でスケールイン・アウトやconstraintを記述可能
- overlayネットワーク
- Dockerホストをまたぐネットワーク
- 同一overlayネットワーク内なら、別ホスト上のサービスでも通信できる
- 別のoverlayネットワークに存在するサービスはディスカバリも通信もできない
- Stackで利用するoverlayネットワークを指定しなければ、stackの数だけoverlayネットワークが作成される
Stackをデプロイする
- アプリケーションの構成
- フロントエンド: Nginx
- バックエンド: API
./stack/docker-stack.yml
version: "3" services: nginx: image: gihyodocker/nginx-proxy:latest deploy: replicas: 3 placement: constraints: [node.role != manager] environment: BACKEND_HOST: echo_api:8080 depends_on: - api networks: - ch03 api: image: registry:5000/exaple/echo:latest deploy: replicas: 3 placement: constraints: [node.role != manager] networks: - ch03 networks: ch03: external: true
- overlay networkは自動で作られないので、あらかじめ作っておく
docker-compose exec manager docker network create --driver=overlay --attachable ch03
o7t5ak2je3l9ivvyhrry3ridc
- StackをSwarmクラスタにデプロイ
-c
は--compose-file
の意
docker-compose exec manager docker stack deploy -c /stack/docker-stack.yml echo
Creating service echo_nginx Creating service echo_api
- Stackの確認
docker-compose exec manager docker stack ls
NAME SERVICES echo 2
docker-compose exec manager docker stack services echo
ID NAME MODE REPLICAS IMAGE PORTS 56zq1ut1zw3l echo_nginx replicated 3/3 gihyodocker/nginx-proxy:latest o825ipqini8p echo_api replicated 3/3 registry:5000/example/echo:latest
- サービスで動いているコンテナの確認
docker-compose exec manager docker service ps echo_api ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS dsogfmca5ass echo_api.1 registry:5000/example/echo:latest 112feaeada15 Running Running about a minute ago iv99dpishl7q echo_api.2 registry:5000/example/echo:latest c22aa67570ce Running Running about a minute ago sxhrigncxc3w echo_api.3 registry:5000/example/echo:latest 9fd11f79ab8f Running Running about a minute ago docker-compose exec manager docker service ps echo_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS kvoxzogmk084 echo_nginx.1 gihyodocker/nginx-proxy:latest 9fd11f79ab8f Running Running about a minute ago lrrifqdkm0yk echo_nginx.2 gihyodocker/nginx-proxy:latest c22aa67570ce Running Running about a minute ago ou8uj318wopt echo_nginx.3 gihyodocker/nginx-proxy:latest 112feaeada15 Running Running about a minute ago
- まとめて確認できる
docker-compose exec manager docker stack ps echo
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS kvoxzogmk084 echo_nginx.1 gihyodocker/nginx-proxy:latest 9fd11f79ab8f Running Running 3 minutes ago dsogfmca5ass echo_api.1 registry:5000/example/echo:latest 112feaeada15 Running Running 3 minutes ago lrrifqdkm0yk echo_nginx.2 gihyodocker/nginx-proxy:latest c22aa67570ce Running Running 2 minutes ago iv99dpishl7q echo_api.2 registry:5000/example/echo:latest c22aa67570ce Running Running 3 minutes ago ou8uj318wopt echo_nginx.3 gihyodocker/nginx-proxy:latest 112feaeada15 Running Running 2 minutes ago sxhrigncxc3w echo_api.3 registry:5000/example/echo:latest 9fd11f79ab8f Running Running 3 minutes ago
Swarmクラスタ上のコンテナを可視化する
./stack/visualizer.yml
version: "3" services: app: image: dockersamples/visualizer ports: - "9000:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock deploy: mode: global placement: constraints: [node.role == manager]
mode: global
は、Swarmクラスタの全ノードにデプロイする、の意- constraints併用により、「全managerノードにデプロイ」の意
- dindに9000->8080でポートフォワーディングしている
- ホストからmanagerノードコンテナは9000->9000でポートフォワーディングしているので、ホストのlocalhost:9000で接続できる
docker-compose exec manager docker stack deploy -c /stack/visualizer.yml visualizer
Creating network visualizer_default Creating service visualizer_app
- Stack確認
docker-compose exec manager docker stack ls NAME SERVICES echo 2 visualizer 1 docker-compose exec manager docker stack services visualizer ID NAME MODE REPLICAS IMAGE PORTS xesh8068cn6k visualizer_app global 1/1 dockersamples/visualizer:latest *:9000->8080/tcp docker-compose exec manager docker stack ps visualizer ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS qk6d1wzazknf visualizer_app.teeifjlt3m3tgsihtsub4bsix dockersamples/visualizer:latest 924cf340028b Running Running 9 minutes ago
Stackの削除
- echoスタックを消す
docker-compose exec manager docker stack rm echo
Removing service echo_api Removing service echo_nginx
- visualizer上にもリアルタイムで反映される
ServiceをSwarmクラスタ外から利用する
- visualizerは必ずmanagerコンテナで動くので、多段ポートフォワーディングで利用できた
- echoスタックのecho_nginxサービスは、worker01~worker03ノードに分散しているのでそうはいかない
- クラスタ外からクラスタ内のサービスへのプロキシサーバーが必要になる
./stack/ingress.yml
version: "3" services: haproxy: image: dockercloud/haproxy networks: - ch03 volumes: - /var/run/docker.sock:/var/run/docker.sock deploy: mode: global placement: constraints: [node.role == manager] ports: - 80:80 - 1936:1936 # for stats page (basic auth. stats:stats) networks: ch03: external: true
./stack/docker-stack.yml
version: "3"
services:
nginx:
image: gihyodocker/nginx-proxy:latest
deploy:
replicas: 3
placement:
constraints: [node.role != manager]
environment:
+ SERVICE_PORTS: 80
BACKEND_HOST: echo_api:8080
depends_on:
- api
networks:
- ch03
api:
image: registry:5000/example/echo:latest
deploy:
replicas: 3
placement:
constraints: [node.role != manager]
networks:
- ch03
networks:
ch03:
external: true
- stackデプロイ
docker stack deploy -c /stack/docker-stack.yml echo Creating service echo_nginx Creating service echo_api docker-compose exec manager docker stack deploy -c /stack/ingress.yml ingress Creating service ingress_haproxy
重要なポイント
- Serviceはレプリカ数(コンテナの数)を制御することで容易にコンテナを複製でき、複数のノードに配置できるため、スケールアウトへの親和性が高い
- Serviceによって管理される複数のレプリカはService名で名前解決でき、かつServiceへのトラフィックはレプリカへ分散される
- Swarmクラスタの外からSwarmのServiceを利用するには、Serviceにトラフィックを分散するためのプロキシを用意する
- Stackは複数のServiceをグルーピングでき、複数のServiceで形成されるアプリケーションのデプロイに役立つ
【補】AWS ECSとの比較
Swarm | AWS ECS | |
---|---|---|
同種コンテナをレプリケーションしたやつ | Service | - |
異種コンテナをまとめたやつ | - | Task |
アプリケーション | Stack | Service |