JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

Docker Swarm(二):服务管理与数据卷挂载

wys521 2024-10-21 11:16:53 精选教程 20 ℃ 0 评论

上一篇文章对Swarm进行了介绍以及Swarm集群的搭建,本文将介绍在Swarm集群中如何对服务进行管理以及数据卷挂载。

上期回顾: Docker Swarm(一):Swarm介绍与集群搭建

服务管理

创建服务

Swarm特点:弹性、扩缩容

之前操作的 docker run 、docker-compose up 启动一个一项目,都是单机的;现在使用swarm集群,通过 docker service 来管理

之前单机:一个service就是指向的一个容器,比如一个 nginx服务指向一个nginx容器;

现在集群 :一个service可能指向一个或多个容器,比如对外暴露了一个nginx服务,实际上后端有多个nginx容器构成(就像负载均衡)。

命令:

[root@docker-1 ~]# docker service --help

Usage:  docker service COMMAND

Manage services

Commands:
  create      Create a new service                                    # 创建一个服务
  inspect     Display detailed information on one or more services    # 查看服务详细信息
  logs        Fetch the logs of a service or task                     # 查看日志
  ls          List services
  ps          List the tasks of one or more services
  rm          Remove one or more services                             # 移除服务
  rollback    Revert changes to a service's configuration
  scale       Scale one or multiple replicated services               # 伸缩一个或多个副本
  update      Update a service                                        # 更新服务

Run 'docker service COMMAND --help' for more information on a command.

创建服务:

[root@docker-1 ~]# docker service create -p 8888:80 --name my-nginx nginx
pvom9t9zbdkh3uk42jj3q06np
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged

查看服务:

# 通过 docker service ls 可以看到有哪些service在集群上 
# 当前只有一个 my-nginx service,当前只有1个副本,总共1个副本
[root@docker-1 ~]# docker service ls
ID             NAME       MODE         REPLICAS   IMAGE          PORTS
pvom9t9zbdkh   my-nginx   replicated   1/1        nginx:latest   *:8888->80/tcp


# 通过 docker service ps my-nginx 可以查看执行的service部署情况 
# 当前运行在 docker-3 机器上
[root@docker-1 ~]# docker service ps my-nginx
ID             NAME         IMAGE          NODE       DESIRED STATE   CURRENT STATE           ERROR     PORTS
rdz0t33xdvxx   my-nginx.1   nginx:latest   docker-3   Running         Running 5 minutes ago

当前my-nginx服务中,真正nginx容器运行在docker-3上,docker-1虽然是manager节点,但也能跑服务。

访问测试:

尽管真正的nginx容器运行在docker-3上,但是由于是采用集群部署模式,此时无论使用集群中的哪个主机IP访问8888端口都能够访问到nginx服务。

http://192.168.92.130:8888/
http://192.168.92.152:8888/
http://192.168.92.153:8888/
http://192.168.92.154:8888/

扩缩容

两个方式:

  • docker service update
  • docker service scale

通过 docker service update 扩缩容

当前my-nginx只有1个副本,现在给它扩到3个,使用 docker service update --replicas 3 my-nginx

[root@docker-1 ~]# docker service update --replicas 3 my-nginx
my-nginx
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 

[root@docker-1 ~]# docker service ls
ID             NAME       MODE         REPLICAS   IMAGE          PORTS
pvom9t9zbdkh   my-nginx   replicated   3/3        nginx:latest   *:8888->80/tcp


# 3个nginx副本分别在 docker-1、docker-3、docker-4机器上各自启动了一个容器
[root@docker-1 ~]# docker service ps my-nginx      
ID             NAME         IMAGE          NODE       DESIRED STATE   CURRENT STATE            ERROR     PORTS
rdz0t33xdvxx   my-nginx.1   nginx:latest   docker-3   Running         Running 17 minutes ago             
m2h63c6g4aee   my-nginx.2   nginx:latest   docker-1   Running         Running 48 seconds ago             
v0t9kqfplu9f   my-nginx.3   nginx:latest   docker-4   Running         Running 42 seconds ago

访问测试:

尽管docker-2上没有部署nginx容器,但是由于是采用集群部署模式,此时无论使用集群中的哪个主机IP访问8888端口都能够访问到nginx服务,包括docker-2。

http://192.168.92.130:8888/
http://192.168.92.152:8888/
http://192.168.92.153:8888/
http://192.168.92.154:8888/

扩到10个:

[root@docker-1 ~]# docker service update --replicas 10 my-nginx
my-nginx
overall progress: 10 out of 10 tasks 
1/10: running   [==================================================>] 
2/10: running   [==================================================>] 
3/10: running   [==================================================>] 
4/10: running   [==================================================>] 
5/10: running   [==================================================>] 
6/10: running   [==================================================>] 
7/10: running   [==================================================>] 
8/10: running   [==================================================>] 
9/10: running   [==================================================>] 
10/10: running   [==================================================>] 
verify: Service converged 


[root@docker-1 ~]# docker service ps my-nginx
ID             NAME          IMAGE          NODE       DESIRED STATE   CURRENT STATE            ERROR     PORTS
rdz0t33xdvxx   my-nginx.1    nginx:latest   docker-3   Running         Running 22 minutes ago             
m2h63c6g4aee   my-nginx.2    nginx:latest   docker-1   Running         Running 5 minutes ago              
v0t9kqfplu9f   my-nginx.3    nginx:latest   docker-4   Running         Running 4 minutes ago              
tcfx6gcwcmwe   my-nginx.4    nginx:latest   docker-4   Running         Running 39 seconds ago             
pmi5gdg62wsg   my-nginx.5    nginx:latest   docker-1   Running         Running 39 seconds ago             
jvu3wmhpv7q2   my-nginx.6    nginx:latest   docker-2   Running         Running 19 seconds ago             
nycvkr4ffnah   my-nginx.7    nginx:latest   docker-3   Running         Running 38 seconds ago             
fr6nmwmkel41   my-nginx.8    nginx:latest   docker-2   Running         Running 19 seconds ago             
u78vj5easfq0   my-nginx.9    nginx:latest   docker-2   Running         Running 19 seconds ago             
ck5p63zoqsq6   my-nginx.10   nginx:latest   docker-3   Running         Running 38 seconds ago

减到1个:

[root@docker-1 ~]# docker service update --replicas 1 my-nginx
my-nginx
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 


[root@docker-1 ~]# docker service ps my-nginx
ID             NAME         IMAGE          NODE       DESIRED STATE   CURRENT STATE            ERROR     PORTS
rdz0t33xdvxx   my-nginx.1   nginx:latest   docker-3   Running         Running 22 minutes ago

通过 docker service scale 扩缩容

[root@docker-1 ~]# docker service scale my-nginx=4
my-nginx scaled to 4
overall progress: 4 out of 4 tasks 
1/4: running   [==================================================>] 
2/4: running   [==================================================>] 
3/4: running   [==================================================>] 
4/4: running   [==================================================>] 
verify: Service converged 


[root@docker-1 ~]# docker service ps my-nginx 
ID             NAME         IMAGE          NODE       DESIRED STATE   CURRENT STATE            ERROR     PORTS
rdz0t33xdvxx   my-nginx.1   nginx:latest   docker-3   Running         Running 24 minutes ago             
kbzanlwvfffq   my-nginx.2   nginx:latest   docker-4   Running         Running 19 seconds ago             
y1bkw76cnsxh   my-nginx.3   nginx:latest   docker-2   Running         Running 19 seconds ago             
jqtazzjq715c   my-nginx.4   nginx:latest   docker-1   Running         Running 19 seconds ago

综上:使用swarm扩缩容真的是轻轻松松。

故障转移

当前在每台主机上都运行着一个nginx容器,我们停止docker-4上的nginx容器,模拟容器出现故障。

[root@docker-4 ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
99c0465704ba   nginx:latest   "/docker-entrypoint.…"   3 minutes ago   Up 3 minutes   80/tcp    my-nginx.2.kbzanlwvfffqm4eu2nr9m390u

[root@docker-4 ~]# docker stop 99c0465704ba
99c0465704ba

再来看看service运行情况:

[root@docker-1 ~]# docker service ps my-nginx
ID             NAME             IMAGE          NODE       DESIRED STATE   CURRENT STATE             ERROR     PORTS
rdz0t33xdvxx   my-nginx.1       nginx:latest   docker-3   Running         Running 27 minutes ago              
0l0h4vh4tw79   my-nginx.2       nginx:latest   docker-4   Running         Running 8 seconds ago               
kbzanlwvfffq    \_ my-nginx.2   nginx:latest   docker-4   Shutdown        Complete 14 seconds ago             
y1bkw76cnsxh   my-nginx.3       nginx:latest   docker-2   Running         Running 3 minutes ago               
jqtazzjq715c   my-nginx.4       nginx:latest   docker-1   Running         Running 3 minutes ago

可以看到docker-4上的nginx容器已经 Shutdown了,自动在docker-4上重建了一个新的nginx容器。

再次停止docker-4上重建的nginx容器,再次查看service运行情况,依然是在docker-4上重建的:

[root@docker-1 ~]# docker service ps my-nginx
ID             NAME             IMAGE          NODE       DESIRED STATE   CURRENT STATE             ERROR     PORTS
rdz0t33xdvxx   my-nginx.1       nginx:latest   docker-3   Running         Running 30 minutes ago              
5121f134n75t   my-nginx.2       nginx:latest   docker-4   Running         Running 49 seconds ago              
0l0h4vh4tw79    \_ my-nginx.2   nginx:latest   docker-4   Shutdown        Complete 55 seconds ago             
kbzanlwvfffq    \_ my-nginx.2   nginx:latest   docker-4   Shutdown        Complete 3 minutes ago              
y1bkw76cnsxh   my-nginx.3       nginx:latest   docker-2   Running         Running 6 minutes ago               
jqtazzjq715c   my-nginx.4       nginx:latest   docker-1   Running         Running 6 minutes ago

是不是停止哪个机器上的容器就在哪个机器上重建呢?

直接将docker-4主机关机,再查看:

此时docker-4上的nginx容器,自动转移到了docker-3主机上,并不受主机的影响,会在集群中自动调度。

[root@docker-1 ~]# docker service ps my-nginx
ID             NAME             IMAGE          NODE       DESIRED STATE   CURRENT STATE                     ERROR     PORTS
rdz0t33xdvxx   my-nginx.1       nginx:latest   docker-3   Running         Running 31 minutes ago                      
rsfjw6pck39l   my-nginx.2       nginx:latest   docker-3   Running         Starting less than a second ago             
5121f134n75t    \_ my-nginx.2   nginx:latest   docker-4   Shutdown        Running 2 minutes ago                       
0l0h4vh4tw79    \_ my-nginx.2   nginx:latest   docker-4   Shutdown        Complete 2 minutes ago                      
kbzanlwvfffq    \_ my-nginx.2   nginx:latest   docker-4   Shutdown        Complete 4 minutes ago                      
y1bkw76cnsxh   my-nginx.3       nginx:latest   docker-2   Running         Running 7 minutes ago                       
jqtazzjq715c   my-nginx.4       nginx:latest   docker-1   Running         Running 7 minutes ago

删除服务

使用 docker service rm

[root@docker-1 ~]# docker service rm my-nginx
my-nginx

[root@docker-1 ~]# docker service ls
ID        NAME      MODE      REPLICAS   IMAGE     PORTS

镜像变更/升级

重新新建service来测试:

docker service create -p 8888:80 --name my-nginx nginx
# 将镜像变更为 nginx:1.20 
[root@docker-1 ~]# docker service update --image nginx:1.20 my-nginx
my-nginx
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged
# 老镜像nginx:latest停止,新镜像nginx:1.20启用
[root@docker-1 ~]# docker service ps my-nginx
ID             NAME             IMAGE          NODE       DESIRED STATE   CURRENT STATE                 ERROR     PORTS
z2gmcjtljhqg   my-nginx.1       nginx:1.20     docker-3   Running         Running about a minute ago              
svh5jpysqcc3    \_ my-nginx.1   nginx:latest   docker-3   Shutdown        Shutdown about a minute ago

回滚到上个版本

# 回滚到上个版本
[root@docker-1 ~]# docker service update --rollback my-nginx
my-nginx
rollback: manually requested rollback 
overall progress: rolling back update: 1 out of 1 tasks 
1/1: running   [>                                                  ] 
verify: Service converged 

[root@docker-1 ~]# docker service ps my-nginx
ID             NAME             IMAGE          NODE       DESIRED STATE   CURRENT STATE             ERROR     PORTS
xak0904ma7wf   my-nginx.1       nginx:latest   docker-1   Running         Running 12 seconds ago              
z2gmcjtljhqg    \_ my-nginx.1   nginx:1.20     docker-3   Shutdown        Shutdown 13 seconds ago             
svh5jpysqcc3    \_ my-nginx.1   nginx:latest   docker-3   Shutdown        Shutdown 6 minutes ago

删除service:

[root@docker-1 ~]# docker service rm my-nginx
my-nginx

更多使用用法请看:

docker service update --help

数据卷挂载

我们之前已经学习过在容器中使用volume数据卷,这里我们来看看如何在swarm集群中使用数据卷。

volume数据卷

创建一个新的数据卷:

[root@docker-1 ~]# docker volume create my-volume
my-volume


[root@docker-1 ~]# docker volume ls
DRIVER    VOLUME NAME
local     my-volume


[root@docker-1 ~]# docker volume inspect my-volume
[
    {
        "CreatedAt": "2022-03-10T16:45:01+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
        "Name": "my-volume",
        "Options": {},
        "Scope": "local"
    }
]

创建一个service并使用数据库挂载:

# 创建service并使用volume挂载
# src可写为source,dst可写为target
[root@docker-1 ~]# docker service create --replicas 3 --mount type=volume,src=my-volume,dst=/vol_test --name my-nginx nginx
frar0fbts1f3ezwyttweoa10r
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 


[root@docker-1 ~]# docker service ls
ID             NAME       MODE         REPLICAS   IMAGE          PORTS
frar0fbts1f3   my-nginx   replicated   3/3        nginx:latest   


[root@docker-1 ~]# docker service ps my-nginx
ID             NAME         IMAGE          NODE       DESIRED STATE   CURRENT STATE            ERROR     PORTS
jbz6e1w0ce7n   my-nginx.1   nginx:latest   docker-1   Running         Running 18 seconds ago             
q4fuyxb7ctph   my-nginx.2   nginx:latest   docker-3   Running         Running 17 seconds ago             
f3ce25vrbrpb   my-nginx.3   nginx:latest   docker-2   Running         Running 18 seconds ago

在3个主机上部署了nginx容器,查看有没有挂载成功,我们逐个登录主机进入容器查看:

首先看docker-1机器:

[root@docker-1 ~]# docker exec -it 7865bec81dce /bin/bash
root@7865bec81dce:/# ls /vol_test/
root@7865bec81dce:/# echo "This is volume test from docker-1" > /vol_test/docker-1.txt
root@7865bec81dce:/# ls /vol_test/
docker-1.txt
root@7865bec81dce:/# exit
exit
[root@docker-1 ~]# ls /var/lib/docker/volumes/my-volume/_data/
docker-1.txt
[root@docker-1 ~]# cat /var/lib/docker/volumes/my-volume/_data/docker-1.txt 
This is volume test from docker-1

再来看 docker-2、docker-3 发现,我们在docker-1容器里创建的文件,docker-2、docker-3的容器里并没有,说明通过此方式挂载的数据卷只能用于本地,是不能够共享的。

另一种挂载方式:

语法:
docker service create --mount type=bind,source=/host_dir,target=/container_dir

# source路径要求在部署的目标机器上真实存在,比如部署3个副本有可能分部在不同主机,那每个主机上都必须要存在此目录

示例:

[root@docker-1 ~]# docker service create --mount type=bind,source=/opt/web,target=/usr/share/nginx/html -p 8888:80 --name my-nginx nginx
mumiyabkxyceeymzmkeoz637q
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 

[root@docker-1 ~]# docker service ls
ID             NAME       MODE         REPLICAS   IMAGE          PORTS
mumiyabkxyce   my-nginx   replicated   1/1        nginx:latest   *:8888->80/tcp

[root@docker-1 ~]# docker service ps my-nginx
ID             NAME         IMAGE          NODE       DESIRED STATE   CURRENT STATE            ERROR     PORTS
jwmr1e9zn1uk   my-nginx.1   nginx:latest   docker-3   Running         Running 33 seconds ago

部署到了docker-3.

在docker-3机器上 /opt/web/目录下创建一个index.html 文件:

[root@docker-3 ~]# echo "This is test from docker-3" > /opt/web/index.html

[root@docker-3 ~]# ls /opt/web/
index.html

访问测试:

使用任意主机IP访问8888端口:

[root@docker-1 ~]# curl http://192.168.92.153:8888
This is test from docker-3

删除service:

[root@docker-1 ~]# docker service rm my-nginx
my-nginx

小总结:

通过以上对数据卷的操作案例可以看出,数据卷之间的数据是不能够在集群中共享的,对于集群部署意义并不大,如果能共享数据才是极好的,可以使用nfs解决。

通过nfs在集群中共享数据:

我们需要用一台服务器当作nfs服务器,这里我们把docker-4当作nfs服务器,在docker-4上安装nfs服务。

yum install nfs-utils -y
mkdir -p /data/nfs

# 编辑 /etc/exports 文件,内容如下
[root@docker-4 ~]# cat /etc/exports
/data/nfs 192.168.92.0/24(rw,no_root_squash)

# 启动nfs
systemctl start nfs
systemctl enable nfs

创建服务:

[root@docker-1 ~]#  docker service create --mount 'type=volume,source=nfsvolume,target=/usr/share/nginx/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/data/nfs,"volume-opt=o=addr=192.168.92.154,rw,nfsvers=4,async"'  --replicas 4 -p 8888:80 --name my-nginx nginx
vqxjrbz91rdy9yutgnfmt2icc
overall progress: 4 out of 4 tasks 
1/4: running   [==================================================>] 
2/4: running   [==================================================>] 
3/4: running   [==================================================>] 
4/4: running   [==================================================>] 
verify: Service converged 
[root@docker-1 ~]# 
[root@docker-1 ~]# docker service ls
ID             NAME       MODE         REPLICAS   IMAGE          PORTS
vqxjrbz91rdy   my-nginx   replicated   4/4        nginx:latest   *:8888->80/tcp
[root@docker-1 ~]# 
[root@docker-1 ~]# docker service ps my-nginx
ID             NAME         IMAGE          NODE       DESIRED STATE   CURRENT STATE            ERROR     PORTS
yuwkqgd3mlyb   my-nginx.1   nginx:latest   docker-3   Running         Running 15 seconds ago             
h6n3t2v9c04x   my-nginx.2   nginx:latest   docker-2   Running         Running 16 seconds ago             
igoqir801uhu   my-nginx.3   nginx:latest   docker-4   Running         Running 16 seconds ago             
3jibweokor60   my-nginx.4   nginx:latest   docker-1   Running         Running 16 seconds ago

查看volume:

[root@docker-1 ~]# docker volume ls
DRIVER    VOLUME NAME
local     nfsvolume
[root@docker-1 ~]# 
[root@docker-1 ~]# docker volume inspect nfsvolume
[
    {
        "CreatedAt": "2022-03-10T17:44:05+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/nfsvolume/_data",
        "Name": "nfsvolume",
        "Options": {
            "device": ":/data/nfs",
            "o": "addr=192.168.92.154,rw,nfsvers=4,async",
            "type": "nfs"
        },
        "Scope": "local"
    }
]

每个机器上都自动创建了 nfsvolume 数据卷。

访问测试:

在 docker-4 上向/data/nfs/目录下创建一个index.html文件

[root@docker-4 ~]# echo "This is nfs volume test from docker-4" > /data/nfs/index.html

访问:

[root@docker-1 ~]# curl http://192.168.92.130:8888
This is nfs volume test from docker-4

成功访问到,成功。

多服务Swarm集群部署

前面我们操作的都是单个服务在swarm集群中部署,那如果要一次部署多个服务呢?

实际上我们可以利用compose来实现,compose默认只是针对多个服务在单机上批量部署的,但我们可以利用到compose中的deploy来定义在集群中如何部署。

关于deploy的官方文档: https://docs.docker.com/compose/compose-file/compose-file-v3/#deploy

deploy 部分的配置只在使用 docker stack deploy 部署到swarm集群中有效,使用 docker-compose 和 docker-compose run 时,deploy部分的配置将会忽略不会被执行。

如下 compose.yml

version: "3.9"
services:
  redis:
    image: redis:alpine
    deploy:
      replicas: 6
      placement:
        max_replicas_per_node: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

启动部署并查看:

# 启动部署
[root@docker-1 ~]# docker stack deploy -c compose.yml up
Creating network up_default
Creating service up_redis

# 看到共计6个副本,成功了4个,因为 (max 1 per node) 每一个节点最多只运行1个副本,这里我们只有4个节点,所以只有4个副本运行成功
[root@docker-1 ~]# docker service ls
ID             NAME       MODE         REPLICAS               IMAGE          PORTS
p0pn2w313tob   up_redis   replicated   4/6 (max 1 per node)   redis:alpine   

# 每个node上只有一个副本在运行,因为compose.yml中定义了 max_replicas_per_node: 1 每一个节点最多只运行1个副本,这里我们只有4个节点,所以看到有两个失败
[root@docker-1 ~]# docker service ps up_redis
ID             NAME         IMAGE          NODE       DESIRED STATE   CURRENT STATE                ERROR                              PORTS
t9b1s57ckrqq   up_redis.1   redis:alpine   docker-2   Running         Running about a minute ago                                      
56oplb1h7n3e   up_redis.2   redis:alpine   docker-4   Running         Running about a minute ago                                      
layzi9ggfu4u   up_redis.3   redis:alpine   docker-3   Running         Running about a minute ago                                      
y67mnxyppjcb   up_redis.4   redis:alpine              Running         Pending about a minute ago   "no suitable node (max replica…"   
56ouwyy0akwi   up_redis.5   redis:alpine              Running         Pending about a minute ago   "no suitable node (max replica…"   
sa8qso0r9m50   up_redis.6   redis:alpine   docker-1   Running         Running about a minute ago

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表