执行docker run命令时,一定要加上--net myapp。
这是一个完整的分步教程 (online version):
如何在多主机网络的集群上部署 swarm
TL;DR: 使用Swarm 部署多主机网络的分步教程。我想尽快把这个教程放到网上,所以我什至没有花时间做演示。降价文件在the github of my website 上可用。随意改编和分享,它是licensed under a Creative Commons Attribution 4.0 International License。
先决条件
环境
Swarm manager 和 consul master 将在名为 bugs20 的机器上运行。其他节点,bugs19、bugs18、bugs17 和 bugs16,将是swarm 代理和consul 成员。
在我们开始之前
Consul 用于多主机网络,可以使用任何其他键值存储——注意引擎支持Consul Etcd, and ZooKeeper。
令牌(或静态文件)用于swarm 代理发现。令牌使用 REST API,最好使用静态文件。
网络
网络范围为 192.168.196.0/25。名为 bugsN 的主机 IP 地址为 192.168.196.N。
码头工人守护进程
所有节点都在运行 docker daemon,如下所示:
/usr/bin/docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-advertise eth0:2375 --cluster-store consul://127.0.0.1:8500
选项详情:
-H tcp://0.0.0.0:2375
将守护进程绑定到接口以允许成为swarm 集群的一部分。一个IP地址显然可以指定,如果你有多个网卡,这是一个更好的解决方案。
--cluster-advertise eth0:2375
定义 docker 守护进程的接口和端口应该用来宣传自己。
--cluster-store consul://127.0.0.1:8500
定义分布式存储后端的 URL。在我们的例子中,我们使用consul,虽然还有其他发现工具可以使用,如果你想下定决心,你应该有兴趣阅读this service discovery comparison。
由于consul 是分发的,URL 可以是本地的(请记住,swarm 代理也是consul 成员),这更灵活,因为您不必指定consul 的 IP 地址master 并在 docker daemon 启动后被选中。
使用的别名
在以下命令中使用了这两个别名:
alias ldocker='docker -H tcp://0.0.0.0:2375'
alias swarm-docker='docker -H tcp://0.0.0.0:5732' #used only on the swarm manager
确保您的$PATH 中有 consul 二进制文件的路径。进入目录后,只需键入 export PATH=$PATH:$(pwd) 即可。
还假设变量$IP 已正确设置和导出。可以通过.bashrc 或.zshrc 或其他方式完成,如下所示:
export IP=$(ifconfig |grep "192.168.196."|cut -d ":" -f 2|cut -d " " -f 1)
领事
让我们根据需要开始部署所有consul成员和master。
领事大师(bugs20)
consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node=master -bind=$IP -client $IP
选项详情:
agent -server
将consul 代理作为服务器启动。
-bootstrap-expect 1
我们希望只有一位大师。
-node=master20
这个consul server/master 将被命名为“master20”。
-bind=192.168.196.20
指定应绑定的 IP 地址。如果您只有一个 NIC,则为可选。
-client=192.168.196.20
指定应该绑定服务器的 RPC IP 地址。默认情况下它是本地主机。请注意,我不确定此选项的必要性,并且此强制为本地请求添加 -rpc-addr=192.168.196.20:8400,例如 consul members -rpc-addr=192.168.196.20:8400 或 consul join -rpc-addr=192.168.196.20:8400 192.168.196.9 以加入 IP 地址为 192.168.196.9 的 consul 成员。
领事成员(错误{16..19})
consul agent -data-dir /tmp/consul -node=$HOSTNAME -bind=192.168.196.N
建议使用tmux,或类似的,带有选项:setw synchronize-panes on,所以这个命令:consul -d agent -data-dir /tmp/consul -node=$HOST -bind=$IP 启动所有consul 成员。
加入领事成员
consul join -rpc-addr=192.168.196.20:8400 192.168.196.16
consul join -rpc-addr=192.168.196.20:8400 192.168.196.17
consul join -rpc-addr=192.168.196.20:8400 192.168.196.18
consul join -rpc-addr=192.168.196.20:8400 192.168.196.19
也可以使用单行命令。如果你使用的是 zsh,那么consul join -rpc-addr=192.168.196.20:8400 192.168.196.{16..19} 就足够了,或者一个 foo 循环:for i in $(seq 16 1 19); do consul join -rpc-addr=192.168.196.20:8400 192.168.196.$i;done。您可以使用以下命令验证您的成员是否属于您的 consul 部署:
consul members -rpc-addr=192.168.196.20:8400
Node Address Status Type Build Protocol DC
master20 192.168.196.20:8301 alive server 0.5.2 2 dc1
bugs19 192.168.196.19:8301 alive client 0.5.2 2 dc1
bugs18 192.168.196.18:8301 alive client 0.5.2 2 dc1
bugs17 192.168.196.17:8301 alive client 0.5.2 2 dc1
bugs16 192.168.196.16:8301 alive client 0.5.2 2 dc1
Consul 成员和主服务器已部署并正在工作。现在重点将放在 docker 和 swarm。
群
在下文中,将使用两种不同的方法详细说明 swarm manager 和 swarm 成员发现的创建:令牌和静态文件。令牌使用 Docker Hub 的托管发现服务,而静态文件只是本地文件,不使用网络(也不使用任何服务器)。应该首选静态文件解决方案(实际上更容易)。
[静态文件]在加入 swarm 成员时启动 swarm manager
创建一个名为/tmp/cluster.disco 的文件,内容为swarm_agent_ip:2375。
cat /tmp/cluster.disco
192.168.196.16:2375
192.168.196.17:2375
192.168.196.18:2375
192.168.196.19:2375
然后按如下方式启动 swarm manager:
ldocker run -v /tmp/cluster.disco:/tmp/cluster.disco -d -p 5732:2375 swarm manage file:///tmp/cluster.disco
你就完成了!
[token] 创建并启动 swarm manager
在 swarm master (bugs20) 上,创建一个 swarm:
ldocker run --rm swarm create > swarm_id
这将创建一个 swarm 并将令牌 ID 保存在当前目录的文件 swarm_id 中。创建后,swarm manager 需要作为守护进程运行:
ldocker run -d -p 5732:2375 swarm manage token://`cat swarm_id`
要验证它是否已启动,您可以运行:
ldocker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d28238445532 swarm "/swarm manage token:" 5 seconds ago Up 4 seconds 0.0.0.0:5732->2375/tcp cranky_liskov
[token] 将 swarm 成员加入 swarm 集群
那么 swarm manager 将需要一些 swarm agent 加入。
ldocker run swarm join --addr=192.168.196.16:2375 token://`cat swarm_id`
ldocker run swarm join --addr=192.168.196.17:2375 token://`cat swarm_id`
ldocker run swarm join --addr=192.168.196.18:2375 token://`cat swarm_id`
ldocker run swarm join --addr=192.168.196.19:2375 token://`cat swarm_id`
std[in|out] 会很忙,这些命令需要在不同的终端上运行。在join 之前添加-d 应该可以解决这个问题,并启用for 循环来进行连接。
swarm 成员加入后:
auzias@bugs20:~$ ldocker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1de6e4ee3fc swarm "/swarm join --addr=1" 5 seconds ago Up 4 seconds 2375/tcp fervent_lichterman
338572b87ce9 swarm "/swarm join --addr=1" 6 seconds ago Up 4 seconds 2375/tcp mad_ramanujan
7083e4d6c7ea swarm "/swarm join --addr=1" 7 seconds ago Up 5 seconds 2375/tcp naughty_sammet
0c5abc6075da swarm "/swarm join --addr=1" 8 seconds ago Up 6 seconds 2375/tcp gloomy_cray
ab746399f106 swarm "/swarm manage token:" 25 seconds ago Up 23 seconds 0.0.0.0:5732->2375/tcp ecstatic_shockley
群成员发现后
要验证成员是否被发现,可以执行swarm-docker info:
auzias@bugs20:~$ swarm-docker info
Containers: 4
Images: 4
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 4
bugs16: 192.168.196.16:2375
└ Containers: 0
└ Reserved CPUs: 0 / 12
└ Reserved Memory: 0 B / 49.62 GiB
└ Labels: executiondriver=native-0.2, kernelversion=3.16.0-4-amd64, operatingsystem=Debian GNU/Linux 8 (jessie), storagedriver=aufs
bugs17: 192.168.196.17:2375
└ Containers: 0
└ Reserved CPUs: 0 / 12
└ Reserved Memory: 0 B / 49.62 GiB
└ Labels: executiondriver=native-0.2, kernelversion=3.16.0-4-amd64, operatingsystem=Debian GNU/Linux 8 (jessie), storagedriver=aufs
bugs18: 192.168.196.18:2375
└ Containers: 0
└ Reserved CPUs: 0 / 12
└ Reserved Memory: 0 B / 49.62 GiB
└ Labels: executiondriver=native-0.2, kernelversion=3.16.0-4-amd64, operatingsystem=Debian GNU/Linux 8 (jessie), storagedriver=aufs
bugs19: 192.168.196.19:2375
└ Containers: 4
└ Reserved CPUs: 0 / 12
└ Reserved Memory: 0 B / 49.62 GiB
└ Labels: executiondriver=native-0.2, kernelversion=3.16.0-4-amd64, operatingsystem=Debian GNU/Linux 8 (jessie), storagedriver=aufs
CPUs: 48
Total Memory: 198.5 GiB
Name: ab746399f106
此时 swarm 已部署,所有运行的容器都将运行在不同的节点上。通过执行几个:
auzias@bugs20:~$ swarm-docker run --rm -it ubuntu bash
然后是:
auzias@bugs20:~$ swarm-docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
45b19d76d38e ubuntu "bash" 6 seconds ago Up 5 seconds bugs18/boring_mccarthy
53e87693606e ubuntu "bash" 6 seconds ago Up 5 seconds bugs16/amazing_colden
b18081f26a35 ubuntu "bash" 6 seconds ago Up 4 seconds bugs17/small_newton
f582d4af4444 ubuntu "bash" 7 seconds ago Up 4 seconds bugs18/naughty_banach
b3d689d749f9 ubuntu "bash" 7 seconds ago Up 4 seconds bugs17/pensive_keller
f9e86f609ffa ubuntu "bash" 7 seconds ago Up 5 seconds bugs16/pensive_cray
b53a46c01783 ubuntu "bash" 7 seconds ago Up 4 seconds bugs18/reverent_ritchie
78896a73191b ubuntu "bash" 7 seconds ago Up 5 seconds bugs17/gloomy_bell
a991d887a894 ubuntu "bash" 7 seconds ago Up 5 seconds bugs16/angry_swanson
a43122662e92 ubuntu "bash" 7 seconds ago Up 5 seconds bugs17/pensive_kowalevski
68d874bc19f9 ubuntu "bash" 7 seconds ago Up 5 seconds bugs16/modest_payne
e79b3307f6e6 ubuntu "bash" 7 seconds ago Up 5 seconds bugs18/stoic_wescoff
caac9466d86f ubuntu "bash" 7 seconds ago Up 5 seconds bugs17/goofy_snyder
7748d01d34ee ubuntu "bash" 7 seconds ago Up 5 seconds bugs16/fervent_einstein
99da2a91a925 ubuntu "bash" 7 seconds ago Up 5 seconds bugs18/modest_goodall
cd308099faac ubuntu "bash" 7 seconds ago Up 6 seconds bugs19/furious_ritchie
如图所示,容器是通过错误传播的{16...19}。
多主机网络
需要一个网络覆盖,以便所有容器都可以“插入”这个覆盖。要创建此网络覆盖,请执行:
auzias@bugs20:~$ swarm-docker network create -d overlay net
auzias@bugs20:~$ swarm-docker network ls|grep "net"
c96760503d06 net overlay
瞧!
创建此覆盖后,将--net net 添加到命令swarm-docker run --rm -it ubuntu bash 中,您的所有容器都将能够进行本地通信,就好像它们在同一个局域网上一样。默认网络为 10.0.0.0/24。
启用多播
默认覆盖不支持多播。需要另一个驱动程序才能使用多播。 docker 插件weave net 确实支持多播。
要使用此驱动程序,安装后,您需要在所有 Swarm 代理和 Swarm 管理器上运行 $weave launch。然后你需要将编织连接在一起,这是通过运行$weave connect $SWARM_MANAGER_IP 来完成的。这显然不是 Swarm 管理器的 IP 地址,但这样做更简洁(或使用除 Swarm 代理之外的其他节点)。
此时 weave 集群已部署完毕,但尚未创建 weave 网络。运行$swarm-docker network create --driver weave weave-net 将创建名为weave-net 的编织网络。使用--net weave-net 启动容器将使它们能够共享同一个 LAN 并使用多播。启动此类容器的完整命令示例为:$swarm-docker run --rm -it --privileged --net=weave-net ubuntu bash。