Docker Swarm 学习
1、 Docker Swarm 是什么?
Docker Swarm 是Docker 公司推出的管理Docker集群的平台。它是将一群Docker宿主机变成一个单一的虚拟主机。
2、Docker Swarm的几个关键概念
Swarm:集群管理工具。
子命令有init,
join
, leave, update。(docker swarm --help查看帮助)
Node:节点。node是加入到swarm集群中的一个docker引擎实体,可以在一台物理机上运行多个node,node分为:manager nodes,也就是管理节点;worker nodes,也就是工作节点。
子命令有accept, promote, demote, inspect, update, tasks,
ls
,
rm
。(docker node --help查看帮助)
Service:应用编排,也可以理解为服务。用于定义任务,创建服务时,需要指定要使用的容器镜像。子命令有create, inspect, update, remove, tasks。(docker service--help查看帮助)
Task:应用实例。
3、Swarm 的调度策略
Swarm在调度(scheduler)节点(leader节点)运行容器的时候,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有:spread, binpack, random.
1)Random
顾名思义,就是随机选择一个Node来运行容器,一般用作调试用,spread和binpack策略会根据各个节点的可用的CPU, RAM以及正在运
行的容器的数量来计算应该运行容器的节点。
2)Spread
在同等条件下,Spread策略会选择运行容器最少的那台节点来运行新的容器,binpack策略会选择运行容器最集中的那台机器来运行新的节点。
使用Spread策略会使得容器会均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了只会损失少部分的容器。
3)Binpack
Binpack策略最大化的避免容器碎片化,就是说binpack策略尽可能的把还未使用的节点留给需要更大空间的容器运行,尽可能的把容器运行在
一个节点上面。
4、Swarm Cluster模式特性
1)批量创建服务
建立容器之前先创建一个overlay的网络,用来保证在不同主机上的容器网络互通的网络模式
2)强大的集群的容错性
当容器副本中的其中某一个或某几个节点宕机后,cluster会根据自己的服务注册发现机制,以及之前设定的值--replicas n,
在集群中剩余的空闲节点上,重新拉起容器副本。整个副本迁移的过程无需人工干预,迁移后原本的集群的load balance依旧好使!
不难看出,docker service其实不仅仅是批量启动服务这么简单,而是在集群中定义了一种状态。Cluster会持续检测服务的健康状态
并维护集群的高可用性。
3)服务节点的可扩展性
Swarm Cluster不光只是提供了优秀的高可用性,同时也提供了节点弹性扩展或缩减的功能。当容器组想动态扩展时,只需通过scale
参数即可复制出新的副本出来。
仔细观察的话,可以发现所有扩展出来的容器副本都run在原先的节点下面,如果有需求想在每台节点上都run一个相同的副本,方法
其实很简单,只需要在命令中将
"--replicas n"
更换成
"--mode=global"
即可!
复制服务(--replicas n)
将一系列复制任务分发至各节点当中,具体取决于您所需要的设置状态,例如“--replicas 3”。
全局服务(--mode=global)
适用于集群内全部可用节点上的服务任务,例如“--mode global”。如果大家在 Swarm 集群中设有 7 台 Docker 节点,则全部节点之上都将存在对应容器。
4. 调度机制
所谓的调度其主要功能是cluster的server端去选择在哪个服务器节点上创建并启动一个容器实例的动作。它是由一个装箱算法和过滤器
组合而成。每次通过过滤器(constraint)启动容器的时候,swarm cluster 都会调用调度机制筛选出匹配约束条件的服务器,并在这上面运行容器。
------------------Swarm cluster的创建过程包含以下三个步骤----------------------
1)发现Docker集群中的各个节点,收集节点状态、角色信息,并监视节点状态的变化
2)初始化内部调度(scheduler)模块
3)创建并启动API监听服务模块
一旦创建好这个cluster,就可以用命令docker service批量对集群内的容器进行操作,非常方便!
在启动容器后,docker 会根据当前每个swarm节点的负载判断,在负载最优的节点运行这个task任务,用
"docker service ls"
和
"docker service ps + taskID"
可以看到任务运行在哪个节点上。容器启动后,有时需要等待一段时间才能完成容器创建。
5、Swarm集群部署
5.1准备工作
机器环境(三台机器,centos系统)
IP:192.168.1.1 主机名:dockerManager 担任角色:swarm manager
IP:192.168.1.2 主机名:dockerNode1 担任角色:swarm node
IP:192.168.1.2 主机名:dockerNode2 担任角色:swarm node
1)修改主机名
# 192.168.31.43 主机上执行
[root@dockerManager ~]# hostnamectl set-hostname dockerManager
# 192.168.31.188 主机上执行
[root@dockerNode1 ~]# hostnamectl set-hostname dockerNode1
# 192.168.31.139 主机上执行
[root@dockerNode2 ~]# hostnamectl set-hostname dockerNode2
2)配置hosts文件(可配置可不配置)
[root@manager43 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.1 dockerManager
192.168.1.2 dockerNode1
192.168.1.3 dockerNode2
# 使用scp复制到node主机
[root@dockerManager ~]# scp /etc/hosts root@192.168.1.2:/etc/hosts
[root@dockerManager ~]# scp /etc/hosts root@192.168.1.3:/etc/hosts
3) 设置防火墙
关闭三台机器上的防火墙。如果开启防火墙,则需要在所有节点的防火墙上依次放行2377/tcp(管理端口)、7946/udp(节点间通信端口)、4789/udp(overlay 网络端口)端口。
[root@dockerManager ~]# systemctl disable firewalld.service
[root@dockerManager ~]# systemctl stop firewalld.service
4) 安装docker并配置加速器(在三台主机都要安装哟...)
[root@dockerManager ~]# yum -y install docker
[root@dockerNode1 ~]# yum -y install docker
[root@dockerNode2 ~]# yum -y install docker
5.2 创建Swarm并添加节点
1) 创建Swarm集群
[root@dockerManager ~]# docker swarm init --advertise-addr 192.168.1.1
Swarm initialized: current node (z2n633mty5py7u9wyl423qnq0) is now a manager.
To add a worker to this swarm, run the following command:
# 这就是添加节点的方式(要保存初始化后token,因为在节点加入时要使用token作为通讯的密钥)
docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.1.1:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
上面命令执行后,该机器自动加入到swarm集群。这个会创建一个集群token,获取全球唯一的 token,作为集群唯一标识。后续将其他节点加入集群都会用到这个token值。
其中,--advertise-addr参数表示其它swarm中的worker节点使用此ip地址与manager联系。命令的输出包含了其它节点如何加入集群的命令。
这里无意中遇到了一个小小的问题:
# 在次执行上面的命令,回报下面的错误
[root@dockerManager ~]# docker swarm init --advertise-addr 192.168.1.1
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@dockerManager ~]# docker swarm leave -f
这里的leave就是在集群中删除节点,-f参数强制删除,执行完在重新执行OK
2) 查看集群的相关信息
[root@dockerManager ~]# docker info
上面的命令执行后 找到Swarm的关键字,就可以看到相关信息了
[root@dockerManager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
3jcmnzjh0e99ipgshk1ykuovd * dockerManager Ready Active Leader 18.06.0-ce
上面的命令是查看集群中的机器(注意上面node ID旁边那个*号表示现在连接到这个节点上)
3) 添加节点主机到Swarm集群
上面我们在创建Swarm集群的时候就已经给出了添加节点的方法
# 192.168.1.2 主机上执行
[root@dockerNode1 ~]# docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.1.1:2377
This node joined a swarm as a worker.
# 192.168.1.3 主机上执行
[root@dockerNode2 ~]# docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.1.1:2377
This node joined a swarm as a worker.
如果想要将其他更多的节点添加到这个swarm集群中,添加方法如上一致
在dockerManager 主机上我们可以看一下集群中的机器及状态
[root@dockerManager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
3jcmnzjh0e99ipgshk1ykuovd * dockerManager Ready Active Leader 18.06.0-ce
vww7ue2xprzg46bjx7afo4h04 dockerNode2 Ready Active 18.06.1-ce
c5klw5ns4adcvumzgiv66xpyj dockerNode1 Ready Active 18.06.1-ce
--------------------------------------------------------------------------------------------------------------------
温馨提示:更改节点的availablity状态
swarm集群中node的availability状态可以为 active或者drain,其中:
active状态下,node可以接受来自manager节点的任务分派;
drain状态下,node节点会结束task,且不再接受来自manager节点的任务分派(也就是下线节点)
[root@dockerManager ~]# docker node update --availability drain dockerNode2 # 将dockerNode2 节点下线。如果要删除dockerNode2 节点,命令是"docker node rm --force dockerNode2 "
dockerNode2
[root@dockerManager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
3jcmnzjh0e99ipgshk1ykuovd * dockerManager Ready Active Leader 18.06.0-ce
vww7ue2xprzg46bjx7afo4h04 dockerNode2 Ready Drain 18.06.1-ce
c5klw5ns4adcvumzgiv66xpyj dockerNode1 Ready Active 18.06.1-ce
如上,当node1的状态改为drain后,那么该节点就不会接受task任务分发,就算之前已经接受的任务也会转移到别的节点上。
再次修改为active状态(及将下线的节点再次上线)
[root@dockerManager ~]# docker node update --availability active dockerNode2
dockerNode2
[root@dockerManager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
3jcmnzjh0e99ipgshk1ykuovd * dockerManager Ready Active Leader 18.06.0-ce
vww7ue2xprzg46bjx7afo4h04 dockerNode2 Ready Active 18.06.1-ce
c5klw5ns4adcvumzgiv66xpyj dockerNode1 Ready Active 18.06.1-ce
5.3 在Swarm中部署服务(nginx为例)
1) 创建网络在部署服务
# 创建网络
[root@dockerManager ~]# docker network create -d overlay nginx_net
a52jy33asc5o0ts0rq823bf0m
[root@dockerManager ~]# docker network ls | grep nginx_net
a52jy33asc5o nginx_net overlay swarm
# 部署服务
[root@dockerManager ~]# docker service create --replicas 1 --network nginx_net --name my_nginx -p 80:80 nginx # 就创建了一个具有一个副本(--replicas 1 )的nginx服务,使用镜像nginx
olexfmtdf94sxyeetkchwhehg
# 使用 docker service ls 查看正在运行服务的列表
[root@dockerManager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
olexfmtdf94s my_nginx replicated 1/1 nginx:latest *:80->80/tcp
2) 查询Swarm中服务的信息
-pretty 使命令输出格式化为可读的格式,不加 --pretty 可以输出更详细的信息:
[root@dockerManager ~]# docker service inspect --pretty my_nginx
# 查询到哪个节点正在运行my_nginx这个服务
[root@dockerManager ~]# docker service ps my_nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
yzonph0zu7km my_nginx.1 nginx:latest dockerManager Running Running about an hour ago
温馨提示:如果上面命令执行后,上面的 STATE 字段中刚开始的服务状态为 Preparing,需要等一会才能变为 Running 状态,其中最费时间的应该是下载镜像的过程
# 查询运行的容器
[root@dockerManager ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0dc7103f8030 nginx:latest "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp my_nginx.1.yzonph0zu7km0211uj0ro5brj
3) 在Swarm中动态扩展服务(scale)
Service提供了复制(类似kubernetes里的副本)功能。可以通过 docker service scale 命令来设置服务中容器的副本数
比如将上面的my_nginx容器动态扩展到4个
[root@dockerManager ~]# docker service scale my_nginx=4
4) 模拟宕机node节点
特别需要清楚的一点:
如果一个节点宕机了(即该节点就会从swarm集群中被踢出),则Docker应该会将在该节点运行的容器,调度到其他节点,以满足指定数量的副本保持运行状态。
比如:
将dockerNode2 宕机后或将dockerNode2 的docker服务关闭,那么它上面的task实例就会转移到别的节点上。当dockerNode2 节点恢复后,它转移出去的task实例不会主动转移回来,
只能等别的节点出现故障后转移task实例到它的上面。使用命令"docker node ls",发现dockerNode2 节点已不在swarm集群中了(状态为:Down)。
5) Swarm 动态缩容服务(scale)
同理,swarm还可以缩容,同样是使用scale命令
如下,将my_nginx容器变为1个
[root@dockerManager ~]# docker service scale my_nginx=1
6) 除了上面使用scale进行容器的扩容或缩容之外,还可以使用docker service update 命令。 可对 服务的启动 参数 进行 更新/修改。
[root@dockerManager ~]# docker service update --replicas 3 my_nginxdocker service update 命令,也可用于直接 升级 镜像等
[root@dockerManager ~]# docker service update --image nginx:new my_nginx
7) 删除service
[root@dockerManager ~]# docker service rm my_nginx
这样就会把所有节点上的所有容器(task任务实例)全部删除了
5.4 Swarm 中使用Volume(挂载目录)
1) 查看volume的帮助信息
[root@dockerManager ~]# docker volume --help
2) 创建一个volume
[root@dockerManager ~]# docker volume create --name testvolume
testvolume# 查看创建的volume
[root@dockerManager ~]# docker volume ls
DRIVER VOLUME NAME
local testvolume
# 查看volume详情
[root@dockerManager ~]# docker volume inspect testvolume
3) 创建新的服务并挂载testvolume(nginx为例)
[root@dockerManager ~]# docker service create --replicas 3 --mount type=volume,src=testvolume,dst=/zjz --name test_nginx nginx温馨提示:
参数src写成source也可以;dst表示容器内的路径,也可以写成target# 查看有没有挂载成功(登录各个节点的容器看看有没有指定的目录并创建文件测试)
# 容器中操作
[root@dockerManager ~]# docker exec -it 63451219cb4e /bin/bash
root@63451219cb4e:/# cd /zjz/
root@63451219cb4e:/zjz# ls
root@63451219cb4e:/zjz# echo "gen wo xue docker" > docker.txt
root@63451219cb4e:/zjz# ls
docker.txt
执行docker volume inspect testvolume 可以看到本地的路径(上面已经执行过了)
本地路径:/var/lib/docker/volumes/testvolume/_data
[root@dockerManager ~]# cd /var/lib/docker/volumes/testvolume/_data
[root@dockerManager _data]# ls
docker.txt
[root@dockerManager _data]# cat docker.txt
gen wo xue docker
还可以将node节点机上的volume数据目录做成软链接
[root@dockerManager _data]# ln -s /var/lib/docker/volumes/testvolume/_data /zjz
[root@dockerManager _data]# cd /zjz/
[root@dockerManager zjz]# ls
docker.txt
[root@dockerManager zjz]# echo "123" > 1.txt
[root@dockerManager zjz]# ll
总用量 8
-rw-r--r-- 1 root root 4 10月 21 11:04 1.txt
-rw-r--r-- 1 root root 18 10月 21 11:00 docker.txt
# 容器中查看
[root@dockerManager zjz]# docker exec -it 63451219cb4e /bin/bash
root@63451219cb4e:/# cd /zjz/
root@63451219cb4e:/zjz# ls
1.txt docker.txt
root@63451219cb4e:/zjz# cat 1.txt
123
root@63451219cb4e:/zjz# cat docker.txt
gen wo xue docker
# 还有一种挂载方式简单说一下吧,上面的会了下面的肯定简单
命令格式:
docker service create --mount type=bind,target=/container_data/,source=/host_data/
其中,参数target表示容器里面的路径,source表示本地硬盘路径
# 示例创建并挂载并使用网络
[root@dockerManager ~]# docker service create --replicas 1 --mount type=bind,target=/usr/share/nginx/html/,source=/opt/web/ --network nginx_net --name zjz_nginx -p 8880:80 nginx
5.5 多服务Swarm集群部署
我们这里部署三个服务(nginx服务,visualizer服务,portainer服务) 都是集群 GUI 管理服务
docker service部署的是单个服务,我们可以使用docker stack进行多服务编排部署
1) 编写docker-compose.yml文件
[root@dockerManager ~]# mkdir testswarm
[root@dockerManager ~]# cd testswarm/
[root@dockerManager testswarm]# vim docker-compose.yml
version: "3"
services:
nginx:
image: nginx
ports:
- 8888:80
deploy:
mode: replicated
replocas: 3
visualizer:
image: dockersamples/visualizer
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
portainer:
image: portainer/portainer
ports:
- "9000:9000"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
2) 通过这个yml文件部署服务
[root@dockerManager testswarm]# docker stack deploy -c docker-compose.yml deploy_deamon
通过上面的执行过程可以看出这样创建会默认创建一个网络并使用它,名字都是我们给的名字的前缀加上服务名
# 查看服务
[root@dockerManager testswarm]# docker service ls
# 查看nginx服务
[root@dockerManager testswarm]# docker service ps deploy_deamon_nginxing Running about a minute ago
# 查看portainer服务
[root@dockerManager testswarm]# docker service ps deploy_deamon_portainer
# 查看visualizer服务
[root@dockerManager testswarm]# docker service ps deploy_deamon_visualizer
6、Docker Swarm 容器网络
Docker Swarm在启动时自己会创建一些网络,然后利用它们实现容器之间的通信与负载均衡等功能。
# 查看docker swarm 网络信息
$ docker network ls NETWORK ID NAME DRIVER SCOPE cac91f9c60ff bridge bridge local b55339bbfab9 docker_gwbridge bridge local fe6ef5d2e8e8 host host local f1nvcluv1xnf ingress overlay swarm 8vty8k3pejm5 net1 overlay swarm 893a1bbe3118 none null local
docker_gwbridge:通过这个网络,容器可以连接到宿主机。(Driver为bridge)
ingress:这个网络用于将服务暴露给外部访问,docker swarm就是通过它实现的routing mesh(将外部请求路由到不同主机的容器)。(Driver为overlay)创建一个自定义的overlay
swarm模式的覆盖网络(
overlay)包括以下功能:
1)可以附加多个服务到同一个网络。
2)默认情况下,service discovery为每个swarm服务分配一个虚拟IP地址(vip)和DNS名称,使得在同一个网络中容器之间可以使用服务名称为互相连接。
3)可以配置使用DNS轮循而不使用VIP
4)为了可以使用swarm的覆盖网络,在启用swarm模式之间你需要在swarm节点之间开放以下端口:
5)TCP
/UDP
端口7946 – 用于容器网络发现
6)UDP端口4789 – 用于容器覆盖网络
#创建自定义voerlay网络
$ docker network create -d overlay my-overlay-network
#查看network
$ docker network ls
#创建服务时将服务连接到overlay网络
$ docker service create --replicas 3 --network my-overlay-network --name testService -p 80:80 nginx
#查询某个节点上关于my-overlay-network的详细信息
$ docker network inspect my-overlay-network
Docker Swarm 学习相关推荐
- Docker Swarm学习教程【转载】
Swarm介绍 Swarm是Docker公司在2014年12月初发布的一套较为简单的工具,用来管理Docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机.Swarm使用标准的Docke ...
- 如何使用Docker Swarm管理更多容器
by nolan grace 通过诺兰·格雷斯 如何使用Docker Swarm管理更多容器 (How to manage more containers with Docker Swarm) Sca ...
- docker swarm实践爆心肝总结全在这里,火速收藏!!!
Docker Swarm 快速入门 "这是一个非常棒的docker swarm学习历程.我把一个国外的docker精简实践教学进行了简略的翻译,比起国内博客学习的总结性文章,它更注重让小白在 ...
- Docker Swarm Mode 学习笔记(聊聊 replicas)
在 Swarm 集群中, 创建服务时可以通过设置 --replicas 参数来指定此服务在工作节点上运行的任务数. 示例 这里我们来创建一个 nginx 服务作为示例: version: '3'ser ...
- Docker学习总结(61)——Docker、Docker-Compose、Docker swarm 、 K8s 之间的区别
Docker Docker 这个东西所扮演的角色,容易理解,它是一个容器引擎,也就是说实际上我们的容器最终是由Docker创建,运行在Docker中,其他相关的容器技术都是以Docker为基础,它是我 ...
- Docker 学习总结(74)—— Docker Swarm 全面总结
一.前言 Swarm 是 Docker 公司推出的用来管理 docker 集群的平台,几乎全部用 GO 语言来完成的开发的,代码开源在 https://github.com/docker/swarm: ...
- 49学习容器管理平台 Docker Swarm 的基本概念和应用,包括节点管理、服务编排
Docker Swarm 是 Docker 官方提供的容器编排工具,可以管理多个 Docker 节点,并支持自动化扩展.负载均衡等功能.下面是 Docker Swarm 的基本概念和使用方法,包括节点 ...
- devops和docker_通过免费的2小时Docker课程学习DevOps基础知识
devops和docker Docker is a powerful DevOps tool for putting your apps into "containers." Do ...
- 容器管理大战:Kubernetes vs.Docker Swarm与Amazon ECS
Container Orchestration: 快速入门 自20世纪70年代以来,容器技术就已经出现,但直到2013年Docker首次亮相后才开始发挥作用.从那时起,容器已经流行起来:它们正在显著地 ...
最新文章
- Structured Streaming编程 Programming Guide
- ubuntu 修改environment导致无法启动
- spring MVC 项目 WEB-INF下的jsp不能加载css文件
- Leetcode每日一题:面试题16.19.水域大小
- 快速了解Spring Cloud
- DeepStream插件Gstreamer(一):概述
- Android 解锁app,应用锁「AppLock」v3.3.0 for Android 完美解锁版
- Java实现特征保持的图像加密算法
- 关于外接显示器无信号的解决办法Win10
- 2021西湖论剑网络安全大赛部分WP
- [计算机网络]十四、网卡的三种模式
- 爬虫小程序 - 单词量测试
- .NET Core 用 Blazor 做 jmeter 系列视频
- 小白面试:EF Core的三种事务
- 参加培训的小盆友进步了
- 浅谈代码规范基础调试几道面试题
- 如何用TL084制作低音炮电路
- Codeblocks的下载、安装以及使用方法(详细说明)
- openlayers3.20.1发布说明
- iPhone分辨率及尺寸
热门文章
- java 十进制转二进制代码_十进制转二进制代码
- 自动换行的两种代码(C#)
- Virtual Machine Software Architecture Style(虚拟机风格)
- impdp 并行_后台,并行expdp、impdp
- Quartus Win10系统USB-Blaster驱动识别解决方法
- 日志收集工具ELK,简单集群配置
- 获取空气质量指数(AQI)和天气信息
- 自动驾驶路径规划——基于概率采样的路径规划算法(PRM)
- 电竞耳机推荐什么牌子好?无线电竞耳机推荐
- Vue router2.0