Docker Swarm集成搭建
Swarm是Docker公司自研发的容器集群管理系统,Swarm在早期是作为一个独立服务存在,在Docker Engine v1.12中集成了Swarm的集群管理
和编排功能。可以通过初始化Swarm或加入现有Swarm来启用Docker引擎的Swarm模式。
Docker Engine CLI和API包括了管理Swarm节点命令,比如添加、删除节点,以及在Swarm中部署和编排服务。
也增加了服务栈(Stack)、服务(Service)、任务(Task)概念
功能特点:
a.与Docker Engine集成的集群管理:
使用Docker Engine CLI创建一组Docker引擎,您可以在其中部署应用程序服务。您不需要其他编排软件来创建或管理群集。
b.节点分散式设计:
Docker Engine不是在部署时处理节点角色之间的差异,而是在运行时处理角色变化。您可以使用Docker Engine部署两种类型的节点,管理节点和工作节点。这意味着您可以从单个服务器构建整个群集。
c.声明性服务模型:
Docker Engine使用声明性方法来定义应用程序堆栈中各种服务的所需状态。例如,您可以描述由具有消息队列服务和数据库后端的Web前端服务组成的应用程序。
d.可扩容与缩放容器:
对于每个服务,您可以声明要运行的任务数。当您向上或向下缩放时,swarm管理器通过添加或删除任务来自动适应,以保持所需的任务数量来保证集群的可靠状态。
e.容器容错状态协调:
群集管理器节点不断监视群集状态,并协调您表示的期望状态的实际状态之间的任何差异。例如,如果设置一个服务以运行容器的10个副本,并且托管其中两个副本的工作程序计算机崩溃,则管理器将创建两个新副本以替换崩溃的副本。 swarm管理器将新副本分配给正在运行和可用的worker节点上。
f.多主机网络:
您可以为服务指定覆盖网络。当swarm管理器初始化或更新应用程序时,它会自动为覆盖网络上的容器分配地址。
g.服务发现:
Swarm管理器节点为swarm中的每个服务分配唯一的DNS名称,并负载平衡运行的容器。您可以通过嵌入在swarm中的DNS服务器查询在群中运行的每个容器。
h.负载平衡:
您可以将服务的端口公开给外部负载平衡器。在内部,swarm允许您指定如何在节点之间分发服务容器。
m.缺省安全:
群中的每个节点强制执行TLS相互验证和加密,以保护其自身与所有其他节点之间的通信。您可以选择使用自签名根证书或来自自定义根CA的证书。
n.滚动更新:
在已经运行期间,您可以增量地应用服务更新到节点。 swarm管理器允许您控制将服务部署到不同节点集之间的延迟。如果出现任何问题,您可以将任务回滚到服务的先前版本。
我的三台测试机
IP | 角色 |
---|---|
172.16.10.85 | manager |
172.16.10.86 | worker |
172.16.10.87 | worker |
创建集群
在创建集群前,如果开启了防火墙,请确认三台主机的防火墙能让swarm需求的端口开放,需要打开主机之间的端口,以下端口必须可用。在某些系统上,这些端口默认为打开。
- 2377:TCP端口2377用于集群管理通信
- 7946:TCP和UDP端口7946用于节点之间的通信
- 4789:TCP和UDP端口4789用于覆盖网络流量
可以直接禁用系统防火墙来让这些端口通信不受限制,一般测试环境我们都会禁用防火墙
systemctl stop firewalld(立即生效)
systemctl disable firewalld(重启生效)
docker环境自行安装
常用命令
在Docker Swarm中经常使用的主要有docker swarm、docker node、docker service、docker stack。
docker swarm
管理swarm,添加节点
Commands:
init Initialize a swarm
join Join a swarm as a node and/or manager
join-token Manage join tokens
leave Leave the swarm
unlock Unlock swarm
unlock-key Manage the unlock key
update Update the swarm
docker node
用于管理节点
Commands:
demote Demote one or more nodes from manager in the swarm
inspect Display detailed information on one or more nodes
ls List nodes in the swarm
promote Promote one or more nodes to manager in the swarm
ps List tasks running on one or more nodes, defaults to current node
rm Remove one or more nodes from the swarm
update Update a node
docker service
管理service
Commands:
create Create a new service
inspect Display detailed information on one or more services
logs Fetch the logs of a service or task
ls List services
ps List the tasks of one or more services
rm Remove one or more services
scale Scale one or multiple replicated services
update Update a service
docker stack
与docker-compose结合的命令,可以方便地在集群中部署应用。
Commands:
deploy Deploy a new stack or update an existing stack
ls List stacks
ps List the tasks in the stack
rm Remove one or more stacks
services List the services in the stack
初始化swarm:
docker swarm init --advertise-addr 172.16.10.85(本机IP)
在其它两台worker主机上执行加入swarm:
[root@swarm-m ~]# docker swarm init --advertise-addr 172.16.10.85
Swarm initialized: current node (mclobj2doj65sek345mjkklfo) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-42w2dmkv2u18k9d6vi65rhqggjcqcc31iijnecd4bbi43bmom2-b3o89g28thkcken0v3qxtczuj 172.16.10.85:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
如果后续我们有新的主机被当做manager、worker节点想要加入到集群中来,但要不记得当时创建集群时的token,在manager主机上执行以下命令:
docker swarm join-token manager
docker swarm join-token worker
查看swarm的节点
[root@swarm-m ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
mclobj2doj65sek345mjkklfo * swarm-m.nahong.com.cn Ready Active Leader 18.06.1-ce
oyrkdwj3da9r275jxsj0lyqxe swarm-node01.nahong.cm.cn Ready Active 18.06.1-ce
f295ymtj2t3vjojdbuwclykva swarm-node02.nahong.com.cn Ready Active 18.06.1-ce
AVAILABILITY列的说明:
- Active 意味着调度程序可以将任务分配给节点。
- Pause 意味着调度程序不会将新任务分配给节点,但现有任务仍在运行。
- Drain 意味着调度程序不会向节点分配新任务。调度程序关闭所有现有任务并在可用节点上调度它们。
MANAGER STATUS列的说明
显示节点是属于manager或者worker
- 没有值 表示不参与群管理的工作节点。
- Leader 意味着该节点是使得群的所有群管理和编排决策的主要管理器节点。
- Reachable 意味着节点是管理者节点正在参与Raft共识。如果领导节点不可用,则该节点有资格被选为新领导者。
- Unavailable 意味着节点是不能与其他管理器通信的管理器。如果管理器节点不可用,您应该将新的管理器节点加入群集,或者将工作器节点升级为管理器。
升级或降级节点
您可以将工作程序节点提升为manager角色。这在管理器节点不可用或者您希望使管理器脱机以进行维护时很有用。 类似地,您可以将管理器节点降级为worker角色。
无论您升级或降级节点,您应该始终在群中维护奇数个管理器节点。
要升级一个节点或一组节点,请从管理器节点运行docker node promote:
[root@swarm-m ~]# docker node promote swarm-node01.nahong.cm.cn
Node swarm-node01.nahong.cm.cn promoted to a manager in the swarm.
[root@swarm-m ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
mclobj2doj65sek345mjkklfo * swarm-m.nahong.com.cn Ready Active Leader 18.06.1-ce
oyrkdwj3da9r275jxsj0lyqxe swarm-node01.nahong.cm.cn Ready Active Reachable 18.06.1-ce
f295ymtj2t3vjojdbuwclykva swarm-node02.nahong.com.cn Ready Active 18.06.1-ce
要降级一个节点或一组节点,请从管理器节点运行docker node demote:
[root@swarm-m ~]# docker node demote swarm-node01.nahong.cm.cn
Manager swarm-node01.nahong.cm.cn demoted in the swarm.
[root@swarm-m ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
mclobj2doj65sek345mjkklfo * swarm-m.nahong.com.cn Ready Active Leader 18.06.1-ce
oyrkdwj3da9r275jxsj0lyqxe swarm-node01.nahong.cm.cn Ready Active 18.06.1-ce
f295ymtj2t3vjojdbuwclykva swarm-node02.nahong.com.cn Ready Active 18.06.1-ce
创建自定义的overlay网络:
docker network create --driver overlay --subnet 10.10.10.0/24 my-overlay-network
查询swarm网络 docker network ls
[root@docker01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
24de50a56f99 bridge bridge local
a4e5dcbfd6b8 docker_gwbridge bridge local
a261cf27e5bb host host local
l5abdspoesd9 ingress overlay swarm
lp2f4kze0osc my-overlay-network overlay swarm
d625b46d604a none null local
创建一个nginx service
先摘取docker镜像
docker pull linuxserver/nginx
执行命令创建service:
docker service create --name webapp-nginx --replicas 3 --network my-overlay-network --publish 8089:80 linuxserver/nginx
docker service create中的参数:
- --name 服务名
- --replicas 是创建的副本的数量
- --network 是使用的网络
- --publish 是服务公开的端口 <Publish-Port>:<Target-Port>
查看webapp-nginx服务任务分配到的节点 docker service ps webapp-nginx
[root@swarm-m ~]# docker service ps webapp-nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
sv6y9jedbetw webapp-nginx.1 linuxserver/nginx:latest swarm-node02.nahong.com.cn Running Running about a minute ago
k26fewhj9lzq webapp-nginx.2 linuxserver/nginx:latest swarm-m.nahong.com.cn Running Running about a minute ago
jnr2t0msnumy webapp-nginx.3 linuxserver/nginx:latest swarm-node01.nahong.cm.cn Running Running 52 seconds ago
外部访问公开端口8089
- http://172.16.10.85:8089
- http://172.16.10.86:8089
-
http://172.16.10.87:8089
都会访问成功,这里就出一个85的截图
o01.png
查看manager主机上的docker容器
[root@swarm-m ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d412b3ce543e linuxserver/nginx:latest "/init" 4 minutes ago Up 4 minutes 80/tcp, 443/tcp webapp-nginx.2.k26fewhj9lzqpva03zv6mgtpm
查看manager节点容器网络
[root@swarm-m ~]# docker exec d412b3ce543e ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0A:FF:00:08
inet addr:10.255.0.8 Bcast:10.255.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
eth1 Link encap:Ethernet HWaddr 02:42:0A:0A:0A:08
inet addr:10.10.10.8 Bcast:10.10.10.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1450 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
eth2 Link encap:Ethernet HWaddr 02:42:AC:12:00:03
inet addr:172.18.0.3 Bcast:172.18.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:648 (648.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
eth0、eth1、eth2网卡分别:
- eth0:10.255.0.8 属于docker的ingress网络
- eth1:10.10.10.8 属于overlay的自定义网络my-overlay-network
- eth2:172.18.0.3 属于docker_gwbridge网络
ingress网络会用于容器间的负载均衡,docker_gwbridge网络用于容器连接外网。
到另外两台查看网络:
[root@swarm-node01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
34dd665161bd linuxserver/nginx:latest "/init" About an hour ago Up About an hour 80/tcp, 443/tcp webapp-nginx.3.jnr2t0msnumyd6znib3smcdj7
[root@swarm-node01 ~]# docker exec 34dd665161bd ifconfig | grep -A 1 eth1
eth1 Link encap:Ethernet HWaddr 02:42:0A:0A:0A:06
inet addr:10.10.10.6 Bcast:10.10.10.255 Mask:255.255.255.0
[root@swarm-node02 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba325bc18b97 linuxserver/nginx:latest "/init" About an hour ago Up About an hour 80/tcp, 443/tcp webapp-nginx.1.sv6y9jedbetw3lbxebtneqhf6
[root@swarm-node02 ~]# docker exec ba325bc18b97 ifconfig | grep -A 1 eth1
eth1 Link encap:Ethernet HWaddr 02:42:0A:0A:0A:07
inet addr:10.10.10.7 Bcast:10.10.10.255 Mask:255.255.255.0
三个容器自定义IP分别是:
- 10.10.10.8 manager主机的nginx容器
- 10.10.10.6 worker主机的nginx容器
- 10.10.10.7 worker主机的nginx容器
在容器10.10.10.6上ping 10.10.10.8
[root@swarm-node02 ~]# docker exec ba325bc18b97 ping 10.10.10.8
PING 10.10.10.8 (10.10.10.8): 56 data bytes
64 bytes from 10.10.10.8: seq=0 ttl=64 time=0.965 ms
64 bytes from 10.10.10.8: seq=1 ttl=64 time=0.600 ms
64 bytes from 10.10.10.8: seq=2 ttl=64 time=0.710 ms
64 bytes from 10.10.10.8: seq=3 ttl=64 time=0.587 ms
64 bytes from 10.10.10.8: seq=4 ttl=64 time=0.706 ms
64 bytes from 10.10.10.8: seq=5 ttl=64 time=0.555 ms
Swarm还内置了DNS服务。将service name作为service的DNS,就可以访问到这个service了
创建另一个服务:
[root@swarm-m ~]# docker service create --name webapp-test --replicas 1 --network my-overlay-network --publish 9089:80 linuxserver/nginx
a7557hfsyh60t2km2g839irvy
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
[root@swarm-m ~]# docker service ps webapp-test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
kdhw9ykrmxo3 webapp-test.1 linuxserver/nginx:latest swarm-m.nahong.com.cn Running Running 26 seconds ago
查看现有的服务 docker service ls
[root@swarm-m ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
n9bg26g83dd9 webapp-nginx replicated 3/3 linuxserver/nginx:latest *:8089->80/tcp
a7557hfsyh60 webapp-test replicated 1/1 linuxserver/nginx:latest *:9089->80/tcp
在webapp-test容器ping 服务名webapp-nginx
[root@swarm-m ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
30ef88e05ed4 linuxserver/nginx:latest "/init" 3 minutes ago Up 3 minutes 80/tcp, 443/tcp webapp-test.1.kdhw9ykrmxo36i7ldu4a43uaz
d412b3ce543e linuxserver/nginx:latest "/init" About an hour ago Up About an hour 80/tcp, 443/tcp webapp-nginx.2.k26fewhj9lzqpva03zv6mgtpm
[root@swarm-m ~]# docker exec 30ef88e05ed4 ifconfig | grep -A 1 eth1
eth1 Link encap:Ethernet HWaddr 02:42:0A:0A:0A:0A
inet addr:10.10.10.10 Bcast:10.10.10.255 Mask:255.255.255.0
[root@swarm-m ~]# docker exec 30ef88e05ed4 ping webapp-nginx
PING webapp-nginx (10.10.10.5): 56 data bytes
64 bytes from 10.10.10.5: seq=0 ttl=64 time=0.259 ms
64 bytes from 10.10.10.5: seq=1 ttl=64 time=0.149 ms
64 bytes from 10.10.10.5: seq=2 ttl=64 time=0.153 ms
64 bytes from 10.10.10.5: seq=3 ttl=64 time=0.137 ms
64 bytes from 10.10.10.5: seq=4 ttl=64 time=0.135 ms
可以看到它们使用了同一个自定义网络 10.10.10.10,但是webapp-nginx解析的IP和之前的不一样,这应该是swarm内部负载均衡的机制
负载均衡
负载均衡分为两种:Swarm集群内的service之间的相互访问需要做负载均衡,称为内部负载均衡(Internal LB);从Swarm集群外部访问服务的公开端口,也需要做负载均衡,称外部部负载均衡(Exteral LB or Ingress LB)
Internal LB
内部负载均衡就是集群内部通过DNS访问service时,Swarm默认通过VIP(virtual IP)、iptables、IPVS转发到某个容器
图片来源网络
Exteral LB(Ingress LB)
外部负载均衡和Ingress网络有关。Swarm网络要提供对外访问的服务就需要打开公开端口,并映射到宿主机。Ingress LB就是外部通过公开端口访问集群时做的负载均衡。
上图是三个节点的Swarm集群,app服务公开了8000端口,并且有两个副;虽然服务只有两个副本,分别在A、B两台主机上,但是访问C主机的8000端口,ingress网络会通过IPVS将请求转到A、B之一的容器中处理,依然可以对外提供服务这就是 routing mesh 的作用。
reference
docker swarm mode的服务发现和LB详解