docker知识8---docker swarm

一、docker swarm介绍

集群使用容器面临的问题主要为:
  如何管理多个node上的多个容器?
  如何方便低横向扩展容器?
  如果容器down了,如何自动恢复?
  如何去更新容器而不影响业务?
  如何监控追踪容器?
  如何调度容器的创建?
  如何保护隐私数据?
docker swarm,是Docker官方提供的一款集群管理工具,其主要作用是把若干台 Docker 主机抽象为一个整体,并且通过一个入口统一管理这些 Docker 主机上的各种 Docker 资源。
swarm集群初始化
  不包含在任何 Swarm 中的 Docker 节点,称为运行于单引擎(Single-Engine)模式。一旦被加入 Swarm 集群,则切换为 Swarm 模式。
docker swarm集群安装方法:

  1)vagrant+virtualbox:使用vagrantfile定义虚拟机,需要10min+时间部署;
  2)docker machine+virtualbox:分钟级部署;
  3)play with docker http://labs.play-with-docker.com/:秒级部署swarm集群,最多保存4h;


 

二、docker swarm入门手册

###本次采用VMware虚拟机直接创建swarm集群;
###在manager1节点执行;
docker swarm init \
   --advertise-addr 192.168.66.10:2377 \
   --listen-addr 192.168.66.10:2377  #初始化一个新的 Swarm,并将自身设置为第一个管理节点。同时也会使该节点开启 Swarm 模式。--advertise-addr 指定其他节点用来连接到当前管理节点的 IP 和端口。这一属性是可选的,当节点上有多个 IP 时,可以用于指定使用哪个IP。此外,还可以用于指定一个节点上没有的 IP,比如一个负载均衡的 IP。--listen-addr 指定用于承载 Swarm 流量的 IP 和端口。其设置通常与 --advertise-addr 相匹配,但是当节点上有多个 IP 的时候,可用于指定具体某个 IP。并且,如果 --advertise-addr 设置了一个远程 IP 地址(如负载均衡的IP地址),该属性也是需要设置的。建议执行命令时总是使用这两个属性来指定具体 IP 和端口。Swarm 模式下的操作默认运行于 2337 端口。虽然它是可配置的,但 2377/tcp 是用于客户端与 Swarm 进行安全(HTTPS)通信的约定俗成的端口配置。

docker node ls #查看docker节点;
docker swarm join-token manager #添加manager节点进swarm集群;
docker swarm join-token worker  #查看“添加worker节点进swarm集群”的命令;
###在manager2节点执行;
docker swarm join --token SWMTKN-1-0d0h5xmlok2iowbnc1h8e9fa0geccu48wxhmr0dfnu2flvqi07-9lefauyigjuw2gt8n3g4hycrv 192.168.66.10:2377
###在worker1节点执行;
docker swarm join --token SWMTKN-1-0d0h5xmlok2iowbnc1h8e9fa0geccu48wxhmr0dfnu2flvqi07-1h61zl9f6bpb93d9iz2bsrhxj 192.168.66.10:2377
docker node ls #查看docker节点;

 

###service创建及扩容
docker service ls                   #查看service明细;
docker service create --name swarm_test1 busybox sh -c "while true;do sleep 3600;done"  #swarm集群不再通过docker run启动服务;
docker service inspect swarm_test1  #查看service详细信息;
docker service scale swarm_test1=4  #设置service副本为4;
docker service ps swarm_test1       #查看service副本调度信息;
docker rm -f 8b56e958b7a2 && docker service ps swarm_test1 && docker ps #删除一个容器后,查看swarm会自动创建一个容器副本;
docker service rm swarm_test1       #删除service;

 

 案例2:DNS服务发现

docker pull jwilder/whoami
docker network create -d overlay demo
docker service create --name whoami -p 1000:8000 --network swarm_test1 -d jwilder/whoami  #swarm必须使用overlay网络才可创建服务;
docker service ps whoami  #确认client调度至object1节点;
docker service create --name client --network swarm_test1 -d busybox sh -c "while true;do sleep 3600;done" 
docker service ps client #确认client调度至controller节点;
docker exec -it client.1.ovjcidh62dvxbupp236c97jyn nslookup whoami  #查看service name绑定的VIP;
docker exec -it client.1.ovjcidh62dvxbupp236c97jyn ping whoami -c 3 #在controller节点执行ping,解析IP为10.0.1.5,该IP为VIP;
docker exec -it whoami.1.hayk0otka6t2r55nsrzgs9933 ip a #在object1节点执行,查询容器IP为10.0.1.6;
docker service scale whoami=3  #设置service副本为3; 
docker exec -it 493244154edf nslookup tasks.whoami #解析service name调度到各容器的具体IP;

 docker routing mesh:一种docker网络技术,用于支撑docker集群间容器服务的通信。有2中体现形式:

  internal routing mesh---不通node的容器通过overlay网络访问其他node服务的VIP,然后通过负载均衡将访问落到某个node中的容器;
  ingress routing mesh---如果服务绑定接口,则此服务可以通过任意swarm节点的相应接口访问。

ingress network包传输过程:
  1)外部访问swarm集群的负载均衡;
  2)swarm集群服务的端口被暴露到各个swarm节点;
  3)集群内部通过IPVS进行负载均衡调度访问任务;

 

 

 如下图所示,client容器访问whoami容器流程---client发送请求包,swarm集群的DNS服务解析被访问容器的域名VIP,然后有iptables+LVS|IPVS转发包到目的node的容器。

  curl 127.0.0.1:1000 #在所有swarm节点(manager|worker节点)都可访问服务暴露的端口;

 

iptables -nvL -t nat  #查看swarm集群节点iptables转发nat规则:任何访问swarm集群几点1000端口的数据都会转发至172.21.0.2:1000,这就造成“swarm集群服务的端口被暴露到各个swarm节点;”现象。

iptables -nvL -t nat  #查看swarm集群节点iptables转发nat规则:任何访问swarm集群几点1000端口的数据都会转发至172.21.0.2:1000,这就造成“swarm集群服务的
端口被暴露到各个swarm节点;”现象。
ip a        #宿主机查看IP,确认172.21.0.2所在网络与docker_gwbridge网卡的网络一致;
brctl show  #列出宿主机所有网桥;
docker network inspect docker_gwbridge #查看网络详细信息,其中ingress-sbox容器的IP为:172.21.0.2;
ls /var/run/docker/netns  #查看容器运行期间的network namespace,找到ingress_sbox的网络名称空间;
nsenter --net=/var/run/docker/netns/ingress_sbox #进入ingress_sbox的网络名称空间;
ip a && exit   #查看名称空间中的IP;

 

 

yum -y install ipvsadm  #安装ipvsadm;
nsenter --net=/var/run/docker/netns/ingress_sbox
ipvsadm -l  #查看负载均衡调度规则:里面为调度节点的容器IP;表示访问swarm节点的8000端口时,iptables会转发包至ingress_sbox,然后通过ipvs转发包至具体的某个容器。

 

三、docker swarm故障排查

问题1:swarm节点无法假如集群?

[root@k8s-master02 ~]# docker swarm join --token SWMTKN-1-28u942qj5l0h67v0gofn410g0zcuelk5d23epd66h12min98dm-1aku87enhdh278w27u9kj40sx 192.168.66.10:2377
Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one.

[root@k8s-master02 ~]# docker swarm leave
Error response from daemon: You are attempting to leave the swarm on a node that is participating as a manager. Removing this node leaves 1 managers out of 3. Without a Raft quorum your swarm will be inaccessible. The only way to restore a swarm that has lost consensus is to reinitialize it with `--force-new-cluster`. Use `--force` to suppress this message.

原因分析:未删除节点出某个swarm集群;

解决方法:强制删除节点出swarm集群,并重新假如新群;

[root@k8s-master02 ~]# docker swarm leave -f
Node left the swarm.

[root@k8s-master02 ~]# docker swarm join --token SWMTKN-1-28u942qj5l0h67v0gofn410g0zcuelk5d23epd66h12min98dm-1aku87enhdh278w27u9kj40sx 192.168.66.10:2377
This node joined a swarm as a manager.

 

 问题2:服务创建失败,提示没有网络?

[root@controller ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
6d9335948452 bin_my-bridge bridge local
e80f0665add1 bridge bridge local
ada3e422721a compose-flask-redis_default bridge local
4e532531e901 compose-lb-scale_default bridge local
3ce035d8549b demo bridge local
4c5814b179e2 docker_gwbridge bridge local
c04897e2966d host host local
6p96ig0ldtld ingress overlay swarm
746689e8990f none null local
qy2uef7soa7w swarm_test1 overlay swarm
[root@controller ~]# docker service create --name whoami -p 1000:8000 --network demo -d jwilder/whoami
Error: No such network: demo
原因分析:swarm集群使用的overlay网络不存在;

解决方法:使用overlay网络创建service;
[root@controller ~]# docker service create --name whoami -p 1000:8000 --network swarm_test1 -d jwilder/whoami
l18jnwic9d01g87u9ksrn51fk

 

问题3:节点加入swarm集群失败?

[root@manager02 ~]# docker swarm join --token SWMTKN-1-4wgfok640zgto34q23ed44983nri58vbi9viv7d8oass6vn30v-8vx1em106t7bt59hohd1h3lya 192.168.66.10:2377
Error response from daemon: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial tcp 192.168.66.10:2377: connect: no route to host"

原因分析:节点防火墙等未关闭。

解决方法:关闭防火墙等。

systemctl disable --now firewalld && systemctl status firewalld

setenforce 0 && getenforce;sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

 问题4:所有节点时间已同步,但节点加入swarm集群失败?

[root@worker01 ~]# docker swarm join --token SWMTKN-1-4wgfok640zgto34q23ed44983nri58vbi9viv7d8oass6vn30v-20mvqgqw2q1xqroby35i8649j 192.168.66.10:2377
Error response from daemon: error while validating Root CA Certificate: x509: certificate has expired or is not yet valid

 

 

原因分析:初始化第一个swarm manager节点时会生成带有时间的CA证书;而后期同步时间了并不会修改CA证书中的时间。

解决方法:重新初始化swarm manager节点,然后再将其他节点加入集群。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

posted on 2021-08-05 12:25  chalon  阅读(802)  评论(0编辑  收藏  举报