コンテナオーケストレーションシステムのDocker Swarmを触ってみました。「Docker/Kubernetesコンテナ実践入門」を読み進めておりDocker Swarmは飛ばしてKubernetesから入ろうかとも思ったのですが、Kubernetesを理解する上で、Docker Swarmの知識も役立ちそうだったので備忘録として残しておきます。
gihyo.jp
Code
Docker Swarmとは
Docker ホストを束ねてクラスタ化するコンテナオーケストレーションシステムの1つ。クラスタ内のノードのコンテナ配置方法やコンテナ同士の通信制御、スケーラビリティの制御を行います、Swarmを扱う上で次の役割のサービスを使います。
Swarmクラスタの構築
Swarmクラスタを構築するため、まず下記のコンテナを用意します。
- registry * 1:Dockerイメージのレジストリとなるコンテナ。managerとworkerから参照
- manager * 1:Swarmクラスタ全体を制御する役割
- worker * 3:managerのワーカー
$ docker-compose up -d $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 425f9e302130 docker:18.05.0-ce-dind "dockerd-entrypoint.…" 40 seconds ago Up 38 seconds 2375/tcp, 4786/udp, 7946/tcp, 7946/udp worker03 9b49fbcd90ef docker:18.05.0-ce-dind "dockerd-entrypoint.…" 40 seconds ago Up 38 seconds 2375/tcp, 4786/udp, 7946/tcp, 7946/udp worker01 68393f9a2309 docker:18.05.0-ce-dind "dockerd-entrypoint.…" 40 seconds ago Up 38 seconds 2375/tcp, 4786/udp, 7946/tcp, 7946/udp worker02 b01f251189c7 docker:18.05.0-ce-dind "dockerd-entrypoint.…" 41 seconds ago Up 40 seconds 2375/tcp, 3375/tcp, 0.0.0.0:9000->9000/tcp, 0.0.0.0:8000->80/tcp manager d7b24d89c6c5 registry:2.6 "/entrypoint.sh /etc…" 43 seconds ago Up 41 seconds 0.0.0.0:5000->5000/tcp
実行したコンテナを協調クラスタとして動作させます。ホストからmanagerに対して「docker swarm init」を実行してSwarmのmanagerに設定します。
$ docker container exec -it manager docker swarm init
実行すると対象のコンテナ全体を管理するmanagerとして、Swarmモードが有効になります。ここから先ほど立ち上げたworkerコンテナを追加しクラスタを形成します。worker01~03を追加して行きます。
$ docker container exec -it worker01 docker swarm join --token SWMTKN-1-4j56rxglt7v1wih7qla3mn3nanrg43xt6l2v6dg1n9c2aqkfik-62ixkhr3obx36ppylqw4fvc81 172.18.0.3:2377 This node joined a swarm as a worker.
managerを確認すると、managerに加えてworkerも追加されていることが確認できます。
$ docker container exec -it manager docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION qkcdh7a24e2abg4ujqbik0s2e 9b49fbcd90ef Ready Active 18.05.0-ce 7r8cy38zsizyxk9jfdpfex111 425f9e302130 Ready Active 18.05.0-ce l8s5by2muej3ab1ntcp08gjwj 68393f9a2309 Ready Active 18.05.0-ce ckzn9h99a65l75qfnjey3i8z5 * b01f251189c7 Ready Active Leader 18.05.0-ce
レジストリに登録
registryコンテナにイメージをpushし、クラスタ内のmanagerやworkerコンテナから参照できるようにします。
# docker image push [push先のレジストリのホスト/]リポジトリ名[:タグ]
$ docker image tag example/echo:latest localhost:5000/example/echo:latest
$ docker image push localhost:5000/example/echo:latest
試しにworker01からPULLし、取得できることを確認します。
$ docker container exec -it worker01 docker image pull registry:5000/example/echo:latest $ docker container exec -it worker01 docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE registry:5000/example/echo latest cc921756bbc3 2 days ago 750MB
Service
Serviceはアプリケーションを構成する一部を制御するための単位です。実行されている複数のコンテナをまとめて管理しています。位置付けとしては、Serviceの上位にStackがあり、StackはSwarmで制御される形になります。試しにServiceを一つ作ってみます。
$ docker container exec -it manager docker service \ create --replicas 1 --publish 8000:8080 --name echo registry:5000/example/echo:latest
Serviceが作られたことを確認してみます。
$ docker container exec -it manager docker service ls ID NAME MODE REPLICAS IMAGE PORTS bd5wgpbdl1w7 echo replicated 1/1 registry:5000/example/echo:latest *:8000->8080/tcp
Serviceが制御するレプリカを増やしてみる。Swarmクラスタ上で実行されているコンテナを確認。6つのechoコンテナが分散されて配置されていることがわかる。
$ docker container exec -it manager docker service scale echo=6 $ docker container exec -it manager docker service ls ID NAME MODE REPLICAS IMAGE PORTS bd5wgpbdl1w7 echo replicated 6/6 registry:5000/example/echo:latest *:8000->8080/tcp $ docker container exec -it manager docker service ps echo ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS nqwi4tu8rram echo.1 registry:5000/example/echo:latest 9b49fbcd90ef Running Running 20 minutes ago ipb2o6lzuurr echo.2 registry:5000/example/echo:latest 425f9e302130 Running Running 9 minutes ago j9tqjwvcvek2 echo.3 registry:5000/example/echo:latest 425f9e302130 Running Running 9 minutes ago 7ep1m82eg57x echo.4 registry:5000/example/echo:latest 9b49fbcd90ef Running Running 11 minutes ago m3qaesn6rnw9 echo.5 registry:5000/example/echo:latest b01f251189c7 Running Running 9 minutes ago m0md7lsjqgil echo.6 registry:5000/example/echo:latest 68393f9a2309 Running Running 9 minutes ago
デプロイしたサービスを削除する
$ docker container exec -it manager docker service rm echo
Stack
Stackは複数のServiceをグルーピングした単位のことです。Serviceは1つのアプリケーションイメージしか使うことができない。複数のServiceが協調するアプリケーションを動かす場合は、Serviceの上位概念である Stackを活用します。StackはSwarm上でスケールイン・スケールアウトが可能になったComposeという位置付けです。Stackの制御にはdocker stackサブコマンドが利用されます。
overlayネットワーク
overlayネットワークとはStackによってデプロイされるService群が所属するネットワークです。同じネットワークに所属しているコンテナ間では通信が可能となる。特にoverlayネットワークを設定しなければ、Stackの数だけoverlayネットワークが作られ、異なるStackで作られたコンテナ群同士は通信もできなくなります。この問題を解決するためには、同一のoverlayネットワークに所属させる必要があります。overlayネットワークを作りStackから作成されるServiceを所属させます。
$ docker container exec -it manager docker network create --driver=overlay --attachable ch03
# webapi.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/example/echo:latest deploy: replicas: 3 placement: constraints: [node.role != manager] networks: - ch03 networks: ch03: external: true
- deploy:新規にStackをデプロイ、または更新する
- external= true :Stack の外にネットワークを作成します(訳者注:Compose が管理していない Docker ネットワークを利用します
- placement:コンテナ配置戦略の設定
- constraints:manager以外のノードにコンテナを配置
Stackをデプロイ
StackをSwarmクラスタにデプロイします。
$ docker container exec -it manager docker stack deploy -c /stack/ch03-webapi.yml echo Creating service echo_nginx Creating service echo_api
- C:Stack定義ファイルのパス
デプロイされたStackを確認します。
$ docker container exec -it manager docker stack services echo ID NAME MODE REPLICAS IMAGE PORTS iqerba71n0mh echo_nginx replicated 3/3 gihyodocker/nginx-proxy:latest z03j17trpp4o echo_api replicated 3/3 registry:5000/example/echo:latest
配置されているコンテナを可視化
コンテナ群がSwarmクラスタ上のノードにどのように配置されているか可視化できるアプリケーションがあります。
# 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]
$ docker container exec -it manager docker stack deploy -c /stack/visualizer.yml visualizer Creating network visualizer_default Creating service visualizer_app
Stackの削除
$ docker container exec -it manager docker stack rm echo Removing service echo_api Removing service echo_nginx
以上となります。