本文依照书籍(Docker企业应用实战教程) 编写

Docker Swarm

1. Basic Knowledge

1. Docker swarm 号称三剑客中之一,Docker Swarm 是一个为 IT 运维团队提供集群和调度能力的编排具。用户可以把集群中所有 Docker Engine 整合进一个「虚拟 Engine」的资源池,在灵活的调度策略下,IT 团队可以更好地管理可用的主机资源,保证应用容器的高效运行。

2. Docker 1.12 Swarm mode 已经内嵌入 Docker 引擎,成为了 docker 子命令 docker swarm。请注意与旧的 Docker Swarm 区分开来,

3.Swarm mode 内置 kv 存储功能,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务fa发现、负载均衡、路由网格、动态伸缩、滚动更新、安全传输等。使得 Docker 原生的 Swarm 集群具备Mesos、Kubernetes竞争的实力。


2. Why Choose Swarm

Swarm 优势:虚拟化,vmware

1.高性能: 经过测试,Swarm 可拓展性的极限是在 1000 个节点上运行 50000 个部署容器,每个容器的启动时间为亚秒级,同时性能无减损;

2.灵活的容器调度 :Swarm 帮助 IT 运维团队在有限条件下将性能表现和资源利用最优化。Swarm 的内置调器(scheduler)支持多种过滤器,包括:节点标签,亲和性和多种容器部策略如 binpack、spread、random 等等。权重值:cpu 利用率、内存、存储空间;

3.服务的可持续性 :Docker Swarm 由 Swarm Manager 提供高可用性,通过创建多个 Swarm master 节点制定主 master 节点宕机时的备选策略。如果一个 master 节点宕机,那么一个 slave 节点就会被升格为 master 节点,直到原来的 master 节点恢复正常;

4.和DockerAPI 及整合支持的兼容性 :Swarm 对 DockerAPI 完全支持,这意味着它能为使用不同 Docker 工具(如 Docker CLI,Compose,Trusted Registry,Hub 和UCP)的用户提供无缝衔接的使用体验;

综上所述,Docker Swarm 提供了一套高可用 Docker 集群管理的解决方案,完全支持标准的 DockerAPI,方便管理调度集群 Docker 容器,合理充分利用集群主机资源。


3. Swarm Framework

3.1 Framwork

图1

Manager: 接收客户端服务定义,将任务发送到 worker 节点;维护集群期望状态和集群管理功能及 Leader 选举。默认情况下 manager 节点也会运行任务,也可以配置只做管理任务。

Worker: 接收并执行从管理节点分配的任务,并报告任务当前状态,以便管理节点维护每个服务期望状态。

3.2 Swarm Characteristic

  1. Docker Swarm 采取集群管理,统一部署
  2. 弹性伸缩:可以通过策略的方式随意增加、删减容器数量
  3. 多主机网络:Swarm内置多主机网络,实现多主机中的容器间互通。(overlay 网络)
  4. 服务发现:可以通过 Swarm 内置的 DNS 服务器查询集群中每个运行的容器。
  5. 负载均衡:实现服务副本负载均衡,提供入口访问。也可以将服务入口暴露给外部负载

均衡器再次负载均衡。Docker swarm

  1. 滚动更新:升级时,逐步将应用服务更新到节点,如果出现问题,可以将任务回滚到先

前版本

  1. 安全传输:Swarm 中的每个节点使用验证方式加入集群,确保安全的其他节点通信

3.3 Two Points

  1. **任务(Task) ** :任务是 Swarm 中最小的调度单位,目前来说就是单一的容器。
  2. 服务(Services) :服务是指一组任务的集合,服务定义了任务的属性,服务有两种模式
    1. replicated services (复制): 按照一定规则在各个工作节点上运行指定个数的任务
    2. global services: 每个工作节点上运行一个任务

两种模式通过 docker service create 的 --mode 参数指定。下图展示了容器、任务、服务的关系。

图2


4. Swarm Combat

4.1 Prerequisite

  • Swarm 集群由管理节点和工作节点组成
  • 集群节点之间保证 TCP 2377、TCP/UDP 7946 和 UDP 4789 端口通信
    • 2377 (TCP) – 集群管理
    • 7496 (TCP 与 UDP) – 节点通信
    • 4789 (TCP 与 UDP) – 覆盖网络流量(overlay)

4.2 Combat

4.2.1 swarm init
##1. 管理节点初始化
	docker swarm init  --advertise-addr string (format:<ip|interface[:port])

##2. 工作节点加入swarm
	docker swarm join —token 令牌环

## 3.查看docker swarm 节点
	docker node  ls

4.2.2 join-token
##1. 查看swarm worker 的连接令牌
- docker swarm join-token worker

## 2. 查看swarm manager 的连接令牌
- docker swarm join-token manager

## 3.使旧令牌无效并生成新令牌
- docker swarm  join-token --rotate

4.2.3 deploy services && common commands
    1. 命令
    • docker service --help
    • docker service create --help
    1. 创建服服
    • docker service create—replicas 2 --name test1 wordpress:latest
    • replicas 参数是指运行实例个数
    1. 查看容器
    • docker service ps test1
    1. 删除服务
    • docker service rm test1
    1. 查看服务详细信息

      docker service inspect —pretty test1

    1. 容器的弹性扩大与缩减
    • docker service scale test1=3
    • docker service scale test1=1
    1. 查看日志
    • docker service logs test1
    1. 查看服务任务
    • docker service ps --filter desired-state=[accepted | running | shutdown] test1
  • 滚动更新服务

    • docker service update --image nginx:1.14 test1

    • docker service ps test1

    • docker service ps --filter desired-state=shutdown test1

4.3 Update Strategy

--update-delay duration Delay between updates (ns|us|ms|s|m|h) 更新之间的延迟(ns / us / ms / s / m / h)(默认为0)
--update-failure-action string Action on update failure ("pause"|"continue"|"rollback") 更新失败的动作(暂停/继续),默认暂停
--update-max-failure-ratio float Failure rate to tolerate during an update 更新期间容忍的故障率
--update-monitor duration Duration after each task update to monitor for failure (ns|us|ms|s|m|h) 每次更新任务后的持续时间以监控故障(ns / us / ms / s / m / h)(默认为0)
--update-order string Update order ("start-first"|"stop-first") 默认 stop-first
--update-parallelism uint Maximum number of tasks updated simultaneously (0 to update all at once) 同时更新的最大任务数(0表示一次更新所有任务),默认是一个
4.3.1 启动服务时设定更新策略
docker service  create  --name my_web1 --replicas 10 --update-delay 10s --update-parallelism 2 --update-failure-action continue  nginx:1.12
4.3.2 启动服务时设定回滚策略
docker service create --name my_web2 --replicas 10 --rollback-parallelism 2 --rollback-monitor 20s --rollback-max-failure-ratio 2 nginx:1.12
4.3.3 服务更新
docker service  update  --image  nginx:1.13 my_web1
4.3.4 服务回滚
docker service  rollback my_web1
4.3.5 指定节点更新

指定service的某个节点排满状态此后,将不会再在 worker1 上面分派任务

  • $ docker node update --availability drain(耗尽、排满) worker1【节点名称】

  • $ docker node update --availability active(启用,恢复) worker1【节点名称】

4.36 指定服务约束(—constraint)

可以通过定义约束表达式来限制可用于任务调度的节点。多个约束查找节点时,需要满足每个表达式(AND匹配)。约束 可以匹配节点或docker engine的lables,如下:

节点属性 匹配 示例
node.id 节点 ID node.id == 2ivku8v2gvtg4
node.hostname 节点 hostname node.hostname != node02
node.role 节点 角色: manager node.role == manager
node.labels 用户自定义节点labels node.labels.security == high
engine.labels Docker Engine labels engine.labels.operatingsystem == ubuntu 14.04
engine.lables 匹配docker engine 的lables,如操作系统,驱动等。集群管理员通过使用docker node update命令来添加node.labels以更好使用节点。

​ 指定容器限定在哪个节点

    docker service create --constraint 'node.hostname==docker' --name website website:7.7 

5. NetWork

5.1 Basic Knowledge

5.1.1 作用(Effect)
    1. 不同主机间的容器互连
    1. 容器间网络隔离
5.1.2 产生两种不同流量原因
    1. 控制和管理计划流量:这包括群集管理消息,例如请求加入或离开群集。这个流量总是加密的。
  • 2.应用程序数据流量:这包括来自外部客户端的集装箱运输和流量。 让不同主机之上的运行的容器彼此实现对接,惟一的方式就是使用覆盖网络。大家可将其视为一套构建于另一网络(在本示例中为物理主机网络)之上的容器网络。Docker Swarm 模式提供一套默认覆盖网络,其负责配合 libnetwork 与 libkv 实现一套基于VxLAN 的解决方案。当然,大家也可以选择 Flannel、Calico 或者 Weave 等其它覆盖网络驱动方案,但需要执行额外的安装步骤。 在 Docker Engine Swarm 模式当中,**大家可以单纯立足管理节点创建一套覆盖网络,*,而且其不需要 etcd、consul 或者 Zookeeper 等额外的键值存储机制。

5.2 Network Concept

    1. Overlay networks: 管理参与集群的Docker守护进程之间的通信。你可以创建 overlay networks,就像用户定义的独立容器网络一样。您可以将服务附加到一个或多个现有的覆盖网络,启用service - to - service沟通。Overlay networks 是使用Overlay networks驱动程序的Docker网络
    1. ingress(进入、入口) network:是一种特殊的覆盖网络,它有助于在服务节点之间实现负载平衡。当任何群集节点接收已发布端口上的请求时。它将请求发送给一个名为IPVS的模块。IPVS跟踪参与该服务的所有IP地址,选择其中一个,并将请求路由到它,over the ingress network。当您初始化或加入一个集群时,ingress网络会自动创建。大多数用户不需要定制它的配置,但是Docker 17.05和更高版本允许您这样做。
    1. docker_gwbridge:是一个bridge network连接Overlay networks (includingthe ingress network)对于单个Docker守护进程的物理网络,默下,一个服务正在运行的每个容器都连接到它的本地Docker守护进程主机的docker_gwbridge网络。docker_gwbridge网络是在初始化或加入集群时自动创建的。大多数用户不需要定制它的配置,但是Docker允许您这样做配置。

5.3 Network Deploy Combat

5.3.1 overlay network setup
- 1. docker network  create  --driver  overlay  --scope swarm  --subnet 172.17.0.0/24  --ip-range 172.17.0.0/24 --gateway 172.17.0.1 my_net

- 2. docker network  inspect  my_net 
5.3.2 use overlay network
-1. 使用my_net网络创建服务
	- docker service  create  --name my_net --network my_net --replicas 5 --update-delay 10s --update-failure-action rollback --update-parallelism 2  --rollback-parallelism .2 --rollback-monitor 20s --rollback-max-failure-ratio 2 wordpress:latest

-2. 查看VIP
	- docker service  inspect  my_net

-3. 查看每个容器的IP,然后测试ping

-4. 将网络更新到已存在的服务中
	- docker service  create  --name my_test --replicas 2 wordpress:latest
	- docker service  update --network-add  my_net my_test 
	- docker service  inspect my_test

5.4 Load Balancing

5.4.1 概述(summary)
  • Swarm 模式内置 DNS 组件,可以自动为集群中的每个服务分配 DNS 记录。Swarmmanager 使用内部负载均衡,根据服务的 DNS 名称在集群内的服务之间分发请求。

  • Swarm manager 使用 ingress load blancing 暴露你想从外部访问集群提供的服务。Swarm manager 自动为服务分配一个范围 30000-32767 端口的 Published Port,也可以为该服务指定一个 Published Port。

  • ingress network 是一个特殊的 overlay 网络,便于服务的节点直接负载均衡。当任何swarm 节点在已发布的端口上接收到请求时,它将该请求转发给调用的 IPVS 模块,IPVS跟踪参与该服务的所有容器 IP 地址,选择其中一个,并通过 ingress network 将请求路由给它。

    5.4.2 swarm 网络负载方式

      **1. vip 同 dnsrr 两个的区别在于 VIP 在进行 IP 轮询方式的时候,也可以进行端口查找,dnsrr 只能进行 ip 轮询。**
    
      **2. DNS负载均衡与vip负载不一样,它主要依赖的用户自定义的overlay网络,例如本实验中的mysql如何确定是创建支持dns或者是vip方式的负载均衡服务,主要是由参数--endpoint-mode决定,例如:**
    
## dns方式是不允许有-p这个参数的,同时vip是默认模式,所以创建VIP类型,也可以不加--endpoint-mode参数。
- 1.dns
	- docker service  create --name nginx --network my_net --replicas 3 --endpoint-mode=dnsrr  nginx:1.12

- 2.vip
	- docker service  create  --name lnmp --network my_net  --replicas 4 -p 80:80  --endpoint-mode vip richarvey/nginx-php-fpm
- 3.获取VIP
	- docker service inspect -f '{{json .Endpoint.VirtualIPs}}' [服务名称]
	- docker service inspect -f '{{json .Endpoint.VirtualIPs}}' lnmp

6. Docker Swarm 数据持久化

6.1 Summary

swarm集群中我们可以创建本地卷或者全局卷来挂载到容器用来保存数据

  1. 全局卷可以被挂载在swarm集群的任意节点, 所以不管你的服务容器启动在哪个节点, 都可以访问到数据. 不过docker目前还没有默认的全局卷驱动支持, 你可以安装一些插件驱动来实现全局卷例如Flocker, Portworx等.
  2. 本地卷就只存在与某个节点本地的一个挂载卷
  3. 使用 NFS 共享存储作为数据卷

6.2 Volume 类型

6.2.1 创建数据卷

Docker volume create my-volumes

####6.2.2 将本地目录挂载至服务中

- 1. 读写挂载
	- docker service create --name my-volume –mount type=volume,src=my-volumes,dst=/root/my-volume --network my-net --replicas 2 wordpress:latest
- 2. 只读挂载
	- docker service create --name my-volume –mount type=volume,src=my-volumes,dst=/root/my-volume,readonly --network my-net --replicas 2 wordpress:latest   (只读权限)
6.2.3 查看数据卷详细信息

docker volume inspect <VOLUME-NAME>


6.3 Bind 类型

-1. 读写挂载 local node
	- docker service create --mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH> --name myservice <IMAGE>
- 2.只读挂载
	- docker service create --mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH>,readonly --name myservice <IMAGE>
- 3.案例
	- docker service create --name bind --mount type=bind,src=/root/db_data,dst=/root/db_data,readonly --network mynet --replicas 2 wordpress:latest

6.4 为原有的服务添加 volume 卷

docker service update my-volume --mount-add type=volume,source=data,target=/var/lib/data

7. Docker swarm 管理节点高可用

7.1 Framwork

图3

为了利用 swarm 模式的容错功能,应保持集群中奇数管理员来支持manager 节点故障。当 leader 故障时,会选举新的 leader.

7.2 方案(programme)

- 1. manager 节点数必须是奇数
- 2. 三台服务器,分别是one.firstleap.cn;two.firstleap.cn;three.firstleap.cn
- 3.假设已经把one.firstleap.cn设置为 Leader, 那么执行以下两行命令即可
	- 1. docker node promote two.firstleap.cn
	- 2. docker node promote three.firstleap.cn
- 4. 节点降级,将three移出管理节点
	- docker node demote three.firstleap.cn

8. 配置文件存储

  1. 生成一个Nginx的配置文件
site.conf
server {
listen 80;
server_name localhost; location / {
root /usr/share/nginx/html; index index.html index.htm; }
}
  1. 将 site.conf 保存到 docker 配置 中

    1. docker config create site.conf site.conf
    2. docker config ls
  2. 创建 一个 Nginx 并应用这个配置

  docker service create --name nginx --config site.conf --publish 8080:80 nginx:latest