重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
Swarm 介绍
Swarm 是 Docker 公司在 2014 年 12 月初发布的一套较为简单的工具,用来管理Docker 集群,它将一群 Docker 宿主机变成一个单一的虚拟的主机。 Swarm 使用标准的Docker API 接口作为其前端访问入口,换言之,各种形式的 Docker Client(dockerclient in Go, docker_py, docker 等)均可以直接与 Swarm 通信。 Swarm 几乎全部用 Go语言来完成开发,Swarm0.2 版本增加了一个新的策略来调度集群中的容器,使得在可用的节点上传播它们,以及支持更多的 Docker 命令以及集群驱动。 Swarm deamon 只是一个调度器(Scheduler)加路由器(router),Swarm 自己不运行容器,它只是接受docker 客户端发送过来的请求,调度适合的节点来运行容器,这意味着,即使 Swarm 由于某些原因挂掉了,集群中的节点也会照常运行,当 Swarm 重新恢复运行之后,它会收集重建集群信息。
Docker 的 Swarm(集群)模式,集成很多工具和特性,比如:跨主机上快速部署服务,服务的快速扩展,集群的管理整合到 docker 引擎,这意味着可以不可以不使用第三方管理工具。
分散设计,声明式的服务模型,可扩展,状态协调处理,多主机网络,分布式的服务发现,负载均衡,滚动更新,安全(通信的加密)等等。成都创新互联-专业网站定制、快速模板网站建设、高性价比多伦网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式多伦网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖多伦地区。费用合理售后完善,10年实体公司更值得信赖。
集群特性:
1)群集管理集成进 Docker Engine:使用内置的群集管理功能,可以直接通过 Docker CLI 命令来创建 Swarm 群集, 然后去部署应用服务, 而不再需要其它外部的软件来创建和管理一个 Swarm 群集。2)去中心化设计:Swarm 群集中包含 Manager 和 Worker 两类 Node,可以直接基于 Docker Engine 来部署任何类型的 Node。 而且在 Swarm 群集运行期间, 既可以对其作出任何改变,实现对群集的扩容和缩容等, 如添加 Manager Node, 如删除 Worker Node, 而做这些操作不需要暂停或重启当前的 Swarm 群集服务。
3) 声明式服务模型: 在实现的应用栈中, Docker Engine 使用了一种声明的方式, 可以定义所期望的各种服务的状态, 例如, 创建了一个应用服务栈: 一个 Web 前端服务、一个后端数据库服务、 Web 前端服务又依赖于一个消息队列服务。
4) 协调预期状态与实际状态的一致性: Swarm 群集 Manager Node 会不断地监控群集的状态, 协调群集状态使得我们预期状态和实际状态保持一致。 例如启动了一个应用服务, 指定服务副本为 10, 则会启动 10 个 Docker 容器去运行。 如果某个 Worker
Node 上面运行的 2 个 Docker 容器挂掉了, 则 Swarm Manager 会选择群集中其它可用的 Worker Node, 并创建 2 个服务副本, 使实际运行的 Docker 容器数仍然保持与预期的 10 个一致。5) 多主机网络: Swarm Manager 会给群集中每一个服务分配一个唯一的 DNS 名称,对运行中的 Docker 容器进行负载均衡。 可以通过 Swarm 内置的 DNS Server, 查询Swarm 群集中运行的 Docker 容器状态。
6) 负载均衡: 在 Swarm 内部, 可以指定如何在各个 Node 之间分发服务容器( ServiceContainer) , 实现负载均衡。 如果想要使用 Swarm 群集外部的负载均衡器, 可以将服务容器的端口暴露到外部。
7) 安全策略: 在 Swarm 群集内部的 Node, 强制使用基于 TLS 的双向认证, 并且在单个 Node 上以及在群集中的 Node 之间,都进行安全的加密通信。 可以选择使用自签名的根证书,或者使用自定义的根 CA( Root CA) 证书。
8) 滚动更新: 对于服务需要更新的场景, 我们可以在多个 Node 上进行增量部署更新,Swarm Manager 支持通过使用 Docker CLI 设置一个 delay 时间间隔, 实现多个服务在多个 Node 上依次进行部署, 这样可以非常灵活地控制。 如果有一个服务更新失败, 则
暂停后面的更新操作, 重新回滚到更新之前的版本。Swarm 架构
Swarm 作为一个管理 Docker 集群的工具,首先需要将其部署起来,可以单独将Swarm 部署于一个节点。需要一个 Docker 集群,集群上每一个节点均安装有 Docker。
具体的 Swarm 架构图可以参照下图:
Swarm 架构中最主要的处理部分自然是 Swarm 节点,Swarm 管理的对象自然是Docker Cluster,Docker Cluster 由多个 Docker Node 组成,而负责给 Swarm 发送请求的是 Docker Client。swarm 关键概念
1)Swarm
集群的管理和编排是使用嵌入到 docker 引擎的 SwarmKit,可以在 docker 初始化时
启动 swarm 模式或者加入已存在的 swarm2)Node
一个节点(node)是已加入到 swarm 的 Docker 引擎的实例,当部署应用到集群,你将会提交服务定义到管理节点,接着 Manager 管理节点调度任务到 worker 节点,manager 节点还执行维护集群的状态的编排和群集管理功能,worker 节点接收并执行来自manager 节点的任务。通常,manager 节点也可以是 worker 节点,worker 节点会报告当前状态给 manager 节点3)服务(Service)
服务是要在 worker 节点上要执行任务的定义,它在 worker 节点上执行,当你创建服务的时,你需要指定容器镜像4)任务(Task)
任务是在 docekr 容器中执行的命令,Manager 节点根据指定数量的任务副本分配任务给 worker 节点主要管理命令集:
docker swarm:集群管理,子命令有 init, join, leave, update。(docker swarm --help 查看帮助)
docker service:服务创建,子命令有 create, inspect, update, remove, tasks。
(docker service--help 查看帮助)
docker node:节点管理,子命令有 accept, promote, demote, inspect, update,tasks, ls, rm。(docker node --help 查看帮助)
1)manager node 管理节点:执行集群的管理功能,维护集群的状态,选举一个
leader 节点去执行调度任务。
2)worker node 工作节点:接收和执行任务。参与容器集群负载调度,仅用于承载task。
3)service 服务:一个服务是工作节点上执行任务的定义。创建一个服务,指定了容器所使用的镜像和容器运行的命令。 service 是运行在 worker nodes 上的 task 的描述,service 的描述包括使用哪个 docker 镜像,以及在使用该镜像的容器中执行什么命令。
4)task 任务:一个任务包含了一个容器及其运行的命令。 task 是 service 的执行实体,task 启动 docker 容器并在容器中执行任务。swarm 工作方式
1、 Node
从 Docker Engine 1.12 版本起开始引进 swarm 模式来创建一个或多个 Docker Engines的集群,称为 swarm。一个 swarm 包含一个或多个节点:运行在 Docker Engine1.12 或更高版本的 swarm 模式下的物理的或虚拟的机器。有两种类型的节点:managers 和
workers。
Manager 节点
manager 节点处理集群管理任务:
- 维护集群状态
- 调度服务
- 提高 swarm 模式的 HTTP API 服务
swarm 管理器使用 Raft 来实现维护整个 swarm 集群一致的内部状态。如果是测试的目的可以只运行一个 swarm 管理节点。如果单管理器的 swarm 出问题下线了,服务仍然会运行,不过你需要创建一个新的集群来恢复它。
要利用 swarm 模式的容错功能,Docker 建议根据你对高可用的要求来创建奇数的管理节点。当你有多个管理节点时,可以不用停机从故障的管理节点中恢复。- 三个管理节点的 swarm 最大允许一个管理节点宕机
- 五个管理节点的 swarm 最大允许两个管理节点宕机
- N 个管理节点的 swarm 最大允许(N-1)/2 个管理节点宕机
- Docker 推荐最多创建 7 个管理节点
Worker 节点
Worker 节点是 Docker Engine 的实例,其唯一目的是运行容器。 Worker 节点不参与Raft 分布状态,作调度的决定或提供 swam 模式的 HTTP API 服务。
你可以创建单个管理节点的 swarm,不过你不能只有一个 Worker 节点而没有管理节点。
默认情况下,所有的管理节点也是 Worker 节点。在单管理节点的集群中,你可以运行命令 docker service create,然后调度器会把所有的任务放到本地执行。如果你想阻止调度器把任务分配到多个节点的集群的管理节点上,你可以设置管理节点的状态为 Drain。调度器就不会继续把任务分发这些节点上执行。改变角色
你可以通过执行 docker node promote 来把一个 worker 节点提升为管理节点。例如,你当你的管理节点下线时你可能会想把 worker 节点提升为管理节点。2、 Service(服务, 任务, 容器)
当你部署服务到 swarm,swarm 管理器接收你对服务期望状态的定义。然后它为你服务在 swarm 中的节点调度一个或多个副本任务。这些任务在 swarm 的节点上彼此独立地运行。
例如假设你想负载均衡三个 HTTP 服务器实例。下面的图表展示了三个 HTTP 服务器副本。
三个 HTTP 实例中的每一个是 swarm 中的一个任务。
一个容器是孤立的进程。在 swarm 模式模型中,每个任务调用一个容器。任务包含着容器。一旦容器运行正常,调度器就会把相此容器相关联的任务识别为在线状态。否则容器停止或有异常,则任务显示为终止。3、任务和调度
任务是 swarm 内调度的原子单位。当你通过创建或更新服务声明一个期望状态的服务,调度器通过调度任务来实现期望的状态。例如,你指定一个服务始终保持运行三个HTTP 实例。调度器就创建三个任务。每个任务运行一个容器。容器是任务的实例化。如果一个 HTTP 容器之后出现故障停止,此任务被标志为失败,调度器就会创建一个新的任务来生成一个新容器。
任务是一个单向机制。它单向地执行一系统状态,assigned,prepared, running 等。如果一个任务失败了,调度器就会删除这个任务和它的容器,然后创建一个新的任务来替换它。
下面的图表显示 swarm 模式是如何接收服务创建请求和调度任务到 worker 节点的。4、副本和全局服务
有两种类型的服务部署,副本和全局。
对于副本服务,你可以指定运行相同任务的数量。例如,你决定部署三个 HTTP 实例的副本,每个提供相同的内容。
一个全局服务是在每个节点上运行一个相同的任务。不需要预先指定任务的数量。每次你增加一个节点到 swarm 中,协调器就会创建一个任务,然后调度器把任务分配给新节点。
比如你希望在每个节点上运行监控代理,病毒扫描器等。
下面的图表显示以×××标注的三个副本的服务和灰色标注的一个全局服务。5、 swarm 调度策略Swarm 在 scheduler 节点(leader 节点)运行容器的时候,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有:spread, binpack, random.
1)Random
顾名思义,就是随机选择一个 Node 来运行容器,一般用作调试用,spread 和 binpack策略会根据各个节点的可用的 CPU, RAM 以及正在运行的容器的数量来计算应该运行容器
的节点。2)Spread
在同等条件下,Spread 策略会选择运行容器最少的那台节点来运行新的容器,binpack策略会选择运行容器最集中的那台机器来运行新的节点。使用 Spread 策略会使得容器会均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了只会损失少部分的容器。3)Binpack
Binpack 策略最大化的避免容器碎片化,就是说 binpack 策略尽可能的把还未使用的节点留给需要更大空间的容器运行,尽可能的把容器运行在一个节点上面。部署案例
- 本案例实验环境
本案例实验环境如表所示。 Docker Swarm 系统环境
主机 操作系统 主机名/IP 地址 主要软件及版本
服务器 Centos 7.5-x86_64 manager/192.168.5.210 Docker-ce 18.06.0-ce
服务器 Centos 7.5-x86_64 worker01/192.168.5.211 Docker-ce 18.06.0-ce
服务器 Centos 7.5-x86_64 worker02/192.168.5.212 Docker-ce 18.06.0-ce2、案例需求
部署 Docker Swarm 集群
- 案例实现思路
1) 准备 Docker Swarm 部署环境。
2) 部署 Docker Swarm 集群。4、案例实施
Docker Swarm 系统环境准备
- 修改主机名
[root@localhost ~]# hostnamectl set-hostname manager //192.168.5.210
[root@localhost ~]# hostnamectl set-hostname worker01 //192.168.5.211
[root@localhost ~]# hostnamectl set-hostname worker02 //192.168.5.2122、修改/etc/hosts 文件,以便做名称解析,每台主机都要修改
[root@manager ~]# cat /etc/hosts128.127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.5.210 manager
192.168.5.211 worker01
192.168.5.212 worker023、修改主机 DNS 地址,保证能够上网
[root@manager ~]# ping -c 1 www.baidu.com
PING www.a.shifen.com (119.75.216.20) 56(84) bytes of data.
64 bytes from 127.0.0.1 (119.75.216.20): icmp_seq=1 ttl=128 time=5.04 ms
--- www.a.shifen.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 5.045/5.045/5.045/0.000 ms4、安装 docker 以及必要的软件包,每台设备都要安装
[root@manager ~]# yum -y install wget telnet lsof vim
[root@manager ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
添加国内 docker 镜像源[root@manager ~]# yum-config-manager --add-repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装 docker 最新版本并启动
[root@manager ~]# yum -y install docker-ce
[root@manager ~]# systemctl enable docker
[root@manager ~]# systemctl start docker配置镜像加速器
sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors":
["https://ariq8b1p.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload
sudo systemctl restart docker查看 docker 版本
[root@manager ~]# docker -v
Docker version 18.06.0-ce, build 0ffa8255、 firewalld 放行端口
每台机器都需要执行, 群集节点之间保证 Tcp 2377(群集管理端口)、 Tcp/Udp 7946
(容
器网络发现端口) 和 Tcp/Udp 4789(overlay 网络通信端口)。
[root@manager ~]# firewall-cmd --zone=public --add-port=2377/tcp --permanent
[root@manager ~]# firewall-cmd --zone=public --add-port=7946/tcp --permanent
[root@manager ~]# firewall-cmd --zone=public --add-port=7946/udp --permanent
[root@manager ~]# firewall-cmd --zone=public --add-port=4789/tcp --permanent
[root@manager ~]# firewall-cmd --zone=public --add-port=4789/udp --permanent
[root@manager ~]# firewall-cmd --reload
重启 firewalld 之后, 还需要重启 docker 服务。
[root@manager ~]# systemctl restart docker6、关闭 Selinux,每台设备都要关闭
[root@manager ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g'
/etc/selinux/config
[root@manager ~]# setenforce 0
[root@manager ~]# getenforce
PermissiveDocker Swarm 群集部署
1、创建 Swarm 群集部署命令, 格式如下所示:
docker swarm init --advertise-addr
在 manager Node 上, 创建一个 Swarm 群集, 执行如下命令:[root@manager ~]# docker swarm init --advertise-addr 192.168.5.210
Swarm initialized: current node (nncjnvm4e6nj6bi6nc1k7zzvq) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-
1gkifydlpoagmek46pce1nktkk6qa68hlhfecd6sqllg4dtb4l-
4vy5k533lt6joatjs83myy3aa 192.168.5.210:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and
follow the instructions.
--advertise-addr 参数配置管理节点发布它的 IP 地址 192.168.5.210。其它的节点必
须能通过此 IP 来连接管理节点。上面命令的输出包含了加入新节点到 swarm 的命令。节
点将作为 manager 或 worker 加入,具体取决于--token 标志的值。
可以运行以下命令获取来获取 manager 加入 swarm 集群的命令
[root@manager ~]# docker swarm join-token manager运行以下命令获取 worker 加入 swarm 集群的命令
[root@manager ~]# docker swarm join-token worker
可以运行 docker info 查看 swarm 集群信息,下图为部分信息
[root@manager ~]# docker info
执行 docker node ls 命令来查看节点的相关信息:
[root@manager ~]# docker node ls
- 添加 worker 节点到 Swarm 群集
在 worker01、 worker02 两个 Worker Node 上,执行命令将 Worker Node 加入到
Swarm 群集中, 命令如下所示:[root@worker01 ~]# docker swarm join --token SWMTKN-1-
1gkifydlpoagmek46pce1nktkk6qa68hlhfecd6sqllg4dtb4l-
4vy5k533lt6joatjs83myy3aa 192.168.5.210:2377
This node joined a swarm as a worker.[root@worker02 ~]# docker swarm join --token SWMTKN-1-
1gkifydlpoagmek46pce1nktkk6qa68hlhfecd6sqllg4dtb4l-
4vy5k533lt6joatjs83myy3aa 192.168.5.210:2377
This node joined a swarm as a worker.回到 manager 主机再查看:
[root@manager ~]# docker info[root@manager ~]# docker node ls
上面信息中, AVAILABILITY 表示 Swarm Scheduler 是否可以向群集中的某个 Node 指
派 Task, 对应有如下三种状态:
- Active: 群集中该 Node 可以被指派 Task。
- Pause: 群集中该 Node 不可以被指派新的 Task, 但是其他已经存在的 Task 保持 运行。
- Drain: 群集中该 Node 不可以被指派新的 Task, Swarm Scheduler 停掉已经存在的 Task,并将它们调度到可用的 Node上。
查看某一个 Node 的状态信息, 只可以在该 Manager Node 上执行如下命令:
[root@manager ~]# docker node inspect worker01 --pretty[root@manager ~]# docker node inspect self --pretty
Docker Swarm 群集管理
Docker Swarm 节点
运行 Docker 主机时可以自动初始化一个 Swarm 群集, 或者加入一个已存在的 Swarm群集, 这样运行 Docker 主机将成为 Swarm 群集中的节点(node)。
Swarm 群集中节点可分为管理(manager)节点和工作(worker)节点。
管理节点用于 Swarm 群集的管理, Docker Swarm 命令基本只能在管理节点执行, 而工作节点退出群集命令 docker swarm leave 可以在工作节点上执行。 Manager node 负责执行
编排和集群管理工作, 保持并维护 Swarm 处于期望的状态。 Swarm 中, 如果有多个manager node, 它们会自动协商并选举出一个 leader 执行编排任务。 工作节点是任务执行节点,管理节点将服务(service)下发至工作节点执行。 管理节点默认也作为工作节点。 也可以通过配置让服务只运行在管理节点。- 服务和任务
任务(Task) 是 Swarm 中的最小的调度单位, 一个单一的容器。
服务(Services) 是指一组任务的集合, 服务定义了任务的属性。 服务有两种模式:
1) replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
2) global services 每个工作节点上运行一个任务。
两种模式都可以通过 docker service create 的--mode 参数指定。实现 Docker Swarm 日常操作管理, 包括:
1) 节点管理
2) 服务管理
3) 网络管理
4) 数据卷管理1、 Docker Swarm 节点管理
1.1 Node 状态变更管理
Node 的 AVAILABILITY 有三种状态: Active、 Pause、 Drain。 对某个 Node 进行变更, 可以将其 AVAILABILITY 值通过 Docker CLI 修改为对应的状态。 下面是常见的变更操作:
1) 设置 Manager Node 只具有管理功能。
2) 对服务进行停机维护, 可以修改 AVAILABILITY 为 Drain 状态。
3) 暂停一个 Node, 然后该 Node 就不再接收新的 Task。
4) 恢复一个不可用或者暂停的 Node。
例如, 将 Manager Node 的 AVAILABILITY 值修改为 Drain 状态, 使其只具备管理功能,
执行如下命令:
[root@manager ~]# docker node update --availability drain manager
这样, Manager Node 不能被指派 Task, 也就是不能部署实际的 Docker 容器来运行服务,而只是作为管理 Node 的角色。1.2. 给 Node 添加标签元数据
每个 Node 的主机配置情况可能不同, 比如: 有的适合运行 CPU 密集型应用, 有的适合运行 IO 密集型应用。 Swarm 支持给每个 Node 添加标签元数据, 这样可以根据 Node的标签,选择性地调度某个服务部署到期望的一组 Node 上。给 Swarm 群集中的某个 Worker Node 添加标签, 执行如下命令格式如下:
docker node update --label-add 值 键
例如, worker01 主机在名称为 GM-IDC-01 这个数据中心, 执行如下命令添加标签:[root@manager ~]# docker node update --label-add GM-IDC-01 worker01
worker01
查看 worker01 主机的标签是否添加成功:
[root@manager ~]# docker node inspect worker01
[ {
"ID": "b0i0h2eueujo3q08b984946l2",
"Version": {
"Index": 23
},
"CreatedAt": "2018-07-23T07:36:53.668770211Z",
"UpdatedAt": "2018-07-24T02:15:44.939047Z",
"Spec": {
"Labels": {
"GM-IDC-01": ""
......//省略部分1.3. Node 提权/降权
改变 Node 的角色,Worker Node 可以变为 Manager Node, 即: 由工作 Node变成了管理Node,对应提权操作。 例如: 将 worker1 和 worker2 都升级为 Manager Node, 执行如下命令:[root@manager ~]# docker node promote worker01 worker02
Node worker01 promoted to a manager in the swarm.
Node worker02 promoted to a manager in the swarm.对上面已提权的 worker1 和 worker2 执行降权, 需要执行如下命令:
[root@manager ~]# docker node demote worker01 worker02
Manager worker01 demoted in the swarm.
Manager worker02 demoted in the swarm.1.4. 退出 Swarm 群集
如果 Manager 想要退出 Swarm 群集, 在 Manager Node 上执行如下命令:
[root@manager ~]# docker swarm leave
如果群集中还存在其它的 Worker Node, 还希望 Manager 退出群集, 则加上一个强制
选
项, 命令行如下所示:
[root@manager ~]# docker swarm leave --force
同理, 如果 Worker 想要退出 Swarm 群集, 在 Worker Node 上, 执行如下命令:
[root@worker01 ~]# docker swarm leave
即使 Manager 已经退出 Swarm 群集, 执行上述命令也可以使得 Worker Node 退出群集。
之后, 根据需要, 还可以加入到其它新建的 Swarm 群集中。2 Docker Swarm 服务管理
在 Swarm mode 下使用 Docker, 可以实现部署运行服务(create)、 服务扩容缩
容(scale)、 删除服务、 滚动更新等功能。2.1. 创建服务
创建 Docker 服务, 可以使用 docker service create 命令实现。例如,要创建如下两个
服务,执行如下命令:
[root@manager ~]# docker service create --replicas 2 --name hello busybox ping
baidu.com
6ndc18vhmtrqet2pogkjevugt
overall progress: 2 out of 2 tasks
1/2: running [=================================>
2/2: running [=================================>
verify: Service converged[root@manager ~]# docker service logs -f hello
hello.1.k25qwbkbb0c5@worker01 | 64 bytes from 123.125.115.110: seq=212
ttl=53 time=1.277
ms
hello.2.6r381vq3jeyv@worker02 | 64 bytes from 123.125.115.110: seq=212 ttl=53
time=1.295ms
……
从 Docker 镜像 busybox 创建了一个名称为 hello 的服务, 其中指定服务副本数为 2,
也就是启动一个 Docker 容器来运行该服务, 通过 logs 可以查看 ping 的结果。 查看当
前已
经部署启动的全部应用服务, 执行如下命令:[root@manager ~]# docker service ls
执行结果, 如下所示:也可以查询指定服务的详细信息, 执行如下命令:
[root@manager ~]# docker service ps hello
查看结果信息, 如下所示:
上面信息中, 在 worker01 和 worker02 这两个 Node 上部署了 hello 这个应用服务,
也
包含了它们对应的当前状态信息。 此时, 也可以通过执行 docker ps 命令, 在
Manager Node
上查看当前启动的 Docker 容器:[root@worker01 ~]# docker ps -a
显示服务详细信息
易于阅读显示执行如下命令:[root@manager ~]# docker service inspect --pretty hello
以 json 的格式显示,如下所示:[root@manager ~]# docker service inspect hello
2.2、服务的扩容缩容
Docker Swarm 支持服务的扩容缩容, Swarm 通过--mode 选项设置服务类型, 提供了
两
种模式:
一种是 replicated, 可以指定服务 Task 的个数(也就是需要创建几个冗余副本),
这
也是 Swarm 默认使用的服务类型。
另一种是 global, 会在 Swarm 群集的每个 Node 上都创建一个服务。
【语法】
docker service scale 服务 ID=服务 Task 总数
例如, 将前面已经部署的 2 个副本的 hello 服务, 扩容到 3 个副本, 执行如下命令:
[root@manager ~]# docker service scale hello=3
hello scaled to 3
overall progress: 3 out of 3 tasks1/3: running
[==================================================>]
2/3: running
[==================================================>]
3/3: running
[==================================================>]
verify: Service converged
进一步通过 docker service ps hello 查看一下 myredis 的各个副本的状态信息, 如下所示:而缩容服务只需要将副本数小于当前应用服务拥有的副本数即可实现, 大于指定缩容副本数的副本会被删除。
2.3. 删除服务
删除服务, 只需要在 Manager Node 上执行如下命令:【语法】
docker service rm 服务名称
如删除 hello 应用服务,执行 docker service rm hello,则应用服务 hello 的全部副本都
会被删除。[root@manager ~]# docker service rm hello
2.4. 滚动更新
在 Manager Node 上执行如下命令,先创建一个 Redis 3.0.6 版本
[root@manager ~]# docker service create \> --replicas 3 \--name redis \
--update-delay 10s \
redis:3.0.6
lbnu84tngtncjodaq9x6d3gdn
overall progress: 3 out of 3 tasks
1/3: running
[==================================================>]
2/3: running
[==================================================>]
3/3: running
[==================================================>]
verify: Service converged
在服务部署时配置了滚动更新策略。
- --update-delay 参数配置更新服务任务之间的延迟时间或一组任务之间的延迟时间。你可以以秒 s,分 m,时 h 单位来配置延迟时间。所以 10m30s 表示 10 分钟 30 秒的延迟。
- 默认情况下,调度程序一次执行一个更新任务。你可以传递–update-parallelism 参数来配置调度程序同时执行的最大更新服务任务数。
- 默认情况下,当单个更新任务返回 RUNNING 的状态时,调度器调度继续其它任务直到所有任务更新完成。如果在更新任务期间的任何时候一个任务返回 FAILED,调度器暂停更新。你可以在 docker service create 或 docker service update 时使用–update-failure-action 来控制其行为。
查看服务 redis 的详细信息:
[root@manager ~]# docker service inspect redis --pretty现在开始更新 redis 容器。 swarm 管理器根据 UpdateConfig 策略来对节点应用更新:
[root@manager ~]# docker service update --image redis:3.0.7 redis
redis
overall progress: 3 out of 3 tasks
1/3: running
[==================================================>]
2/3: running
[==================================================>]
3/3: running
[==================================================>]
verify: Service converged
默认情况下调度器应用滚动更新的步骤如下:
- 停止第一个任务。
- 对已停止的任务执行更新。
- 启动已经完成更新的容器。
- 如果更新任务返回 RUNNING,等待一个指定的延迟然后停止下一个任务。
- 如果在任何时候任务返回 FAIlED,停止更新。
查看更新后的 Redis 服务详细信息
查看服务,发现以前的版本也在,只是处于停止状态
[root@manager ~]# docker service ps redis
如果更新暂停,执行 docker service update 命令来重启已暂停的更新,例如:
docker service update redis2.5 回滚版本
[root@manager ~]# docker service update --rollback redis3. 添加自定义 Overlay 网络
Docker Engine 的 swarm 模式原生支持覆盖网络(overlay networks),所以你可以启用容器到容器的网络。 swarm 模式的覆盖网络包括以下功能:
你可以附加多个服务到同一个网络默认情况下,service discovery 为每个 swarm 服务分配一个虚拟 IP 地址(vip)和DNS 名称,使得在同一个网络中容器之间可以使用服务名称为互相连接。
你可以配置使用 DNS 轮循而不使用 VIP为了可以使用 swarm 的覆盖网络,在启用 swarm 模式之间你需要在 swarm 节点之间开放以下端口:TCP/UDP 端口 7946 – 用于容器网络发现
UDP 端口 4789 – 用于容器覆盖网络在 Manager Node 上创建一个 Overlay 网络, 执行如下命令:
[root@manager ~]# docker network create \
--driver overlay \
--subnet 10.0.9.0/24 \
--opt encrypted \
my-networkdlu21qvmv1zoi2bnl60wptkro默认情况下 swarm 中的节点通信是加密的。在不同节点的容器之间,可选的–opt encrypted 参数能在它们的 vxlan 流量启用附加的加密层。
–subnet 参数指定覆盖网络的子网。当你不指定一个子网时,swarm 管理器自动选择一个子网并分配给网络。在一些旧的内核,包括 kernel 3.10,自动分配的地址可能会与其它子网重叠。这样的重叠可能引起连接问题。
执行 docker network ls 来查看网络:swarm scope 表示部署到 swarm 的服务可以使用这个网络。当你创建一个服务并附加到一个网络后,swarm 仅仅扩展该网络到服务运行的节点上。在一个没有运行有附加到网络的服务 worker 节点上,network ls 命令不会显示有任何网络。
要附加一个服务到一个覆盖网络,在创建服务的时候传递–network 参数。例如创建一个nginx 服务并附加到一个名为 my-network 的网络:
[root@manager ~]# docker service create \--replicas 3 \
--name my-web \
--network my-network \
nginx
xnjwd3sg67tddbee1r29mnezv
overall progress: 3 out of 3 tasks
1/3: running[==================================================>]
2/3: running
[==================================================>]
3/3: running
[==================================================>]
verify: Service converged
查看服务所在的节点信息[root@manager ~]# docker service ps my-web
查看网络具体信息
[root@manager ~]# docker network inspect my-network默认情况下,当你创建一个服务并附加到一个网络时,swarm 就给服务分配一个 VIP。
VIP 根据服务名称映射到 DNS 别名。在该网络的容器之间通过 gossip 来共享 DNS 映射信息,所以在该网络的容器能通过服务名称来访问彼此。
查看 VIP:
[root@manager ~]# docker service inspect \--format='{{json .Endpoint.VirtualIPs}}' \
my-web[{"NetworkID":"dlu21qvmv1zoi2bnl60wptkro","Addr":"10.0.9.5/24"}]
如果外部要访问这个服务,可以发布端口:
默认情况下,以上发布的端口都是 TCP 端口。你可以指定发布一个 UDP 端口
如:docker service create --name dns-cache -p 53:53/udp dns-cache下面发布 my-web 的 TCP8080 端口[root@manager ~]# docker service update --publish-add 8080:80 my-web
my-web
overall progress: 3 out of 3 tasks
1/3: running
[==================================================>]
2/3: running
[==================================================>]
3/3: running
[==================================================>]
verify: Service converged
查看发布的端口:[root@manager ~]# docker service inspect --format='{{json .Endpoint.Ports}}'
my-web
[{"Protocol":"tcp","TargetPort":80,"PublishedPort":8090,"PublishMode":"ingress"}]
当你访问任意节点的 8080 端口,swarm 的负载均衡会把你的请求路由到一个任意节点的可用的容器上。 routing mesh 在 swarm 节点的所有 IP 上监听 published 端口
可以配置一个外部负载均衡来路由请求到 swarm 服务。例如,你可以配置 HAProxy 来路由请求到一个 published 端口为 8080 的 nginx 服务。4. 创建数据卷
[root@manager ~]# docker volume create web-test
web-test
[root@manager ~]# docker volume ls
DRIVER VOLUME NAME
local3c79787a32ee0c28d71022c854489ff95584c36c0ff745d861617e2a67f2314d
local
8cec61172886947826aef4168807dba054a3fdeacf606c0e76e8cae4dd434250
local
d7b8a0e8c250ea61be4051b2f25fef2d5ffebbee89f0424b7f168fa27d8f2189
local web-test
应用上述创建的数据卷, 如下所示:
[root@manager ~]# docker service create --mount type=volume,src=webtest,dst=/usr/local/apache2/htdocs --replicas 2 --name web08 httpdvnzbh778lma8qcbpc5kb3zu0o
overall progress: 2 out of 2 tasks
1/2: running
[==================================================>]
2/2: running
[==================================================>]
verify: Service converged
查看数据卷的详细信息:[root@manager ~]# docker volume inspect web-test
[
{
"CreatedAt": "2018-08-19T16:01:32+08:00",
"Driver": "local","Labels": {},
"Mountpoint": "/var/lib/docker/volumes/web-test/_data",
"Name": "web-test",
"Options": {},
"Scope": "local"
}
]
查看服务所在的节点:[root@manager ~]# docker service ps web08
ID NAME IMAGE NODE DESIRED STATE
CURRENT STATE ERROR PORTS
mvevlguiv506 web08.1 httpd:latest worker02 Running
Running about a minute ago
c1o5qbvndynv web08.2 httpd:latest worker01 Running
Running about a minute ago登陆到 worker01 主机
root@worker01 ~]# cd /var/lib/docker/volumes/web-test/_data/
[root@worker01 _data]# mkdir test01 test02
[root@worker01 _data]# docker exec -it eeda631495e3 bash
root@eeda631495e3:/usr/share/nginx/html# ls /usr/share/nginx/html/
50x.html index.html test01 test02从上面的验证结果看, 在本地数据卷的目录下创建几个文件, 在进入到容器后, 找到队应的目录, 数据依然存在。
采用 bind mount 挂载类型的数据卷, 在 worker02 主机上创建本地挂载目录。[root@worker02 ~]# mkdir /opt/webroot/
创建 web09 的两个服务:
[root@manager _data]# docker service create --mount
type=bind,source=/opt/webroot,target=/usr/local/apache2/htdocs --replicas 2 --
name web09 httpd
ec20py2hqee1k2bldxav58be7
overall progress: 2 out of 2 tasks
1/2: running
[==================================================>]
2/2: running
[==================================================>]
verify: Service converged
其中,参数 target 表示容器里面的路径,source 表示本地硬盘路径
[root@worker02 ~]# cat /opt/webroot/index.htmlwebroot
[root@worker02 ~]#
进入容器进行验证(注意此容器必须在 worker012 主机上), 验证结果正常如下。
root@c76b532f4127:/usr/local/apache2# cat htdocs/index.htmlwebroot
root@c76b532f4127:/usr/local/apache2#