docker群的几个副本

尝试将容器部署到群集中。 执行命令:

docker service create --name backend --replicas 3 --publish published=8080,target=80 my-repo/subserver:latest 

它开始3个副本,但其中一个总是有错误:

 docker service ps --no-trunc backend ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 0759ox8aganle2banj4s1uc31 backend.1 my-repo/subserver:latest Debian-70-wheezy-64-minimal Running Running 2 minutes ago zjm9tf5ca1t58iuyjsyjqpjnq backend.2 my-repo/subserver:latest Debian-70-wheezy-64-minimal Running Running 2 minutes ago u9ebicuyh0it6kvpaj9n7id2b backend.3 my-repo/subserver:latest Debian-70-wheezy-64-minimal Ready Ready less than a second ago 4kgwlm4rddj7zefr9tc1xst75 \_ backend.3 my-repo/subserver:latest Debian-70-wheezy-64-minimal Shutdown Failed 2 seconds ago "starting container failed: Address already in use" dqvsyy5cjd95iid845ylrpdzi \_ backend.3 my-repo/subserver:latest Debian-70-wheezy-64-minimal Shutdown Failed 8 seconds ago "starting container failed: Address already in use" ki0y94msyswqirm03qr7ldzl6 \_ backend.3 my-repo/subserver:latest Debian-70-wheezy-64-minimal Shutdown Failed 13 seconds ago "starting container failed: Address already in use" emydpjqzzo5ce2ngid9ap9pb7 \_ backend.3 my-repo/subserver:latest Debian-70-wheezy-64-minimal Shutdown Failed 19 seconds ago "starting container failed: Address already in use" 

尝试不同的端口。 容器包含PHP-FPM和nginx。 服务以bash脚本开始:

 #!/bin/bash service nginx start service php7.0-fpm start while /bin/true; do ps aux |grep nginx |grep -q -v grep PROCESS_1_STATUS=$? ps aux |grep php |grep -q -v grep PROCESS_2_STATUS=$? # If the greps above find anything, they will exit with 0 status # If they are not both 0, then something is wrong if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then echo "One of the processes has already exited." exit -1 fi sleep 60 done 

Docker文件只公开了80端口。

在群集模式下使用缩放时,不要发布端口。 你只会遇到麻烦。
正确的方法是:

  1. 创build一个dockernetworking
  2. 将您的服务分配给此networking(不要发布端口)
  3. 在gobal模式下使用反向代理(例如nginx,apache或traefik),使您的服务在端口80上公开

所以你的反向代理只会调用你的服务的名字( --name your_service ),而内部的docker swarm模式将使用它的循环负载均衡器来调用你的第n个服务( --replicas n

这就是Docker群体模式的devise方式,并且通过负载均衡的方式进行缩放。

这里发生的是你正在尝试创build多个服务都附加到同一个端口。 只有一个服务可以附加到任何一个端口 – 这不是特定于Docker的,您将在未来的技术尝试中遇到这个问题。

然而; 有趣的是,默认情况下Swarm模式是ingressnetworking被设置为默认networking – 这是一个带路由网格的覆盖networking; 实际情况是,Docker正在为您处理的是Layer-3 IP负载平衡。

所以你很好奇你遇到了这个问题 – 我敢说,你正在运行一个老版本的Docker。

如果你想自己解决这个问题 – 最简单的方法是创build一个覆盖networking,例如:

 docker network create --driver overlay my_new_network 

然后,当创build你的服务,确保你指定的networking:

 docker service create --network my_new_network --name backend --replicas 3 --publish published=8080,target=80 my-repo/subserver:latest 

这将解决基于IP的路由; 但是如果你想要做一些基于主机的路由,你可以像@Markus所说的那样使用一个Layer-7负载平衡器,比如Traefik,Docker Flow Proxy,HAProxy等等。