Docker--Docker Swarm集群 Docker Swarm 是docker原生集群管理系统它将一个Docker主机池变成了一个虚拟主机只需要使用简单的API就可以实现与Docker集群的通信。从Docker 1.12.0开始Docker Swarm就内置于Docker引擎中了不需要单独安装配置。节点架构swarm node从物理上讲一个swarm 就是若干个安装了Docker的物理机或虚拟机这些主机上的Docker 都采用Swarm 模式运行。从逻辑上讲一个Swarm 由若干个节点node组成每个node会落实在一个物理Docker主机上但是一个物理Docker主机不一定就是一个node也可能一个主机上有多个node节点即swarm node与Docker主机不是一对一关系。swarm node 有两种类型manager和worker。ManagerManager节点用于维护swarm集群状态、调试service、处理swarm集群管理任务。为了防止单点故障一个swarm集群一般包含多个manager这些Manager通过Raft算法为维护着一致性。WorkerWorker节点用于在其Container 中运行task任务即对外提供service服务。默认manager 同时也充当worker角色可以运行task任务。角色转换manager 和Worker 的角色不是一成不变的他们之间可以相互转换。manager--》worker 称为节点降级worker--》manager 称为节点升级服务架构service搭建docker swarm的目的是为了在swarm集群中运行应用提供更强抗压能力的服务。service服务是一个逻辑概念表示对外提供的服务。task一个service是通过task的形式出现在swarm 的各个节点中每个节点的task是通过容器对外提供服务。编排器在swarm manager中有一个编排器用来管理task的创建与停止。比如searm manager 中定义一个有3个task的service时编排器会先创建3个task每个task有一个taskID通过分配器为每个task分配一个虚拟IP。再讲task注册到内置的DNS中。当某个task不可用时编排器会在DNS中注销该task。分发器swarm manager中有一个分发器用于对task的监听、调度等操作。在前面的例子中当编排器创建3个task后会调用分发器为每个task分配节点分发器会现在swarm集群的所有节点中找到3个 available node每个node分配一个task。每个task像是一个“插槽”分发器会在每个“插槽”中放入一个容器一个容器就是一个task实例。一旦容器运行分发器就能监测其运行状态即task的运行状态。如果容器不可用或被终止task也会被终止。此时编排器会立即在DNS中注销该task然后编排器再生成一个新的task并在DNS中注册然后分发器分配一个新的available node 然后在此节点上运行容器。分发器除了为task分配节点外还实现对访问请求的负载均衡。当请求到来时会被manager处理根据内置的DNS实现访问的负载均衡。服务部署模式常见的service部署模式有两种replicated模式与global模式replicated模式副本模式service的默认部署模式需要指定task数量。当task数量不等于swarm 的节点数量时需要使用replicated模式。manager 中的分发器会找到task个数的available node为每个节点分配一个或若干个task。global模式全局模式分发器为每个节点都分配一个task。不能指定task数量。swarm集群每增加一个节点编排器就会创建一个task通过分发器分配到新的节点上。swarm集群搭建现在搭建一个swarm集群包括5个swarm节点。准备5个主机主机名分别是docker1、docker2、docker3、docker4、docker5查看swarm激活状态通过docker info命令查看swarm的激活状态。上图表示swarm未激活。swarm初始化在“docker1”主机上运行docker swarm init 命令。创建并初始化一个swarm添加worker节点复制上面执行命令的结果中添加worker节点命令在docker4和docker5中运行将这两个节点添加未docker节点添加manager节点执行docker swarm join-token manager命令复制上面的响应结果在docker2和docker3中运行将这两个节点添加为manager节点查看swarm节点在manager 节点docker1、docker2、docker3 上执行docker node ls 查看当前节点数据但是在worker节点不能运行docker node ls 命令swarm集群维护退出swarm集群worker 退群直接运行docker swarm leave 即可worker 重新加入先在manager运行docker swarm join-token worker然后复制生成的命令在新worker节点上运行就添加到swarm集群了。查看节点情况发现原来的docker5是down新的docker5节点是Ready删除down节点在manager节点上运行docker node rmmanager 退群对于manager节点原则上不推荐直接退群这样会导致swarm集群的一致性受到损坏。可在docker swarm leave 命令后添加-f 或--force选项进行强制退群。swarm自动锁定swarm集群自动锁定原理在manager集群中swarm童话该国Raft日志方式维护manager集群中数据的一致性。即每个节点通过manager间通信方式维护自己的Raft日志。但在通信过程中有一种风险攻击者通过Raft日志数据的传递来访问、篡改manager节点中的数据。为了防止被攻击swarm开启了一种集群自动锁定功能为通信启用TLS加密。加密解密的公钥与私钥全部维护在各个节点的Docker内存中。一旦节点的Docker 重启则密钥丢失。swarm通过autolock 标志来设置集群的自动锁定功能true表示开启false表示关闭。设置自动锁定在manager节点通过docker swarm update -autolocktrue开启此时查看manager的docker info可以看到autolock设为true。查看解锁密钥在manager中运行docker swarm unlock-key查看关闭一个manager直接关闭docker3 的docker引擎模拟宕机情况systemctl stop docker加入manager 启用docker3 的docker引擎systemctl start docker此时查看节点docker info可以看到Swarm值为locked若要加入必须先解锁。在docker3中执行docker swarm unlock命令解锁输入密钥就完成解锁了。swarm节点维护角色转换worker升级为manager通过docker node promote命令可以将worker升级为manager。下面的命令是将docker4和docker5升级为managermanager降级为worker通过docker node demote命令将manager降级为workerdocker node update 变更角色通过docker node update --role [manager|worker] [node]也可以变更角色# 将docker2和docker3变为manager docker node update --role manager docker2 docker node update --role manager docker3 # 将docker4和docker5变为worker docker node update --role worker docker4 docker node update --role worker docker5节点标签swarm可以为节点添加描述性标签以便于更加了解节点。添加/修改节点标签通过docker node update --label-add命令为指定node添加keyvalue的标签。如果key已经存在则修改value。如果要添加或修改多个标签需要多个--label-add 选项指定。docker node update --label-add authzs --label-add emailzs163.com docker2通过docker node inspect查看该节点的标签删除节点标签通过docker node update --label-rm为指定的node删除指定key标签。若要删除多个标签通过多个--label-rm指定要删除的key标签。docker node update --label-rm auth --label-rm email docker2节点删除manage节点通过docker node rm 命令可以删除一个Down 状态的、指定的worker节点。注意该命令只能删除worker节点不能删除manager节点有问题的删除无法直接删除Ready状态的worker节点无法删除manager节点。正确的删除首先关闭节点的Docker是节点变为Down状态然后再删除。强制删除添加 -f选项实现强制删除注意对于manager节点强制删除也不能删除docker node rm -f使一个节点强制退群而docker swarm leave是使当前docker主机关闭swarm模式。swarm安全PKIDocker内置了PKIpublic key infrastructure,公钥基础设置保障系统安全TLS安全保障Swarm 节点之间采用TLS来鉴权授权和加密通信。当运行docker swarm init命令时Docker 指定当前节点为一个manager节点。manager节点生成一个新的swarm CA根证书及一对密钥。同时还会生成2个token一个用于添加worker节点一个用于添加manager节点。每个token都包含CA根证书的digest个一个随机密钥。当有节点加入Swarm时复制manager中对应的docker swarm join 加入命令。并在该节点中运行。这个过程是通过随机密钥这种对称验证方式保障通信安全的。一旦节点加入Swarm 集群他们之间的通信都是通过TLS加密方式进行的。先通过CA证书对通信对方的身份进行验证在验证通过后再进行数据通信。通信数据是通过随机密钥加密过的。CA数字证书轮换轮换周期Swarm的CA数字证书有可能被攻击所以需要轮换默认90天轮换一次。指定证书轮换的数字证书来自哪里呢通过docker swarm ca命令可以指定外部ca数字证书或生成新的CA数字证书。轮换过程当manager运行docker swarm ca --rotate会按顺序执行以下内容Docker生成一个交叉签名cross-signed根证书即新根证书由旧的根证书生成的这份交叉签名根证书是一个过渡性的根帧数。是为了确保节点仍信任旧的根帧数也信任新的根证书。Docker 通知所有节点立即更新根证书这回花费几分钟时间。所有节点更新了根证书后manager 会通知所有节点仅信任新的根证书不再信任旧的根证书和交叉签名根证书。所有节点使用新的根证书签发自己的数字证书。如果使用外部的CA根证书那就不存在交叉签名根证书生成直接通知所有节点更新新证书后续过程旧与前面相同了。manager集群容灾热备容灾Swarm的manager集群采用热备方式提升容灾能力。即再manager集群中只有一个处于leader状态其余manager处于热备状态当manager宕机其余manager会自动发起leader选举重新选举一个新的manager leader。选举算法采用Raft算法。其简单思路是所有manager都有选举与被选举权最后获得过半选票的manager 当选新的leader。service创建注意service只能依附于docker swarm集群所以service创建前提是swarm集群搭建完毕创建service在manager中运行 docker service create 命令比如创建一个tomcat镜像服务名为toms包含3个task端口9000docker service create --name toms --replicas 3 -p 9000:8080 tomcat:8.5.49# 查看服务列表 docker service ls # 用来查看正在运行的service。一个swarm可运行多个swarm。 # 查看指定服务详情 docker service inspect [service name|service ID]此时用户就可以通过swarm集群中的任意主机来访问服务了比如docker39000或docker29000# 查看task节点查看指定服务的各个task所分配的节点信息 docker service ps [service name|service ID] # 查看节点task docker node ps [node] # 查看节点docker5的task docker node ps docker5 # 查看service日志 docker service logs [service name|service ID] # 查看task日志 docker service logs [taskID] # taskID 可通过查看task详情获取 docker node ps [service name|service ID]负载均衡当一个service 包含多个task时用户访问service 会通过负载均衡的方式转发给各个task处理。负载均衡策略为轮询策略且无法通过修改service的属性方式进行变更。但可以通过第三方实现负载均衡策略的变更例如Nginx、HAProxy。service操作task伸缩当需要在不停止服务的前提下对服务的task进行扩容/缩容有两种实现方式docker service update 方式# 变更task数量 docker service update --replicas 4 tomsdocker service scale 方式# 变更服务数量 docker service scale toms7暂停节点的task分配生产环境下由于某主机性能低下扩容时不想为此主机分配更多的task可以pause 该主机节点。# 不为docker2 增加task数量 docker node update --availability pause docker2 # 然后就可以扩容了 docker service scale toms10清空task当不想让manager节点接收task或者某个节点出现问题需要停止服务进行维修此时就需要将该节点上的task清空以不影响service的整体性能。# 清空docker2 节点上的task此时就将docker2节点上task分配到其他节点了。 docker node update --availability drain docker2task容错当task所在主机或容器发生故障manager编排器会自动创建新的task然后分配到可用节点上。service 删除docker service rm [service name|service ID]删除后service消失对应的task也全部删除。task相关的节点容器也全部消失。滚动更新当一个service的task较多时为了不影响对外提供服务对service进行更新时可采用滚动更新。比如将镜像tomcat:8.5.49 的service 的镜像滚动更新为tomcat8.5.39创建servicedocker service create --name toms --replicas 10 --update-parallelism 2 --update-delay 3s --update-max-failure-ratio 0.2 --update-failure-action rollback --rollback-parallelism 2 --rollback-delay 3s \ --rollback-max-failure-ratio 0.2 --rollback-failure-action continue -p 9000:8080 tomcat:8.5.49更新service将镜像tomcat:8.5.49 的service 的镜像滚动更新为tomcat8.5.39docker service update --image tomcat:8.5.39 toms更新回滚当更新失败会回滚到更新前的状态用户也可通过命令方式手动回滚。docker service update --rollback tomsservice全局部署模式常见的service部署模式有两种replicated模式和global模式。前面创建的service 是replicated模式。下来创建global模式的service。创建service通过--mode 指定部署模式,默认采用replicated模式。docker service create --name toms --mode global -p 9000:8080 tomcat:8.5.49该模式会在每个节点上分配一个tasktask伸缩对于global模式来说要改变task数量必须先改变该service所依附的swarm集群的节点数量。节点增加task自动增加节点减少task自动减少。比如在manager节点新增一个节点那么这个节点会自动增加一个task。overlay网络overlay网络称为重叠网络或覆盖网络是一种构建于underlay网络之上的逻辑虚拟网络。在物理网络的基础上通过节点间单播隧道机制将主机两两相连而形成的虚拟、独立的网络。Docker Swarm集群中的overlay网络 主要通过iptables、ipvs、vxlan等技术实现。overlay网络模型overlay网络模型 在创建时会创建出两个网络docker_gwbidge网络和ingress网络。同时还创建出docker_gwbidge网关与br0网关和ingress-sb