可以在多主机环境中使用Swarm与Compose(Fig)进行组合
概述
通过与Swarm结合,可以使Compose(Fig)能够在多主机环境中使用。
将由 Sinatra 容器和 Redis 容器组成的应用程序部署到多个 Docker 主机上。
使用Compose来管理多主机环境
建立Swarm集群。
-
- Docker Swarm リファレンス
- Docker Swarm を使ってマルチホスト環境下で Hello World コンテナを動かす
准备3台Docker主机,以此为参考。
$ docker -H core-01:2377 info
Containers: 4
Nodes: 3
core-01: core-01:2375
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 998 MiB
core-03: core-03:2375
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 998 MiB
core-02: core-02:2375
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 998 MiB
每个端口2375都可以使用Docker Remote API。
-
- core-01: tcp://core-01:2375
core-02: tcp://core-02:2375
core-03: tcp://core-03:2375
$ docker -H core-01:2377 ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8a6d378fd434 swarm:latest "/swarm join --addr= 7 seconds ago Up About a minute 2375/tcp core-02/swarm-agent-core-02
0cd3fbda1f31 swarm:latest "/swarm join --addr= About a minute ago Up About a minute 2375/tcp core-03/swarm-agent-core-03
62b93d0e9f7c swarm:latest "/swarm join --addr= 7 minutes ago Up 7 minutes 2375/tcp core-01/swarm-agent-core-01
df7b39a2eeba swarm:latest "/swarm manage --tls 8 minutes ago Up 8 minutes 172.17.8.101:2377->2375/tcp core-01/swarm-manager
Swarm 管理者位于 core-01,并且 core-01:2377 是其终端节点。(因此使用 $ docker -H core-01:2377 命令)
Swarm 代理分别部署在每个节点上。
-
- core-01
swarm manager
swarm agent 01
core-02
swarm agent 02
core-03
swarm agent 03
在单一主机环境中使用Compose。
首先,在单个主机环境下尝试使用Compose。
- Docker Compose リファレンス
参考此,安装Compose:
- Docker Compose を使って Sinatra と Redis コンテナを 1 コマンドで立ち上げる
基于之前使用过的配置来使用
# docker-compose.yml
web:
image: quay.io/spesnova/sinatra-hello-world
command: bundle exec ruby app.rb
ports:
- 4567
links:
- redis
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
redis:
image: redis:latest
3个要点
-
- コンテナのスケールをする際のポートの衝突を避けるために web サービスの ports は 80:4567 から 4567 に変える
-
- どの Docker ホストからでもイメージが取得できるよう build の代わりに image を指定する(イメージも push しておく)
- 開発時は手元のコードをコンテナと共有したいので VOLUME を使っていたが、今回はできたイメージを使うので web サービスコンテナの volumes を外す
试着启动
# at core-01
$ cd sample
$ docker-compose up -d
Creating sample_redis_1...
Creating sample_web_1...
这种状态
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------
sample_redis_1 /entrypoint.sh redis-server Up 6379/tcp
sample_web_1 bundle exec ruby app.rb Up 172.17.8.101:49153->4567/tcp
尝试进行规模化
$ docker-compose scale web=2
Creating sample_web_2...
Starting sample_web_2...
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------
sample_redis_1 /entrypoint.sh redis-server Up 6379/tcp
sample_web_1 bundle exec ruby app.rb Up 0.0.0.0:49155->4567/tcp
sample_web_2 bundle exec ruby app.rb Up 0.0.0.0:49156->4567/tcp
当然的是,core-01 上启动了两个 web 服务容器。
一旦容器停止,就将其删除。
$ docker-compose kill && docker-compose rm
Killing sample_web_2...
Killing sample_web_1...
Killing sample_redis_1...
Going to remove sample_web_2, sample_web_1, sample_redis_1
Are you sure? [yN] y
Removing sample_redis_1...
Removing sample_web_2...
Removing sample_web_1...
使用Swarm在多主机环境中运行Compose(Fig)。
由于Swarm API与现有的Docker API兼容,可以使用Swarm API代替core-01的Docker API。
使用Swarm API可以实现例如docker run busybox echo hello world的功能,在多个主机中的某一处执行busybox容器。同样地,在Compose中使用,可以实现Sinatra容器+Redis容器的组合在多个主机中的某一处启动。
这是一个图表化的表示
# シングルホスト環境での Compose の利用
Compose ---> Docker Remote API (Docker Host, core-01)
# マルチホスト環境での Compose の利用
---> Docker Remote API(Docker Host, core-01)
/
Compose ---> Swarm API --- ---> Docker Remote API(Docker Host, core-02)
\---> Docker Remote API(Docker Host, core-03)
编辑 docker-compose.yml 以适应 Swarm。
将Swarm API设置为默认使用。
$ export DOCKER_HOST=tcp://core-01:2377
进一步修改 docker-compose.yml
web:
image: quay.io/spesnova/sinatra-hello-world
command: bundle exec ruby app.rb
ports:
- 4567
environment:
- REDIS_HOST=172.17.8.101 # 追加
- REDIS_PORT=6379
- affinity:container!=sample_web_* # 追加
redis:
image: redis:latest
ports:
- 6379:6379 # 追加
environment:
- constraint:node==core-01 # 追加
如果在多个主机上运行Web服务容器时,由于不允许使用LINK,所以无法进行协作。
web サービスコンテナから link を外す
web サービスコンテナの Redis ホストを core-01 に向ける
redis サービスコンテナのポートを外部にさらす
redis コンテナが core-01 で動くように Swarm 用に contraint を設定
另外,通过设置,将Web服务容器配置为在不同的Docker主机上启动。affinity:container!=sample_web_*条件表示,如果存在名为sample_web_*的容器,则不在该容器上启动Web服务容器。
使用Swarm进行规模扩展
尝试使用 docker-compose up -d
$ docker-compose up -d
Creating sample_redis_1...
Creating sample_web_1...
尝试运行 docker-compose ps 和 docker ps
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
sample_redis_1 /entrypoint.sh redis-server Up 6379/tcp
sample_web_1 bundle exec ruby app.rb Up 172.17.8.101:80->4567/tcp
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0fa8b600d765 redis:latest "/entrypoint.sh redi 9 seconds ago Up Less than a second 6379/tcp core-01/sample_redis_1
599a99f51659 sample_web:latest "bundle exec ruby ap 9 seconds ago Up Less than a second 172.17.8.101:80->4567/tcp core-01/sample_web_1
看起来容器在与执行docker-compose命令的主机core-01上启动了。到此为止都很正常。
尝试扩展网络服务容器
$ docker-compose scale web=2
Creating sample_web_2...
Starting sample_web_2...
web_2 已经连接到 core-03
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
23d5276ef844 quay.io/spesnova/sinatra-hello-world:latest "bundle exec ruby ap 3 seconds ago Up Less than a second 172.17.8.103:49155->4567/tcp core-03/sample_web_2
f94b9cf27ba3 redis:latest "/entrypoint.sh redi 43 seconds ago Up 16 seconds 172.17.8.101:6379->6379/tcp core-01/sample_redis_1
8469bdd81f5a quay.io/spesnova/sinatra-hello-world:latest "bundle exec ruby ap 43 seconds ago Up 17 seconds 172.17.8.101:49165->4567/tcp core-01/sample_web_1
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------
sample_redis_1 /entrypoint.sh redis-server Up 172.17.8.101:6379->6379/tcp
sample_web_1 bundle exec ruby app.rb Up 172.17.8.101:49165->4567/tcp
sample_web_2 bundle exec ruby app.rb Up 172.17.8.103:49155->4567/tcp
http://172.17.8.101:49165/
http://172.17.8.103:49155/
你好世界,以及能够递增访问次数。
进一步扩大规模
$ docker-compose scale web=3
Creating sample_web_3...
Starting sample_web_3...
这次站在 core-02 上
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
737f31bf1d0a quay.io/spesnova/sinatra-hello-world:latest "bundle exec ruby ap Less than a second ago Up Less than a second 172.17.8.102:49153->4567/tcp core-02/sample_web_3
23d5276ef844 quay.io/spesnova/sinatra-hello-world:latest "bundle exec ruby ap 2 minutes ago Up 2 minutes 172.17.8.103:49155->4567/tcp core-03/sample_web_2
f94b9cf27ba3 redis:latest "/entrypoint.sh redi 3 minutes ago Up 2 minutes 172.17.8.101:6379->6379/tcp core-01/sample_redis_1
8469bdd81f5a quay.io/spesnova/sinatra-hello-world:latest "bundle exec ruby ap 3 minutes ago Up 2 minutes 172.17.8.101:49165->4567/tcp core-01/sample_web_1
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------
sample_redis_1 /entrypoint.sh redis-server Up 172.17.8.101:6379->6379/tcp
sample_web_1 bundle exec ruby app.rb Up 172.17.8.101:49165->4567/tcp
sample_web_2 bundle exec ruby app.rb Up 172.17.8.103:49155->4567/tcp
sample_web_3 bundle exec ruby app.rb Up 172.17.8.102:49153->4567/tcp
进一步扩大规模
$ docker-compose scale web=4
Creating sample_web_4...
unable to find a node that satisfies container!=sample_web_*
由于找不到没有web容器的Docker主机,因此无法启动,这是一条消息。亲和性已正确运作。
在多主机环境下,可以同时查看日志
$ docker-compose logs
请用中文将以下内容进行改述,只需要一个选项:
参考资料
-
- Docker Swarm リファレンス
- Docker Compose リファレンス