听说了最大的更新后,我决定试试Docker1.12

ということで、タイトル通り、過去最大のupdateと言われているDocker1.12の気になる機能を試しました。
meetup等でDocker社の人の話を聞いた内容や公式ドキュメントベースで気になった箇所のみ試します。
ちなみに後方互換性は保たれているので、以下で出てくるswarm init等のコマンドを使わない限り今まで通り使えるそうです。

自分が気になったところを試しただけなので、網羅的な更新一覧および、内部の仕組みは公式ページなり、いつも訳して下さっている前佛さんの日本語訳を参考にしてください。

GitHub上のリリース情報

日本語訳

Docker Built-in Orchestration Ready for Production: Docker 1.12 Goes GA

日本語訳

Docker 1.12: Now with Built-in Orchestration!

日本語訳

あとはDockerConの動画とかも沢山あるけど多すぎるので、先日行われたオンラインmeetupの動画がまとまっててオススメです。
というか、このポストはほぼオンラインmeetup及び、ほぼ同じ内容のSanta Claraのmeetupで紹介されてた機能の紹介ですw

环境

以下の環境はLinuxで行いました。dockerはインストール済みと仮定します。dockerrepoを追加していれば、aptでもdnfでも最新版が入るはずです。以下のデモではDigitalOceanを使いますがVirtualBoxでもAWSでも何でも大丈夫かと思います。DigitalOceanの場合はこちらから登録すると今回動かす分くらいのクレジットは貰えます。(私にもクレジットが入るのでそーゆーのがイヤな方は普通にトップから登録してください)

また、以下のポートが開いている必要があります。(DigitalOceanでは設定不要ですが、ipv6有効になってたりするとトラブルかもしれません)

    • TCP: 2377, 7946, 4789

 

    UDP: 7946, 4789

尝试完整进行Swarm mode的教程体验一遍。

首先,我会试着用教程中的Swarm Mode功能一一地进行尝试。如果你已经完成了类似的操作,那么你可以不必阅读这部分。

在教程中,每个节点都使用docker命令,但由于繁琐的ssh操作,我想使用docker-machine代替。

curl -L https://github.com/docker/machine/releases/download/v0.8.0/docker-machine-`uname -s`-`uname -m` >~/path/to/docker-machine && chmod +x ~/path/to/docker-machine

首先创建一个节点作为管理节点。请根据需要适当设置DIGITALOCEAN_API_TOKEN。(以后相同)

docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} manager

以swarm模式启动。请在”advertise-addr”参数中指定管理者(manager)的IP地址,可通过使用docker-machine ls等命令进行查询。

eval $(docker-machine env manager)
docker swarm init --advertise-addr 192.241.219.207

以下是获得worker和manager的追加方法的输出。

Swarm initialized: current node (djvtufr82caej8ebysdbsj0ov) is now a manager.

To add a worker to this swarm, run the following command:
    docker swarm join \
    --token SWMTKN-1-46kek56vwx6f7y9d0tqci7zrly11b2h8u0k31xhx0kaxx4f70o-6k4xdghyave5qci4o94s8b433 \
    192.241.219.207:2377

To add a manager to this swarm, run the following command:
    docker swarm join \
    --token SWMTKN-1-46kek56vwx6f7y9d0tqci7zrly11b2h8u0k31xhx0kaxx4f70o-dxsejlrazkr0jaznx4u9o8yl7 \
    192.241.219.207:2377

可以通过运行”docker info”命令来确认Swarm模式处于活动状态,并且”IsManager”属性为真。

docker info
Swarm: active
IsManager: true

您可以使用docker node ls命令来确认节点的状态。

$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
djvtufr82caej8ebysdbsj0ov *  manager   Ready   Active        Leader

接下来,我会制作两台专供工人使用的机器。

docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} worker1
docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} worker2

参考先前创建经理时得到的结果,我们试着添加一个工人。

eval $(docker-machine env worker1)
docker swarm join --token SWMTKN-1-46kek56vwx6f7y9d0tqci7zrly11b2h8u0k31xhx0kaxx4f70o-6k4xdghyave5qci4o94s8b433 192.241.219.207:2377

eval $(docker-machine env worker2)
docker swarm join --token SWMTKN-1-46kek56vwx6f7y9d0tqci7zrly11b2h8u0k31xhx0kaxx4f70o-6k4xdghyave5qci4o94s8b433 192.241.219.207:2377

我会再次在管理者中运行docker node ls命令并确认结果。

eval $(docker-machine env manager)

$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
as3dl417gpz9795aedxa970th    worker2   Ready   Active
asqs3rls6pc32izn74zkkiysd    worker1   Ready   Active
djvtufr82caej8ebysdbsj0ov *  manager   Ready   Active        Leader

接下来,我们将创建一个服务。

docker service create --replicas 1 --name helloworld alpine ping docker.com

这个服务的名字是helloworld,只有一个容器,使用alpine镜像,执行ping docker.com命令。

使用各种命令来确认结果。

$ docker service ls
ID            NAME        REPLICAS  IMAGE   COMMAND
16hidqk9zown  helloworld  1/1       alpine  ping docker.com

$ docker service inspect --pretty helloworld
ID:             16hidqk9zown8qpqt424yzwxc
Name:           helloworld
Mode:           Replicated
 Replicas:      1
Placement:
UpdateConfig:
 Parallelism:   1
 On failure:    pause
ContainerSpec:
 Image:         alpine
 Args:          ping docker.com
Resources:

$  docker service ps helloworld
ID                         NAME          IMAGE   NODE     DESIRED STATE  CURRENT STATE          ERROR
bdbz6k194232czgn0rrvkklkw  helloworld.1  alpine  manager  Running        Running 2 minutes ago

我尝试调整规模。

$ docker service scale helloworld=5
helloworld scaled to 5

$ docker service ps helloworld
ID                         NAME          IMAGE   NODE     DESIRED STATE  CURRENT STATE           ERROR
bdbz6k194232czgn0rrvkklkw  helloworld.1  alpine  manager  Running        Running 7 minutes ago
6qhabtifgay4zzzduqabiiwhe  helloworld.2  alpine  worker1  Running        Running 12 seconds ago
33zyifha6z47dvnve8g48g9dh  helloworld.3  alpine  manager  Running        Running 13 seconds ago
7cobt9a7umy33h1flgzor0j1s  helloworld.4  alpine  worker2  Running        Running 11 seconds ago
d8jnt9u5yn85t8bjcfp58cmau  helloworld.5  alpine  worker1  Running        Running 12 seconds ago

我要删除服务。

$ docker service rm helloworld
helloworld

当您尝试检查服务状态时,由于已被删除,将导致出现错误。

$ docker service ps helloworld
Error: No such service: helloworld

接下来,我将尝试滚动更新。
首先,我会运行3个Redis容器,并将更新延迟设置为10秒。

$ docker service create \
  --replicas 3 \
  --name redis \
  --update-delay 10s \
  redis:3.0.6

我們需要確認狀態。

$ docker service ps redis
ID                         NAME     IMAGE        NODE     DESIRED STATE  CURRENT STATE             ERROR
bq9xwhwbryx7i180fx1zw6pb2  redis.1  redis:3.0.6  worker2  Running        Preparing 16 seconds ago
86mgm09e7vb8hzp7aki87fxcd  redis.2  redis:3.0.6  worker1  Running        Running 4 seconds ago
0aphe5lz4w3mrn9wx2rmdnykh  redis.3  redis:3.0.6  manager  Running        Running 3 seconds ago

$ docker service inspect redis --pretty
ID:             6ue7ncgimxwsnarvvdgw7431d
Name:           redis
Mode:           Replicated
 Replicas:      3
Placement:
UpdateConfig:
 Parallelism:   1
 Delay:         10s
 On failure:    pause
ContainerSpec:
 Image:         redis:3.0.6
Resources:

我打算对Redis 3.0.7进行滚动更新。

$ docker service update --image redis:3.0.7 redis

首先,您可以通过以下内容了解到更新正在进行中。

$ docker service inspect redis --pretty
ID:             6ue7ncgimxwsnarvvdgw7431d
Name:           redis
Mode:           Replicated
 Replicas:      3
Update status:
 State:         updating
 Started:       9 seconds ago
 Message:       update in progress
Placement:
UpdateConfig:
 Parallelism:   1
 Delay:         10s
 On failure:    pause
ContainerSpec:
 Image:         redis:3.0.7
Resources:

因为每10秒会进行滚动更新,所以请适当间隔一段时间来确认结果,可以看到以下的滚动更新情况。

$ docker service ps redis
ID                         NAME         IMAGE        NODE     DESIRED STATE  CURRENT STATE            ERROR
bq9xwhwbryx7i180fx1zw6pb2  redis.1      redis:3.0.6  worker2  Running        Running 2 minutes ago
86mgm09e7vb8hzp7aki87fxcd  redis.2      redis:3.0.6  worker1  Running        Running 2 minutes ago
1kdq4xygokkeeycdhgw1f9zpc  redis.3      redis:3.0.7  manager  Running        Running 4 seconds ago
0aphe5lz4w3mrn9wx2rmdnykh   \_ redis.3  redis:3.0.6  manager  Shutdown       Shutdown 16 seconds ago

$ docker service ps redis
ID                         NAME         IMAGE        NODE     DESIRED STATE  CURRENT STATE            ERROR
bq9xwhwbryx7i180fx1zw6pb2  redis.1      redis:3.0.6  worker2  Running        Running 2 minutes ago
5tn67yo2r8rdt9sx4tbmk6h3x  redis.2      redis:3.0.7  worker2  Running        Running 9 seconds ago
86mgm09e7vb8hzp7aki87fxcd   \_ redis.2  redis:3.0.6  worker1  Shutdown       Shutdown 25 seconds ago
1kdq4xygokkeeycdhgw1f9zpc  redis.3      redis:3.0.7  manager  Running        Running 36 seconds ago
0aphe5lz4w3mrn9wx2rmdnykh   \_ redis.3  redis:3.0.6  manager  Shutdown       Shutdown 47 seconds ago

$ docker service ps redis
ID                         NAME         IMAGE        NODE     DESIRED STATE  CURRENT STATE                ERROR
a02h3iatx9dfwnkcl5doqette  redis.1      redis:3.0.7  worker1  Running        Running about a minute ago
bq9xwhwbryx7i180fx1zw6pb2   \_ redis.1  redis:3.0.6  worker2  Shutdown       Shutdown about a minute ago
5tn67yo2r8rdt9sx4tbmk6h3x  redis.2      redis:3.0.7  worker2  Running        Running about a minute ago
86mgm09e7vb8hzp7aki87fxcd   \_ redis.2  redis:3.0.6  worker1  Shutdown       Shutdown 2 minutes ago
1kdq4xygokkeeycdhgw1f9zpc  redis.3      redis:3.0.7  manager  Running        Running 2 minutes ago
0aphe5lz4w3mrn9wx2rmdnykh   \_ redis.3  redis:3.0.6  manager  Shutdown       Shutdown 2 minutes ago

在结束之后,我们会再次确认状态。我们会看到更新已经完成。

$ docker service inspect redis --pretty
ID:             6ue7ncgimxwsnarvvdgw7431d
Name:           redis
Mode:           Replicated
 Replicas:      3
Update status:
 State:         completed
 Started:       2 minutes ago
 Completed:     about a minute ago
 Message:       update completed
Placement:
UpdateConfig:
 Parallelism:   1
 Delay:         10s
 On failure:    pause
ContainerSpec:
 Image:         redis:3.0.7
Resources:

我会删除该服务。

$ docker service rm redis
redis
$ docker service ps redis
Error: No such service: redis

接下来尝试进行Drain操作。把节点状态设置为Drain后,该节点将不再创建任何容器。
已经创建的容器将被移动到其他节点上。

$ docker service create --replicas 3 --name redis --update-delay 10s redis:3.0.6
6w08p3j5ew7pg4nurc3ywdq2l

$ docker service ps redis
ID                         NAME     IMAGE        NODE     DESIRED STATE  CURRENT STATE          ERROR
d4z5lw1sn8uiz21m0s2btgvc5  redis.1  redis:3.0.6  manager  Running        Running 8 seconds ago
ad3nqvbu357xjcao1wwdow2kf  redis.2  redis:3.0.6  worker2  Running        Running 7 seconds ago
0yndsykpbfsu4iegpxfuu900q  redis.3  redis:3.0.6  worker1  Running        Running 8 seconds ago

将工人1调到排水区。

$ docker node update --availability drain worker1
worker1

当确认节点状态时,可以发现它已被标记为”Drian”。

$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
as3dl417gpz9795aedxa970th    worker2   Ready   Active
asqs3rls6pc32izn74zkkiysd    worker1   Ready   Drain
djvtufr82caej8ebysdbsj0ov *  manager   Ready   Active        Leader

serviceの状態を確認するとworker1で動いていたコンテナはmanagerに移動しているのが分かります。

$ docker service ps redis
ID                         NAME         IMAGE        NODE     DESIRED STATE  CURRENT STATE               ERROR
d4z5lw1sn8uiz21m0s2btgvc5  redis.1      redis:3.0.6  manager  Running        Running about a minute ago
ad3nqvbu357xjcao1wwdow2kf  redis.2      redis:3.0.6  worker2  Running        Running about a minute ago
d8aehr5dad3u61d77iiun8gyj  redis.3      redis:3.0.6  manager  Running        Running 50 seconds ago
0yndsykpbfsu4iegpxfuu900q   \_ redis.3  redis:3.0.6  worker1  Shutdown       Shutdown 50 seconds ago

我会将worker1重新设为活动状态。

$ docker node update --availability active worker1
worker1

$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
as3dl417gpz9795aedxa970th    worker2   Ready   Active
asqs3rls6pc32izn74zkkiysd    worker1   Ready   Active
djvtufr82caej8ebysdbsj0ov *  manager   Ready   Active        Leader

移动的集装箱将不会返回,但在下次创建时,也将被分配给worker1。

Drainは色々使い方があるようで、例えば、メンテナンスするときなどには当然活用できるでしょう。
また、managerにはコンテナを作りたくないといった場合は、managerをDrainにすれば実現できます(もちろんlabel等を使っても同じことはできますが)。

暂时先删除所有节点。

docker-machine rm manager
docker-machine rm worker1
docker-machine rm worker2

经理的故障切换 de

接下来,我们将试验管理者的故障转移。

コンセンサスにはRaftが使われているので、奇数のmanagerが推奨されています。
ということで、managerとworkerを3台ずつ作ってみます。下記は出力結果を省略しています。

# docker-machineでmanagerとworkerを3台ずつ作成
docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} manager1
docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} manager2
docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} manager3
docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} worker1
docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} worker2
docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} worker3


# manager1でswarmモードを初期化
eval $(docker-machine env manager1)
docker swarm init --advertise-addr 104.236.176.63

# manager2,3を既存のswarmにmanagerとして追加
eval $(docker-machine env manager2)
    docker swarm join \
    --token SWMTKN-1-3pxkaylj5uubcwiu3a3d7e3zuwqabdbl2y7tf26c1wbbw4xnvy-9ed3sgq2agihmq7aewbvoim4e \
    104.236.176.63:2377
eval $(docker-machine env manager3)
    docker swarm join \
    --token SWMTKN-1-3pxkaylj5uubcwiu3a3d7e3zuwqabdbl2y7tf26c1wbbw4xnvy-9ed3sgq2agihmq7aewbvoim4e \
    104.236.176.63:2377

# worker1,2,3を既存のswarmにworkerとして追加
eval $(docker-machine env worker1)
docker swarm join \
    --token SWMTKN-1-3pxkaylj5uubcwiu3a3d7e3zuwqabdbl2y7tf26c1wbbw4xnvy-619h8ucg44larxtqszj9080gx \
    104.236.176.63:2377
eval $(docker-machine env worker2)
docker swarm join \
    --token SWMTKN-1-3pxkaylj5uubcwiu3a3d7e3zuwqabdbl2y7tf26c1wbbw4xnvy-619h8ucg44larxtqszj9080gx \
    104.236.176.63:2377
eval $(docker-machine env worker3)
docker swarm join \
    --token SWMTKN-1-3pxkaylj5uubcwiu3a3d7e3zuwqabdbl2y7tf26c1wbbw4xnvy-619h8ucg44larxtqszj9080gx \
    104.236.176.63:2377

結果を確認しておきます。

$ eval $(docker-machine env manager1)
$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
0eapj2cat7ih6973k9ysapwz2    worker2   Ready   Active
0inl859a5zuul7peoyjfjx9x8    worker3   Ready   Active
6hfv3zrwrd5doma7s6tc7hs61 *  manager1  Ready   Active        Leader
6snxc51snhhjzsin7qg0egobx    manager2  Ready   Active        Reachable
7xj8a2ufn63k38j9aynfzbyl8    manager3  Ready   Active        Reachable
918ny04ls768sl33rl5n02qal    worker1   Ready   Active

おもむろにLeaderのmanagerを落としてみます。

docker-machine rm manager1

我会确认领导发生变化。

$ eval $(docker-machine env manager2)
$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
0eapj2cat7ih6973k9ysapwz2    worker2   Ready   Active
0inl859a5zuul7peoyjfjx9x8    worker3   Ready   Active
6hfv3zrwrd5doma7s6tc7hs61    manager1  Down    Active        Unreachable
6snxc51snhhjzsin7qg0egobx *  manager2  Ready   Active        Reachable
7xj8a2ufn63k38j9aynfzbyl8    manager3  Down    Active        Leader
918ny04ls768sl33rl5n02qal    worker1   Down    Active

managerは奇数推奨なのでこのような場合は一台追加するべきです。
managerの追加は先述のdocker swarm joinコマンドでもできますが、docker node promoteというコマンドを使うことでworkerをmanagerにpromoteすることができるようなので、こちらを試してみます。

$ docker node promote worker1

我会确认一下结果。

$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
0eapj2cat7ih6973k9ysapwz2    worker2   Ready   Active
0inl859a5zuul7peoyjfjx9x8    worker3   Ready   Active
6hfv3zrwrd5doma7s6tc7hs61    manager1  Down    Active        Unreachable
6snxc51snhhjzsin7qg0egobx *  manager2  Ready   Active        Reachable
7xj8a2ufn63k38j9aynfzbyl8    manager3  Ready   Active        Leader
918ny04ls768sl33rl5n02qal    worker1   Ready   Active        Reachable

使用逆转命令时,还可以将经理降级为员工。

$ docker node demote manager3
$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
0eapj2cat7ih6973k9ysapwz2    worker2   Ready   Active
0inl859a5zuul7peoyjfjx9x8    worker3   Ready   Active
6hfv3zrwrd5doma7s6tc7hs61    manager1  Down    Active        Unreachable
6snxc51snhhjzsin7qg0egobx *  manager2  Ready   Active        Leader
7xj8a2ufn63k38j9aynfzbyl8    manager3  Ready   Active
918ny04ls768sl33rl5n02qal    worker1   Ready   Active        Reachable

ちなみにSTATUSの変化は1分くらいかけて、Unknown、Downと変わってからReadyに変わりました。

为了下一次示威,我会再次彻底肃清。

docker-machine rm manager1
docker-machine rm manager2
docker-machine rm manager3
docker-machine rm worker1
docker-machine rm worker2
docker-machine rm worker3

Routing meshを試す

当创建Routing mesh服务时,即使接收请求的节点上并未运行相应的服务容器,它也可以将请求重定向到正在运行容器的节点。

这次我将再次尝试以一个经理和三个工人的组合进行实验。
通过–engine-label指定标签,将worker1和2设定为env=production,将worker3设定为env=development,以供实验使用。

# docker-machineでノードを作成
docker-machine create -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} manager
docker-machine create --engine-label env=production -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} worker1
docker-machine create --engine-label env=production -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} worker2
docker-machine create --engine-label env=development -d digitalocean --digitalocean-image "ubuntu-16-04-x64" --digitalocean-region "sfo1" --digitalocean-size "512mb" --digitalocean-access-token ${DIGITALOCEAN_API_TOKEN} worker3

# swarmの初期化とworkderの追加
eval $(docker-machine env manager)
docker swarm init --advertise-addr 162.243.146.81
eval $(docker-machine env worker1)
docker swarm join \
    --token SWMTKN-1-3vh5e65rcvv5vbx10o456ikl6mmab7v5pgpebrilpejictw1kh-c5ewusty0safq5764gvgvknwl \
    162.243.146.81:2377
eval $(docker-machine env worker2)
docker swarm join \
    --token SWMTKN-1-3vh5e65rcvv5vbx10o456ikl6mmab7v5pgpebrilpejictw1kh-c5ewusty0safq5764gvgvknwl \
    162.243.146.81:2377
eval $(docker-machine env worker3)
docker swarm join \
    --token SWMTKN-1-3vh5e65rcvv5vbx10o456ikl6mmab7v5pgpebrilpejictw1kh-c5ewusty0safq5764gvgvknwl \
    162.243.146.81:2377

创建一个Redis服务,以容器作为管理者启动。

docker service create \
  --replicas 1 \
  --name redis \
  --update-delay 10s \
  --publish 6379:6379 \
  --constraint node.hostname==manager \
  redis:latest

在工作的時候運行應用程式。
所使用的應用程式是之前在一篇文章中使用過的程式碼和容器。

每次访问,只需获取从REDIS访问时可变的计数器的值。

docker service create \
  --replicas 2 \
  --name app \
  --update-delay 10s \
  --publish 8000:8000 \
  --env REDIS_HOST=162.243.146.81 \
  --constraint engine.labels.env==production \
  daikikohara/app01:v6 

因为需要一些时间,所以我会等待docker service ps app命令执行完成并启动。

# これだとPrepareだからまだ
$ docker service ps app
ID                         NAME   IMAGE                 NODE     DESIRED STATE  CURRENT STATE             ERROR
7t31od5tkcey8cri9mbhp7elt  app.1  daikikohara/app01:v6  worker2  Running        Preparing 53 seconds ago
2s74twgjjxlrxlgz3v5zxy498  app.2  daikikohara/app01:v6  worker1  Running        Preparing 53 seconds ago

# こうなればOK
$ docker service ps app
ID                         NAME   IMAGE                 NODE     DESIRED STATE  CURRENT STATE          ERROR
7t31od5tkcey8cri9mbhp7elt  app.1  daikikohara/app01:v6  worker2  Running        Running 3 minutes ago
2s74twgjjxlrxlgz3v5zxy498  app.2  daikikohara/app01:v6  worker1  Running        Running 3 minutes ago

顺便提一下,根据上述结果可以看出,只有在将环境标签设为“production”的worker上才会运行容器。

我会使用curl命令访问每个worker节点,以确保能够获取计数器的值。

每个节点的IP地址如下。

$ docker-machine ls
NAME      ACTIVE   DRIVER         STATE     URL                          SWARM   DOCKER    ERRORS
manager   *        digitalocean   Running   tcp://162.243.146.81:2376            v1.12.0
worker1   -        digitalocean   Running   tcp://107.170.250.177:2376           v1.12.0
worker2   -        digitalocean   Running   tcp://107.170.233.85:2376            v1.12.0
worker3   -        digitalocean   Running   tcp://104.131.132.105:2376           v1.12.0

如果向正在运行的worker1和worker2发送请求,自然会得到值。

$ curl http://107.170.250.177:8000
You have visited this page 1 times!

$ curl http://107.170.233.85:8000
You have visited this page 2 times!

使用路由网格,即使容器未在worker3上启动,也可以获取值。

$ curl http://104.131.132.105:8000
You have visited this page 3 times!

嗯,worker3指定了”development”的标签,所以我本以为无法获取它,但在swarm集群的节点上,似乎启用了所有路由网格。
我觉得如果能够设置只能获取指定服务以外的内容会更方便,所以我对未来抱有期望。(也许已经可以设置了吗?)

所以,实际上我只想将production的一个节点进行扩展,以确认反向的production worker也可以正常工作。但从根本上说,我们已经成功验证了,所以就这样结束吧~

健康检查

以上的Dockerfile中添加了HEALTHCHECK指令。使用HEALTHCHECK可以根据自定义逻辑对容器进行健康检查。我已经将名为app01的容器替换为以下内容的Dockerfile,并以v7标签进行发布。

FROM golang:1.6.3
ADD app /app
HEALTHCHECK --interval=10s --timeout=5s --retries=3 CMD curl http://localhost:8000 | grep "You have visited"
CMD /app

如果在上述情况下,以CMD指定的命令每10秒执行一次,在5秒内无法成功获得结果的情况发生连续3次,容器将被视为不健康。

所以,首先启动Redis容器。

docker service create \
  --replicas 1 \
  --name redis \
  --update-delay 10s \
  --publish 6379:6379 \
  --constraint node.hostname==manager \
  redis:latest

接下来启动应用程序。

docker service create \
  --replicas 2 \
  --name app \
  --update-delay 10s \
  --publish 8000:8000 \
  --env REDIS_HOST=162.243.146.81 \
  --constraint engine.labels.env==production \
  daikikohara/app01:v7

我要停止redis服务。

docker service rm redis

由于上述的HEALTHCHECK失败,所以在一段时间后进行确认时可以发现,容器在多次尝试重新启动时仍然失败。

$ docker service ps app
ID                         NAME       IMAGE                 NODE     DESIRED STATE  CURRENT STATE                    ERROR
7u1xdmznc4n1qmxn5m8noeu84  app.1      daikikohara/app01:v7  worker1  Ready          Ready 3 seconds ago
82g81zthfgm0o4b8ylbegsvfr   \_ app.1  daikikohara/app01:v7  worker1  Shutdown       Failed 4 seconds ago             "task: non-zero exit (2)"
9wlenwhsht77zcavdpw39ju7m   \_ app.1  daikikohara/app01:v7  worker1  Shutdown       Failed 10 seconds ago            "task: non-zero exit (2)"
51zxip69n196202i0cqelurf5   \_ app.1  daikikohara/app01:v7  worker1  Shutdown       Failed 16 seconds ago            "task: non-zero exit (2)"
as4vhy7zxh78wj30k3w2b0cdp   \_ app.1  daikikohara/app01:v7  worker1  Shutdown       Failed 22 seconds ago            "task: non-zero exit (2)"
2v1tmjx0qmh0x46pfvklns542  app.2      daikikohara/app01:v7  worker2  Running        Starting less than a second ago
eqqdrefs7w63v239tr1gjy85g   \_ app.2  daikikohara/app01:v7  worker2  Shutdown       Failed 5 seconds ago             "task: non-zero exit (2)"
2r17smeo78j1lppbu9n1z5z9h   \_ app.2  daikikohara/app01:v7  worker2  Shutdown       Failed 11 seconds ago            "task: non-zero exit (2)"
5zkes80bq2wtp8h4b3d2qpora   \_ app.2  daikikohara/app01:v7  worker2  Shutdown       Failed 16 seconds ago            "task: non-zero exit (2)"
e4s1lrwc1ainf5jfzfq1iqmg4   \_ app.2  daikikohara/app01:v7  worker2  Shutdown       Failed 22 seconds ago            "task: non-zero exit (2)"

重新启动Redis后,过一段时间再确认,两个容器都能保持运行状态。

$ docker service ps app
ID                         NAME       IMAGE                 NODE     DESIRED STATE  CURRENT STATE          ERROR
d39j1zw2fs2d1bc4o5tzc5q7n  app.1      daikikohara/app01:v7  worker1  Running        Running 2 minutes ago
9u8nmhwwmkczxqg9pjpcug214   \_ app.1  daikikohara/app01:v7  worker1  Shutdown       Failed 2 minutes ago   "task: non-zero exit (2)"
4yau7s92c0917penlazl5uuq0   \_ app.1  daikikohara/app01:v7  worker1  Shutdown       Failed 2 minutes ago   "task: non-zero exit (2)"
581y6jezbpr6cxwyynnqqvw97   \_ app.1  daikikohara/app01:v7  worker1  Shutdown       Failed 2 minutes ago   "task: non-zero exit (2)"
7u1xdmznc4n1qmxn5m8noeu84   \_ app.1  daikikohara/app01:v7  worker1  Shutdown       Failed 3 minutes ago   "task: non-zero exit (2)"
at0qqu7xhjz90ujmnmgminn00  app.2      daikikohara/app01:v7  worker2  Running        Running 2 minutes ago
f0cq0x7ccq9d88dpspolx78db   \_ app.2  daikikohara/app01:v7  worker2  Shutdown       Failed 2 minutes ago   "task: non-zero exit (2)"
4qpmgm93g899xu9rgr8rrqq30   \_ app.2  daikikohara/app01:v7  worker2  Shutdown       Failed 2 minutes ago   "task: non-zero exit (2)"
1ce8fu69ua6hnqnomho52vb1t   \_ app.2  daikikohara/app01:v7  worker2  Shutdown       Failed 2 minutes ago   "task: non-zero exit (2)"
a5r6fkpme7elaj0qw3kln5zo3   \_ app.2  daikikohara/app01:v7  worker2  Shutdown       Failed 2 minutes ago   "task: non-zero exit (2)"

全球模式

在使用复制服务的情况下,每个节点上都会适当地分布式部署容器,并且通过使用全局模式,您可以确保在每个节点上都会运行一个容器。根据官方文档等,似乎假设需要在每个节点上运行必要的监控、病毒扫描等服务。

docker service create \
  --name redis \
  --mode global \
  --publish 6379:6379 \
  redis:latest


$ docker service ps redis
ID                         NAME       IMAGE         NODE     DESIRED STATE  CURRENT STATE            ERROR
1fitx5g74ujssl9bjbhyz5nv3  redis      redis:latest  worker3  Running        Preparing 7 seconds ago
1quo2c3c9fz3wll6cl57dao4b   \_ redis  redis:latest  worker2  Running        Preparing 7 seconds ago
5paactsnolafblrz0y6j8rhfs   \_ redis  redis:latest  worker1  Running        Preparing 7 seconds ago
coh5zcahl5jedozkqzgcx06g4   \_ redis  redis:latest  manager  Running        Running 6 seconds ago

通过这样的方式,我们确认了每个节点上都运行了一个容器。

其他引起注意的事项 tā de

    • ノード間の通信がデフォルトでTLSになったらしいです。(参考)

pluginコマンドとかも気になるんですが、まだexperimentalな上にドキュメントがよく分からなかったので試してません。。。

如果有其他需要,我会追加和修正以上内容。

广告
将在 10 秒后关闭
bannerAds