Swarm 模式有一个内置的 DNS 组件,它会自动给 swarm 中的每个服务分配一个 DNS 条目。Swarm 管理器使用internal load balancing 基于服务对应的 DNS 名称在服务之间分发请求。
开始实践
本教程将指导你完成以下任务:
在 Docker Engline swarm 模式下初始化一个集群
添加节点到 swarm
部署服务到 swarm
在一切就绪后管理 swarm
准备工作
在开始本教程之前,你需要准备一下几样东西:
三台通过网络连接的主机
每台主机安装 Docker Engine 1.12 或更新版本
充当管理节点的主机 IP
主机之间开放下面提到的端口
主机之间端口开放
主机之间的以下端口必须是开放。某些环境下,这些端口默认是允许的:
TCP 端口 2377 用于集群管理通信(管理节点)
TCP 和 UDP 端口 7946 用于节点间通信(所有节点)
TCP 和 UDP 端口 4789 用于 overlay 网络流量(所有节点)
如果你的这些端口没有打开,可以用iptables命令打开它们:
1
2
3
4
5
iptables -A INPUT -p tcp --dport 2377 -j ACCEPT
iptables -A INPUT -p tcp --dport 7946 -j ACCEPT
iptables -A INPUT -p udp --dport 7946 -j ACCEPT
iptables -A INPUT -p tcp --dport 4789 -j ACCEPT
iptables -A INPUT -p udp --dport 4789 -j ACCEPT
192.168.33.160 swarm_manager
192.168.33.161 node1
192.168.33.162 node2
创建 swarm
创建一个 swarm
随意选择一个主机作为管理节点,在上面初始化一个 swarm:
[iyunv@swarm_manager ~]# docker swarm init --advertise-addr 192.168.33.160
Swarm initialized: current node (7ik7wqhe5wcag8k5tp816c7ck) is now a manager.
To add a worker to this swarm, run the following command:
[iyunv@node1 ~]# docker swarm join \
--token SWMTKN-1-0p0p5f96e1w4xblhw2eeookrv46spwf4yx7qmve2srxe9wec5g-ellbnyt4cwwvvdkssaj0cbtus \
192.168.33.160:2377
This node joined a swarm as a worker.
[iyunv@node1 ~]# docker swarm join \
--token SWMTKN-1-0p0p5f96e1w4xblhw2eeookrv46spwf4yx7qmve2srxe9wec5g-ellbnyt4cwwvvdkssaj0cbtus \
192.168.59.128:2377
This node joined a swarm as a worker.
查看所有节点的状态
在管理节点上
[iyunv@swarm_manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
622ih8ji5t428lazjx233pvks node2 Ready Active
9e21bk67ey1abzje69lmpvbe1 * swarm_manager Ready Active Leader
f3wzagmtgsn8qyqzidxtw98d3 node1 Ready Active
输出信息第二行 id 后面的*表示当前连接到了该节点。HOSTNAME 栏输出节点的 hostname。MANAGER 用于指示 swarm中的管理节点,该栏值为 Leader 表示为管理节点,空值表示为工作节点。
[iyunv@swarm_manager ~]# docker service ls
ID NAME REPLICAS IMAGE COMMAND
c3hvgwhyim4n helloworld 1/1 busybox:1.25.1-musl /bin/sh -c while true; do echo hello world; sleep 3; done
查看服务的详细信息查看服务的详细信息在管理节点上。
1
2
3
4
5
6
7
8
9
10
11
12
13
[iyunv@swarm_manager ~]# docker service inspect --pretty helloworld
ID: c3hvgwhyim4nllg1qqix7kli6
Name: helloworld
Mode: Replicated
Replicas: 1
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
ContainerSpec:
Image: busybox:1.25.1-musl
Args: /bin/sh -c while true; do echo hello world; sleep 3; done
Resources:
[iyunv@swarm_manager ~]# docker service ps helloworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
556c2lpvr4489yrclo52cjlo5 helloworld.1 busybox:1.25.1-musl node2 Running Running 3 minutes ago
[iyunv@node2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
964ddb3220b6 busybox:1.25.1-musl "/bin/sh -c 'while tr" 5 minutes ago Up 5 minutes helloworld.1.556c2lpvr4489yrclo52cjlo5
伸缩服务伸缩服务的任务数量在管理节点上
1
2
3
[iyunv@node2 ~]# docker service scale helloworld=5
helloworld scaled to 5
我们将服务的数量伸缩到5。
查看服务列表在管理节点上:
1
2
3
4
5
6
7
[iyunv@swarm_manager ~]# docker service ps helloworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
556c2lpvr4489yrclo52cjlo5 helloworld.1 busybox:1.25.1-musl node2 Running Running 10 minutes ago
e2tw7i9bkjb32jrr3sdztskwe helloworld.2 busybox:1.25.1-musl swarm_manager Running Running 24 seconds ago
d5plppbjvtr1rany4tzb88czc helloworld.3 busybox:1.25.1-musl node2 Running Running 28 seconds ago
a0hs8ik837jl7mlgeaowws1i3 helloworld.4 busybox:1.25.1-musl node1 Running Running 18 seconds ago
bo27jnf7n59hqzl9m9jnpwbks helloworld.5 busybox:1.25.1-musl swarm_manager Running Running 24 seconds ago
在各节点上查看服务首先是管理节点:
1
2
3
4
[iyunv@swarm_manager ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
46aa83031ad7 busybox:1.25.1-musl "/bin/sh -c 'while tr" About a minute ago Up About a minute helloworld.2.e2tw7i9bkjb32jrr3sdztskwe
e1cb3bd1bfb0 busybox:1.25.1-musl "/bin/sh -c 'while tr" About a minute ago Up About a minute helloworld.5.bo27jnf7n59hqzl9m9jnpwbks
再是工作节点1
1
2
3
[iyunv@node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c200722ace5 busybox:1.25.1-musl "/bin/sh -c 'while tr" About a minute ago Up About a minute helloworld.4.a0hs8ik837jl7mlgeaowws1i3
再是工作节点2
1
2
3
4
[iyunv@node2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2dba702ccd68 busybox:1.25.1-musl "/bin/sh -c 'while tr" About a minute ago Up About a minute helloworld.3.d5plppbjvtr1rany4tzb88czc
964ddb3220b6 busybox:1.25.1-musl "/bin/sh -c 'while tr" 11 minutes ago Up 11 minutes helloworld.1.556c2lpvr4489yrclo52cjlo5
可以看到:管理节点上运行了两个任务,工作节点1运行了两个任务,工作节点2运行了1个任务。 删除 swarm 上运行的服务删除在管理节点上
[iyunv@swarm_manager ~]# docker service rm helloworld
helloworld 确认在管理节点上
[iyunv@swarm_manager ~]# docker service ls
ID NAME REPLICAS IMAGE COMMAND
[iyunv@swarm_manager ~]#
[iyunv@swarm_manager ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7c5ebb8678b redis:3.2.5-alpine "docker-entrypoint.sh" 4 minutes ago Up 4 minutes 6379/tcp redis.1.e69zhhxz66jmlm0h15gj89s2x
524aadad84b8 redis:3.0.7-alpine "docker-entrypoint.sh" 7 minutes ago Exited (0) 5 minutes ago redis.2.39jitd0mzztl0mpy6k6rppkx5
可以看出更新后,swarm并没有删除旧的容器。 下线某个节点在前面的步骤中,所有的节点都处于运行状态且可用性为ACTIVE。swarm 管理器可以将任务分配给任何可用性为 ACTIVE 的节点,所以到目前为止,所有节点都可以接收任务。
有时候,比如到了计划的维护时间,你需要将节点的可用性设为DRAIN。可用性为DRAIN的节点不会从 swarm 接收任何新任务。同时,管理器将停止运行在该节点上的任务,并在另外可用性为 ACTIVE 的节点上启动相应的任务副本。 确认所有节点都是活跃可用的
1
2
3
4
5
[iyunv@swarm_manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
622ih8ji5t428lazjx233pvks node2 Ready Active
9e21bk67ey1abzje69lmpvbe1 * swarm_manager Ready Active Leader
f3wzagmtgsn8qyqzidxtw98d3 node1 Ready Active
[iyunv@swarm_manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
622ih8ji5t428lazjx233pvks node2 Ready Drain
9e21bk67ey1abzje69lmpvbe1 * swarm_manager Ready Active Leader
f3wzagmtgsn8qyqzidxtw98d3 node1 Ready Active
[iyunv@swarm_manager ~]# docker node inspect --pretty node2
ID: 622ih8ji5t428lazjx233pvks
Hostname: node2
Joined at: 2017-10-25 06:45:04.369968305 +0000 utc
Status:
State: Ready
Availability: Drain
Platform:
Operating System: linux
Architecture: x86_64
Resources:
CPUs: 1
Memory: 985.6 MiB
Plugins:
Network: bridge, host, null, overlay
Volume: local
Engine Version: 1.12.6
可以看到该节点的状态为Ready,但可用性为Drain。 再次查看任务的分配情况
1
2
3
4
5
6
7
8
9
[iyunv@swarm_manager ~]# docker service ps redis
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
e69zhhxz66jmlm0h15gj89s2x redis.1 redis:3.2.5-alpine swarm_manager Running Running 8 minutes ago
63h5wy36474k01vmr5jppbbxs \_ redis.1 redis:3.0.7-alpine node1 Shutdown Shutdown 9 minutes ago
6q046y1camb43b146kj2jaxe4 redis.2 redis:3.2.5-alpine node1 Running Running about a minute ago
1h9e8m9v3rx3hgx5x2bn71kim \_ redis.2 redis:3.2.5-alpine node2 Shutdown Shutdown about a minute ago
39jitd0mzztl0mpy6k6rppkx5 \_ redis.2 redis:3.0.7-alpine swarm_manager Shutdown Shutdown 9 minutes ago
8pwrkq6558fwp8oiiu0uq484h redis.3 redis:3.2.5-alpine node1 Running Running 8 minutes ago
6usd4p2mj7p597ilgs490ou7a \_ redis.3 redis:3.0.7-alpine node2 Shutdown Shutdown 8 minutes ago
再次将被下线的节点重置为活动状态
1
2
[iyunv@swarm_manager ~]# docker node update --availability active node2
node2
确认该节点的新状态
1
2
3
4
5
[iyunv@swarm_manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
622ih8ji5t428lazjx233pvks node2 Ready Active
9e21bk67ey1abzje69lmpvbe1 * swarm_manager Ready Active Leader
f3wzagmtgsn8qyqzidxtw98d3 node1 Ready Active
说明现在该节点又可以重新接收任务了。
再看看 node2 节点上是否被分配了任务:
1
2
3
4
5
[iyunv@swarm_manager ~]# docker service ps -f desired-state=running redis
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
e69zhhxz66jmlm0h15gj89s2x redis.1 redis:3.2.5-alpine swarm_manager Running Running 10 minutes ago
6q046y1camb43b146kj2jaxe4 redis.2 redis:3.2.5-alpine node1 Running Running 2 minutes ago
8pwrkq6558fwp8oiiu0uq484h redis.3 redis:3.2.5-alpine node1 Running Running 9 minutes ago