Docker Swarm实现容器的复制均衡及动态管理:详细过程版

Swarm简介

Swarm是一套较为简单的工具,用以管理Docker集群,使得Docker集群暴露给用户时相当于一个虚拟的整体。Swarm使用标准的Docker API接口作为其前端访问入口,换言之,各种形式的Docker Client(dockerclient in go, docker_py, docker等)均可以直接与Swarm通信。

Swarm的设计和其他Docker项目一样,遵循"batteries included but removable"原则

笔者对该原则的理解是:batteries included代表设计Swarm时,为了完全体现分布式容器集群部署、运行与管理功能的完整性,Swarm和Docker协同工作,Swarm内部包含了一个较为简易的调度模块,以达到对Docker集群调度管理的效果;"but removable"意味着Swarm与Docker并非紧耦合,同时Swarm中的调度模块同样可以定制化,用户可以按照自己的需求,将其替换为更为强大的调度模块,如Mesos等。另外,这套管理引擎并未侵入Docker的使用,这套机制也为其他容器技术的集群部署、运行与管理方式提供了思路。

Swarm 特点

对外以Docker API接口呈现,这样带来的好处是,如果现有系统使用Docker Engine,则可以平滑将Docker Engine切到Swarm上,无需改动现有系统。

Swarm对用户来说,之前使用Docker的经验可以继承过来。非常易上手,学习成本和二次开发成本都比较低。同时Swarm本身专注于Docker集群管理,非常轻量,占用资源也非常少。

"Batteries included but swappable",简单说,就是插件化机制,swarm中的各个模块都抽象出了api,可以根据自己一些特点进行定制实现。

Swarm自身对docker命令参数支持的比较完善,Swarm目前与Docker是同步发布的。Docker的新功能,都会第一时间在Swarm中体现。

实验开始

实验环境

主机 IP 系统 角色

153 192.168.121.153 centos7 manager

154 192.168.121.154 centos7 worker

155 192.168.121.155 centos7 worker

命令介绍:

-d 后台运行

--name 指定server 名,不是容器名(容器命令默认 服务名.编号.随机id串)

-p 指定service映射的端口

--network 指定网络

--mode 指定容器分配的模式(replicated: 随机分配,可由 constraint约束分配到哪些节点 global:全局,确保每个节点都会有该服务的容器)

--constraint 约束容器分配到哪些节点

--replicas 指定当前services 下创建的 容器的数量

--replicas-max-per-node 指定每个节点可创建给service的容器的最大数

--restart-condition 重启条件,类似于 容器run的 --restart

--user 指定运行用户身份

--endpoint-mode 负载均衡模式 vip dns

nginx:latest 创建容器使用的镜像

首先准备好三台机子 ,我是用153、154 、155

每台主机都配置A记录相互解析

bash 复制代码
cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.121.153 server153
192.168.121.154 server154
192.168.121.155 server155

dcoker的安装

先卸载本机原来的docker,如果主机是干净的就不用执行这步,我是还原的机子,所以这步不执行也没什么

bash 复制代码
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

然后去官方下载docker的yum源

bash 复制代码
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

然后下载docker

bash 复制代码
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

启动docker

bash 复制代码
sudo systemctl start docker

swarm集群的创建

然后我们指定一台153主机构建一个集群并成为管理节点

bash 复制代码
[root@server153 ~]# docker swarm init
Swarm initialized: current node (cul5m5m456oq9wwrbw91i5vsu) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-15p6qvh2u2znrrcslz53inkdhleubl8x9m5xlcm27f9q2eimyl-enul5wbhb6qepej1nod6jdrq2 192.168.121.153:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

集群构建好以后我们去154和155主机加入这个集群

bash 复制代码
[root@server154 ~]# docker swarm join --token SWMTKN-1-15p6qvh2u2znrrcslz53inkdhleubl8x9m5xlcm27f9q2eimyl-enul5wbhb6qepej1nod6jdrq2 192.168.121.153:2377
This node joined a swarm as a worker.
bash 复制代码
[root@server154 ~]# docker swarm join --token SWMTKN-1-15p6qvh2u2znrrcslz53inkdhleubl8x9m5xlcm27f9q2eimyl-enul5wbhb6qepej1nod6jdrq2 192.168.121.153:2377
This node joined a swarm as a worker.

然后去153管理主机查看集群情况

bash 复制代码
[root@server153 ~]# docker node   ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
cul5m5m456oq9wwrbw91i5vsu *   server153   Ready     Active         Leader           24.0.7
fh23wcmmfmt7vyayh7bzx28ls     server154   Ready     Active                          24.0.7
5y468v8pk98ei79frycmz9fww     server155   Ready     Active  

可以看到集群情况都是健康的

然后开始我们项目的部署

首先在管理节点创建一个overlay网络给这个集群通信使用

bash 复制代码
[root@server153 ~]# docker  network create  --driver overlay  nginx-net
zwvmf0upuledjh2uarupfnzgt
[root@server153 ~]# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
db5d2975dd04   bridge            bridge    local
31eb2f0c4e92   docker_gwbridge   bridge    local
52a372541a65   host              host      local
ag7i6g1sb542   ingress           overlay   swarm
zwvmf0upuled   nginx-net         overlay   swarm
b95fd0863462   none              null      local

service的构建

然后在每个节点都拉取一个nginx的最新镜像

当然只在管理节点拉也行,管理节点会将镜像分发给其它节点来保证镜像的一致性

不过分发镜像需要时间,所以还是先拉取一样的镜像比较好

为了验证我故意在155节点不拉取镜像

bash 复制代码
[root@server153 ~]# docker pull nginx:latest
[root@server153 ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    c20060033e06   3 days ago   187MB

然后开始构建service,其中参数不懂得可以对照上面写的,上面开头介绍了用到的参数

复制代码
[root@server153 ~]# docker  service  create  -d  --name web -p80:80  --network nginx-net --replicas 3  --replicas-max-per-node 10  --restart-condition  any  --user root  --mode  replicated  nginx:latest

然后查看service web下容器的情况

因为我们指定创建三个容器,刚好每个节点一台

然后这里注意看155节点容器的运行时间比其它两个节点少一分钟

那就是因为分发镜像要花时间,他启动的就比其它两个节点晚一分钟,镜像越大分发的时间越长

bash 复制代码
[root@server153 ~]# docker service ps web 
ID             NAME      IMAGE          NODE        DESIRED STATE   CURRENT STATE           ERROR     PORTS
u4cxfrcd2t4q   web.1     nginx:latest   server153   Running         Running 9 minutes ago             
w22cnbrdjo24   web.2     nginx:latest   server154   Running         Running 9 minutes ago             
n2g4nma52mtg   web.3     nginx:latest   server155   Running         Running 8 minutes ago   

起来了以后我们访问去浏览器访问试试

可以看到访问每台机子都是可以的,而且还实现了负载均衡,因为内容一样看不出来,下面我来实验一下

给三台机子里的文件index.html编辑不同的内容

bash 复制代码
[root@server153 ~]# echo 33333333333333333 > ./index.html
[root@server153 ~]# docker cp ./index.html web.1.qydzc04d6vt4q2ux4uzokir6z:/usr/share/nginx/html/index.html
Successfully copied 2.05kB to web.1.qydzc04d6vt4q2ux4uzokir6z:/usr/share/nginx/html/index.html
bash 复制代码
[root@server154 ~]# echo 44444444444444 > ./index.html
[root@server154 ~]# docker cp ./index.html web.2.d2qto723yk3hqlb76leaps3u5:/usr/share/nginx/html/index.html
Successfully copied 2.05kB to web.2.d2qto723yk3hqlb76leaps3u5:/usr/share/nginx/html/index.html
bash 复制代码
[root@server155 ~]# echo 55555555555 > index.php
[root@server155 ~]# docker cp ./index.php web.3.b41rsxvjxw7br5vxk5d6i74ve:/usr/share/nginx/html/index.html
Successfully copied 2.05kB to web.3.b41rsxvjxw7br5vxk5d6i74ve:/usr/share/nginx/html/index.html

因为浏览器有缓存,测试不了,我直接用curl测试

bash 复制代码
[root@server153 ~]# curl 192.168.121.153
44444444444444
[root@server153 ~]# curl 192.168.121.153
55555555555
[root@server153 ~]# curl 192.168.121.153
33333333333333333
[root@server153 ~]# curl 192.168.121.153
44444444444444
[root@server153 ~]# curl 192.168.121.153
55555555555
[root@server153 ~]# curl 192.168.121.153
33333333333333333

可以看到我只是访问了153节点,但是却能访问到其它节点的docker的内容

所以这就是负载均衡的实现,swarm集群会自动实现负载均衡

docker service scale 的扩展

docker swarm还可以扩展或缩小容器服务

下面也展示一下,一开始我们不是指定三个容器而已吗,现在我们扩展为5个,并查看容器情况

bash 复制代码
[root@server153 ~]# docker service scale web=5
web scaled to 5
overall progress: 5 out of 5 tasks 
1/5: running   
2/5: running   
3/5: running   
4/5: running   
5/5: running   
verify: Service converged 
[root@server153 ~]# docker service ps web 
ID             NAME      IMAGE          NODE        DESIRED STATE   CURRENT STATE                ERROR     PORTS
qydzc04d6vt4   web.1     nginx:latest   server153   Running         Running 46 minutes ago                 
d2qto723yk3h   web.2     nginx:latest   server154   Running         Running 46 minutes ago                 
b41rsxvjxw7b   web.3     nginx:latest   server155   Running         Running 46 minutes ago                 
6tfah9y7hsvi   web.4     nginx:latest   server153   Running         Running about a minute ago             
a4jxhcyn33ui   web.5     nginx:latest   server155   Running         Running about a minute ago   

可以看到我们多出了两个容器,并且由swarm随机分配到其它节点上

我们去访问试试

bash 复制代码
[root@server153 ~]# curl 192.168.121.154
55555555555
[root@server153 ~]# curl 192.168.121.154
33333333333333333
[root@server153 ~]# curl 192.168.121.154
44444444444444
[root@server153 ~]# curl 192.168.121.154
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

可以看到不仅访问到了原来我们修改的信息,还访问到了其它信息

那是因为我们扩展容器节点是创建新的容器,容器里的内容就是原本镜像生成的,所以内容就会变为原来的页面信息,后面真实生产环境中挂volume载数据券就可以保持数据一致了

docker service scale 的缩小

当然还有缩小docker服务,这个在高峰访问流量下来以后还是很有用的

bash 复制代码
[root@server153 ~]# docker service scale web=2
web scaled to 2
overall progress: 2 out of 2 tasks 
1/2: running   [==================================================>] 
2/2: running   [==================================================>] 
verify: Service converged 
[root@server153 ~]# docker service ps web 
ID             NAME      IMAGE          NODE        DESIRED STATE   CURRENT STATE               ERROR     PORTS
qydzc04d6vt4   web.1     nginx:latest   server153   Running         Running about an hour ago             
d2qto723yk3h   web.2     nginx:latest   server154   Running         Running about an hour ago             

可以看到将5个docker服务缩小为2个以后,155节点上的就没有了,这样就减少了资源的消耗

docker swarm的基本用法就是这样了

希望对大家有帮助

相关推荐
阿里云云原生5 小时前
LLM 不断提升智能下限,MCP 不断提升创意上限
云原生
阿里云云原生5 小时前
GraalVM 24 正式发布阿里巴巴贡献重要特性 —— 支持 Java Agent 插桩
云原生
sauTCc8 小时前
Docker初探
docker
宁zz8 小时前
乌班图安装jenkins
运维·jenkins
云上艺旅8 小时前
K8S学习之基础七十四:部署在线书店bookinfo
学习·云原生·容器·kubernetes
c无序8 小时前
【Docker-7】Docker是什么+Docker版本+Docker架构+Docker生态
docker·容器·架构
FixBug_Nick8 小时前
使用Docker安装及使用最新版本的Jenkins
docker·容器·jenkins
大丈夫立于天地间8 小时前
ISIS协议中的数据库同步
运维·网络·信息与通信
rainFFrain9 小时前
单例模式与线程安全
linux·运维·服务器·vscode·单例模式
ghostwritten10 小时前
Run Milvus in Kubernetes with Milvus Operator
容器·kubernetes·milvus