1.Docker Swarm的概述
1.1基本概念
Docker Swarm是基于Docker的集群调度管理工具,构建Docker集群,为容器生成副本,实现高可用。结合Overlay实现容器调度和互访。
用户可以通过Swarm API管理多个主机Docker。
Swarm集群包含Manager和Worker工作节点。
1.2 工作原理
在 Swarm 集群中部署镜像创建一个服务时。在一些大的应用上下文环境中需要各种服务配合工作,这样的服务通常称之为微服务。
在创建服务时,可以指定要使用的容器镜像以及容器中要运行的命令。服务还可以定义下面选项:
- 集群要对外服务的端口;
- 在集群中用于服务之间相连的 Overlay 网络:
- 滚动更新策略;
- 集群总运行的副本数量。
1.3基本特性
- 去中心化:包含manager和worker
- 声明式服务模型:定义所期望的服务状态
- 协调期望状态与实际状态的一致性
- 多主机网络
- 负载均衡
- 安全策略:利用TLS(传输层安全)进行身份验证和加密
- 滚动更新
2 实验案例
主机 | 主机名/IP | 主要软件 |
服务器 | manager/192.168.10.101 | centos |
服务器 | worker01/192.168.10.102 | centos |
服务器 | worker02/192.168.10.103 | centos |
二、实验部署
1.设置基础环境
(1)manager主机
[root@localhost ~]# hostnamectl set-hostname manager
[root@localhost ~]# bash
(2)worker01主机
[root@localhost ~]# hostnamectl set-hostname worker01
[root@localhost ~]# bash
(3)worker02主机
[root@localhost ~]# hostnamectl set-hostname worker02
[root@localhost ~]# bash
修改所有主机的hosts文件
[root@manager ~]# vim /etc/hosts
192.168.10.101 manager
192.168.10.102 worker01
192.168.10.103 worker02
2.在manager上创建docker swarm集群
[root@manager ~]# docker swarm init --advertise-addr 192.168.10.101
Swarm initialized: current node (zalgnhmr5p8sj0uu3nhydhmyi) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1j5w9tk2qy97kubws544d8z7arsq97ez8sbg1tgbt020cbc9vl-9yfyo91dvnag41xv6h1ahr71i 192.168.10.101:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
(将该令牌分别加入worker01和worker02上)
[root@manager ~]# docker info (查看集群信息)
或者
[root@manager ~]# docker node ls (查看集群中node的详细信息)
[root@manager ~]# docker node update --availability drain manager (将管理节点availability中active改为drain,使其只具备管理功能)
manager
[root@manager ~]# docker node ls
备注:
节点的 AVAILABILITY 有三种状态:Active、 Pause、Drain。
Active:集群中该节点可以被指派任务。
Pause:集群中该节点不可以被指派新的任务,但是其他已经存在的任务保持运行。
Drain:集群中该节点不可以被指派新的任务,Swarm Scheduler 停掉已经存在的任务,并将它们调度到可用的节点上
3.添加标签
[root@manager ~]# docker node update --label-add group=g2 worker01
标签名称:group=g2
[root@manager ~]# docker node inspect worker01 (查询指定节点标签)
[root@manager ~]# docker service create --name mynginx --constraint 'node.labels.group==g2' hub.atomgit.com/amd64/nginx:1.25.2-perl
备注:
constraint 约束
node.labels.group==g2 节点标签
[root@manager ~]# docker service ps mynginx ( 查看mynginx容器所在的主机)
4.节点提权
[root@manager ~]# docker node promote worker01 worker02 (将worker01和worker02升级为管理节点)
Node worker01 promoted to a manager in the swarm.
Node worker02 promoted to a manager in the swarm.
[root@manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
zalgnhmr5p8sj0uu3nhydhmyi * manager Ready Drain Leader 26.1.4
wza9aih7jfy4al00yqup0ov9i worker01 Ready Active Reachable 26.1.4
44oihz3cgvngokxnwyphpxomm worker02 Ready Active Reachable 26.1.4
对上面已提权的 worker01 和 worker02 执行降权操作
[root@manager ~]# docker node demote worker01 worker02
将swarm集群进行解散
[root@manager ~]# docker swarm leave --force
在worker上退出该节点
[root@worker01 ~]# docker swarm leave
注意:
工作节点退出集群后通过 docker swarm join 命令并指定对应的 token 值重新加入集群。
如果管理节点也推出了群,需要在管理节点上使用docker swarm init --advertise-addr 192.168.10.201命令再生成一次群,其他节点再加入一次群即可,相当于重新创建一次群集
集群解散后,swarm创建的service会被删除掉。
[root@manager ~]# docker service create -p 80:80 --replicas 2 --name web hub.atomgit.com/amd64/nginx:1.25.2-perl (使用 docker service create 命令创建 Docker 服务,从 Docker 镜像 创建一个名称为 web 的服务,指定服务副本数为 2。)
vk1i5vk31wsj9jkv6fjgorov7
overall progress: 2 out of 2 tasks
1/2: running
2/2: running
verify: Service vk1i5vk31wsj9jkv6fjgorov7 converged
[root@manager ~]# docker service ls (查看部署的应用服务)
[root@manager ~]# docker service ps web (查看指定服务的信息)
[root@manager ~]# docker service logs -f web (查看指定服务的日志)
[root@manager ~]# docker service inspect web (以JSON格式显示服务的详细信息)
[root@manager ~]# docker service inspect --pretty web (以阅读方式查看显示信息)
5.扩缩容
[root@manager ~]# docker service scale web=3 (已经部署的 2 个副本的 Web 服务,扩容到 3 个副本)
[root@manager ~]# docker service ps web
[root@manager ~]# docker service scale web=1 (将3个副本缩容到一个)
[root@manager ~]# docker service ps web
[root@manager ~]# docker service rm web (删除服务)
6.滚动跟新
[root@manager ~]# docker service create --replicas 3 --name nginx --update-delay 10s hub.atomgit.com/amd64/nginx:1.25.2-perl
[root@manager ~]# docker service update --image hub.atomgit.com/library/nginx:1.24-bullseye-perl nginx (更新已经部署服务所在容器中使用的镜像版本)
7.添加overlay网络
[root@manager ~]# docker network create --driver overlay my-network
kxw3zru6bseq5fjjmulwmfya6
[root@manager ~]# docker service create --replicas 3 --network my-network --name myweb hub.atomgit.com/amd64/nginx:1.25.2-perl
备注:
--driver 网络驱动器
如果 Swarm 集群中其他节点上的 Docker 容器也使用 my-network 网络,那么处于该
Overlay 网络中的所有容器之间都可以进行通信
8.数据卷的创建于应用
[root@manager ~]# docker volume create product-kgc (创建product-kgc卷)
[root@manager ~]# cd /var/lib/docker/volumes/ (创建卷的位置)
[root@manager volumes]# docker service create --mount type=volume,src=product-kgc,dst=/usr/share/nginx/html --replicas 2 --name kgc-web hub.atomgit.com/amd64/nginx:1.25.2-perl
[root@manager ~]# docker volume inspect product-kgc (查看数据卷)
到work01中查看数据是否进行同步
[root@worker01 ~]# cd /var/lib/docker/volumes/product-kgc/_data/
[root@worker01 _data]# mkdir test01 test02
[root@worker01 _data]# docker ps
创建测试目录
[root@manager ~]# mkdir -p /var/vhost/www/aa
[root@worker01 ~]# mkdir -p /var/vhost/www/aa
[root@worker02 ~]# mkdir -p /var/vhost/www/aa
在manager节点安装nfs-utils
[root@manager ~]# yum -y install nfs-utils
设置nfs共享
[root@manager ~]# vim /etc/exports
/var/vhost/www/aa *(rw,sync,no_root_squash)
启动nfs服务
[root@manager ~]# systemctl start nfs
[root@manager ~]# systemctl start rpcbind
在其他work节点分别挂载
yum -y install nfs-utils
mount 192.168.10.101:/var/vhost/www/aa /var/vhost/www/aa/
[root@manager ~]# docker service create --mount type=bind,src=/var/vhost/www/aaa/,dst=/usr/share/nginx/html --replicas 2 --name kgc-webbbb hub.atomgit.com/amd64/nginx:1.25.2-perl
[root@manager ~]# docker service ps kgc-webbbb
验证数据是否同步
[root@worker01 ~]# docker ps
[root@worker01 ~]# docker exec -it a11 bash
root@a113082dcad4:/# ls
bin dev docker-entrypoint.sh home lib32 libx32 mnt proc run srv tmp
boot docker-entrypoint.d etc lib lib64 media opt root sbin sys usr
root@a113082dcad4:/# cd /usr/share/nginx/html/
root@a113082dcad4:/usr/share/nginx/html# ls
root@a113082dcad4:/usr/share/nginx/html# echo bbb>index.html
[root@worker02 ~]# docker ps
[root@worker02 ~]# docker exec -it 9fc bash
root@9fcfdb686a29:/# cd /usr/share/nginx/html/
root@9fcfdb686a29:/usr/share/nginx/html# ls
index.html
root@9fcfdb686a29:/usr/share/nginx/html# cd index.html
bash: cd: index.html: Not a directory
root@9fcfdb686a29:/usr/share/nginx/html# ls
index.html
root@9fcfdb686a29:/usr/share/nginx/html# cat index.html
bbb