暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Docker-Swarm集群管理

星河之码 2022-12-20
1598

「伸手摘星,即使一无所获,亦不致满手污泥」

「请关注公众号:星河之码」

一、Docker Swarm介绍

「Docker Swarm是Docker的集群管理工具,它提供了标准的Docker API,所有任何已经与Docker守护程序通信的工具都可以使用Swarm轻松地扩展到多个主机」。支持的工具包括Dokku、Docker Compose、Docker Machine和Jenkins等。

compose、machine 和 swarm 是docker 原生提供的三大编排工具,简称docker三剑客。其官网地址

https://docs.docker.com/engine/swarm/

  • 「Docker Swarm 和 Docker Compose」

    Docker Swarm 和 Docker Compose都是 Docker 官方容器编排项目

    • 「Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,可以将组成某个应该的多个docker容器编排在一起,同时管理」

    • 「Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口(docker stack)统一管理这些Docker主机上的各种Docker资源」

  • 「docker stack」

    • docker stack 是构成特定环境中的 service 集合, 它是自动部署多个相互关联的服务的简便方法,而无需单独定 义每个服务。
    • stack file 是一种 yaml 格式的文件,类似于 docker-compose.yml 文件,它定义了一个或多个服务,并 定义了服务的环境变量、部署标签、容器数量以及相关的环境特定配置等。

Docker Swarm就是用来管理Docker集群的,但是现在基本上使用的很少,一般都是用的K8S,学习K8S之前可以先学习一个Docker Swarm,将其作为一个容器编排的一个学习基础,了解一下即可

二、Docker Swarm运行原理

Swarm集群由多个运行在swarm mode的docker主机组成,docker主机分为管理节点(manager)和工作节点(work node)两种类型

  • 「管理节点(manager):负责整个集群的管理工作包括集群配置、服务管理,服务的创建和调度等」

  • 「工作节点(work node):负责运行相应的服务来执行任务(运行容器服务)」

    manager节点也可以运行的容器服务,但是一般不这么做,只是让它管理work node

Swarm集群的优点:

  • 在线修改Service的配置,包括networks和volumes,不需要重启docker服务
  • 可以将其它standalone模式的docker主机加入到Swarm集群

Standalone模式简单点说就是  manager 和 work 的一种管理关系模式

「在Docker  Swarm中有几个基本概念:nodes、Service、tasks、load balancing」。需要简单了解一下

2.1 nodes

Node是加入到Swarm集群中的Docker实例,即是一个docker节点,包含上面说的【管理节点(manager)和工作节点(work node)】

  • 在部署应用到Swarm集群的时候,会向管理节点提交service定义,管理节点会将这些这些work也就是tasks分发到work节点中。
  • Work节点接收并执行管理节点分配的任务,work节点也会将当前tasks的状态通知到管理节点以维护节点的状态信息。
  • 「管理节点(manager node)」

    「Manager节点主要通过raft算法实现整个集群和运行的service的内部状态维护,Docker官方建议一个集群最好使用基数manager节点数(最大使用7个manager节点)保证可用性」 ,Manager节点主要工作是完成以下tasks:

    • 维护cluster state
    • scheduling服务
    • service swarm mode集群服务
  • 「工作节点(work node)」

    Work节点是容器实际运行的实例节点,在默认情况下manager节点也是work节点,而且在在Swarm集群中必须存在manager节点

    manager节点状态、信息的同步根据Raft consensus group(Raft一致性算法)的网络进行通信同步的,而worker之间的通信依靠的是Gossip network通信协议实现的。

  • 「管理节点与工作节点的切换」

    在多节点的Swarm集群中,节点有两种模式:【Active模式,Drain模式】。

    「Swarm调度不会将任务分配到Drain模式,只会在Active模式的节点上分配任务。因此可以将manager节点设置为Drain模式(避免调度任务运行在manager节点,manager指做管理)」

    docker node promote

    通过以上命令可以修改节点模式,将worker节点变为manager节点,也可以将manager节点转换为worker节点。

2.1 Service与tasks

「Service是manage和work节点上执行的task的定义,创建service的时候可以指定使用哪个container image以及执行的命令。」

「当Service部署到Swarm集群的时候,swarm管理节点会将service为标准(container image以及执行的命令),然后将service调度到集群的节点上,以一个或多个tasks执行」,这些nodes上运行的tasks之间是相互独立的。

  • 「在replicated service模式下,swarm管理节点会根据desired state中设置的scale分发replica tasks」
  • 「在globalservice模式,swarm集群会向每个可用的节点运行tasks」

如上service中有三个replicas tasks,每个实例是Swarm集群中的一个task。

「Task是Swarm集群中调度的最小单元,当创建或更新service时候给定了desired state,集群会调度tasks来实现这种理想状态」

  • Task是一种单向机制,它整个周期过程中会完成一系列的状态(assigned、prepared和running等),tasks运行失败集群会remove这个tasks并创建新的tasks来替代。

2.1 load balancing

「负载均衡:Swarm集群使用ingress loading balancing提供集群服务,Swarm集群会自动为service分配PublishedPort,默认使用30000-32767范围」

三、Docker-swarm安装部署

3.1 准备工作

  • 「官方地址」

    https://docs.docker.com/engine/swarm/

  • 「添加私服仓库地址」

    由于官方镜像下载比较慢,由于网络原因可能拉取不下来,而集群的每个节点都需要安装镜像,所以使用私有仓库会快很多,当然也可以不使用私有仓库,直接自己下载上传。

    #编辑配置文件
    vi etc/docker/daemon.json
    #增加仓库配置信息
    # 在daemon.json中添加以下 key,保存退出。此步用于让 docker 信任私有仓库地址
    {"insecure-registries":["192.168.242.130:5000"]}


    #重新加载docker配置
    systemctl daemon-reload
    #重启docker
    systemctl restart docker

3.2 docker-swarm安装

这里模拟安装集群,以三个节点搭建集群在加上一个Harbor节点,节点信息如下

节点Ip说明
manager-01192.168.242.131swarm-manager 节点
work-01192.168.242.132swarm-work节点
work-02192.168.242.133swarm-work节点
harbor192.168.242.130harbor 私服

安装上述配置,克隆出相应的虚拟机,其中harbor之前已经存在,这里用之前的,所以一共克隆出三个服务器

  • 「查看网络情况」

    docker network ls

  • 「初始化manager管理节点」

    初始化manager管理节点完整命令如下

    #这里使用192.168.242.131这台主机作为manager 所以以下命令在192.168.242.131上执行 端口默认是2377
    docker swarm init --advertise-addr 192.168.242.131:2377 --listen-addr 192.168.242.131:2377

    执行上面命令后,就会初始化swarm集群,并且会告诉我们如何增加wrok 节点和manager节点

    • 「再次查看网络情况」

      #集群初始化后会新增集群网络
      docker network ls

    • 「--advertise-addr」:指定其他节点连接manager时的地址
    • 「--listen-addr」:监控swarm集群manager的IP和端口
    • 「语法」

      docker swarm init 

    • 参数说明

      这个命令需要指定两个参数--advertise-addr  与--listen-addr

  • 「查看节点」

    docker node ls

  • 「新加一个work节点」

    通过上面初始化manager返回的命令,给集群加入新的节点,只需要在对应的主机上执行该命令即可

    docker swarm join --token SWMTKN-1-55wujoaco7zp7kdvot57wu15drul4m3svoifnitz69r6jv2xyj-5o009d6f4oxlnahfwfzke5ukj 192.168.242.131:2377

    我在192.168.242.132这台主机上执行上述命令,将其加入到集群中

    这个命令「本质上就是manager初始化的时候返回了一个token,其他主机通过这个token加入集群,并且token只有24小时」。如果失效,则需要重新获取

    • 「重新获取token」

      #获取一个worker加入集群的token
      docker swarm join-token worker

  • 「查看节点」

    docker node ls

  • 「新加一个manager节点」

    一个集群要有多个manager节点,上面加入了work节点,接下来在集群中加入一个manager节点,加入方式一样的,先获取manager的token

    • 「获取manager节点的token」

      #获取一个manager加入集群的token  ,这个命令要在之前的那个manager 192.168.242.131 上执行
      docker swarm join-token manager

    • 「加入集群」

      这里就用  192.168.242.133 这个主机作为一个manager加入集群

3.3 swarm节点说明

  • 「manager与work的权限」

    「swarm集群中,只有manager节点可以执行swarm命令(比如docker node ls),work节点会报错,因为只有manager节点才可以管理集群,执行集群相关的命令」

    work 节点只是不能执行swarm的集群命令,但是docker本身的命令是可以执行的,比如docker ps等

  • 「查看节点信息」

    可以分别在manager和node中查看节点的swarm信息,对比差异

    docker info

  • 「节点可用性与状态说明」

    在使用docker node ls 命令查看集群的节点信息的时候,有两列需要注意一下:AVAILABILITY,MANAGER STATUS

    • 「Leader:该节点是集群管理和编排决策的主要管理器节点。」
    • 「Reachable:该节点是管理者节点正在参与Raft选举。如果Leader节点不可用,则该节点有资格被选为新领导者。」
    • 「Unavailable:该节点属于不能与其他manager通信的manager。如果manager节点不可用,可以将它加入群集,或者将工作器节点升级为管理器」
    • 「Active:调度程序可以将任务分配给当前节点。」
    • 「Pause:调度程序不会将新任务分配给当前节点,但现有任务仍在运行。」
    • 「Drain:调度程序不会向当前节点分配新任务。调度程序关闭所有现有任务并在可用节点上重新调度这些任务。」
    • 「AVAILABILITY」

      决定当前节点可用性,是否用于运容器,它有三个值:

      「改变节点的可用性(availability)」

      docker node update --availability drain 节点Id/名称

    • 「MANAGER STATUS」

      表示manger节点的状态,work节点为空,它也有三个状态值

3.4 集群节点管理

  • 「节点权限提升/降低」

    节点manager和work两种,他们的权限不一样,我们可以手动的对节点权限提升/降低,也是「将manager降级为work,将work升级为manager节点」。升级降级的命令都要在manager节点执行。

    • 「将work升级为manager节点」

      #将worker节点提升为manager节点,在manager节点执行如下命令:
      docker node promote 节点名称|节点ID

      比如我将132 节点升级为manager节点

    • 「将manager降级为work」

      将manager节点降低为worker节点,在manager节点执行如下命令:
      docker node demote 节点名称|节点ID
      docker node ls

      将刚刚升级的132 节点重新降级为worker节点

  • 「work脱离集群」

    前面演示了怎么给集群中加入节点,现在来看看将节点脱离集群

    #在要脱离集群的节点上使用一下命令, 主动离开集群,让节点处于down状态,才能删除
    docker swarm leave
    #指向完后,等一会在manager节点使用命令:docker node ls 就会发现该节点已经脱离集群管理

    这里我将132节点脱离集群

  • 「删除脱离集群的节点」

    上述节点脱离集群后,才能删除节点,删除节点使用如下命令

    docker node rm 节点名称|节点ID

  • 「manager脱离集群」

    「manager节点不能脱离集群,使用docker swarm leave会报错」

    manager节点不能脱离集群,只能强制退出,manager退出后意味着整个swarm 不复存在。

    #manager节点强制退出
    docker swarm leave --force

3.5 Docker-swarm命令汇总

  • 「swarm命令汇总」

    命令描述
    docker swarm init初始化一个 swarm 群集
    docker swarm join加入群集作为节点或管理器
    docker swarm join-token管理用于加入群集的令牌
    docker swarm leave离开 swarm 群集
    docker swarm unlock解锁 swarm 群集
    docker swarm unlock-key管理解锁钥匙
    docker swarm update更新 swarm 群集
  • 「node命令汇总」

    命令描述
    docker node demote从 swarm 群集管理器中降级一个或多个节点
    docker node promote将一个或多个节点推入到群集管理器中(也就是升级节点)
    docker node inspect显示一个或多个节点的详细信息
    docker node ls列出 swarm 群集中的节点
    docker node ps列出在一个或多个节点上运行的任务,默认为当前节点
    docker node rm从 swarm 群集删除一个或多个节点
    docker node update更新一个节点


四、图形界面

上述安装过程是通过命令行的方式安装docker-swarm,docker-swarm也提供了一个图形界面来操作,接下来就来安装一下docker-swarm的图形界面。

「docker-swarm的图形界面需要安装在manager节点上」,不然无法操作节点

#docker官网地址
https://hub.docker.com/r/dockersamples/visualizer

  • 「拉取镜像」

    docker pull dockersamples/visualizer:latest

  • 「备份镜像」

    备份镜像有两种方式:私服和tar包。

    • 「tar包」

      镜像拉取下来之后,可以把它打成一个tar,保存起来,后面使用的时候直接还原即可,就不用下载了

      #打成一个tar 包
      docker save dockersamples/visualizer:latest -o dockersamples.visualizer.tar
      #需要用的时候还原成镜像
      docker load -i dockersamples.visualizer.tar

    • 「私服」

      除了打成tar 存在本地之外,还可以将镜像上传私服,以后在私服拉取

      # 1、标记镜像打一个tag
      docker tag dockersamples/visualizer:latest 192.168.242.130:5000/edwinedu/dockersamples/visualizer:latest

      # 2、上传标记的镜像 上传之前要先登录 docker login -u admin -p Harbor12345 192.168.242.130:5000
      docker push 192.168.242.130:5000/edwinedu/dockersamples/visualizer:latest

  • 「运行镜像」

    # var/run/docker.sock 是必须要的挂载目录  HOST是指定Ip,需要是manager节点的Ip
    docker run -itd --name visualizer -p 8099:8080 -e HOST=192.168.198.131 -e PORT=8080 -v var/run/docker.sock:/var/run/docker.sock 192.168.242.130:5000/edwinedu/dockersamples/visualizer:latest

  • 「访问图形界面」

    http://192.168.242.131:8099/

五、Docker-service

docker-service 是指一组任务的集合,服务定义了任务的属性,比如任务的个数、服务策略、镜像的版本号等,服务有两种模式:

  • replicated services:按照一定规则在各个工作节点上运行指定个数的任务
  • global services:每个工作节点上运行一个任务

接下来以Nginx为例,分别在几个节点上部署Nginx任务

5.1 Nginx基础镜像准备

  • 「拉取Nginx镜像」

    docker pull nginx:1.18.0-alpine

  • 「备份镜像」

    由于要在每个节点都安装Nginx,所以需要在每个节点都下载镜像,当然可以使用私服下载,但是这里我不使用私服,练习一个scp命令

    #打成一个tar 包
    mkdir -p data/nginx
    docker save nginx:1.18.0-alpine -o data/nginx/nginx:1.18.0.tar

  • 「传输镜像」

    将nginx镜像使用scp 命令传输到192.168.242.132,192.168.242.132两个节点中

    #执行下面命令之前,要确保132 133 两个节点有指定的目录 data/nginx  
    #注意nginx\:1.18.0.tar 中间有一个反斜杠
    scp data/nginx/nginx\:1.18.0.tar root@192.168.242.132:/data/nginx
    scp data/nginx/nginx\:1.18.0.tar root@192.168.242.133:/data/nginx

  • 「解压nginx」

    分别在所有节点中解压nginx (192.168.242.132,192.168.242.132两个节点)

    cd data/nginx
    docker load -i nginx:1.18.0.tar

5.2 部署Nginx

  • 「创建nginx网络」

    在manager节点中创建overlay网络

    docker network create -d overlay nginx-net

  • 「部署Nginx」

    在集群中创建7个Nginx服务,在manager节点中执行,使用【docker service create】命令

    # --network nginx-net 使用刚刚创建的网络
    # replicas 7 代表 7个副本服务
    docker service create --name nginx --network nginx-net -p 80:80 --replicas 7 nginx:1.18.0-alpine

    • 「界面查看」

    • manager节点也可以查看

      docker service ls

  • 「访问Nginx」

    #三台主机都可以访问
    http://192.168.242.131/80
    http://192.168.242.132/80
    http://192.168.242.133/80

  • 「剔除manager中非服务」

    前面说manager节点只用于管理集群,一般不部署服务,而在上面图形界面中显示,manager中有三个服务,如果要剔除,可以执行以下命令

    docker node update --availability drain 节点Id|名称

  • 「服务的缩容与扩容」

    目前是在两个work中部署了7个nginx,如果要扩容与缩容,只需要修改service的数量就可以无感扩容与缩容,执行一下命令

    #将nginx服务从七个减到5
    docker service scale nginx=5

5.3 升级Nginx

在我们日常开发中,版本迭代是非常常见的,可能一周、一个月就迭代一个版本,那么版本迭代升级应该怎么做呢,接下来我们将nginx从1.18升级到1.19。

  • 「查看nginx版本」

    查看nginx版本可以通过容器查看,也可以通过界面查看

    #通过容器查看版本,先进入容器中
    docker exec -it 503fe639bb89 sh
    nginx -v
    #退出容器
    exit

  • 「准备nginx:1.19的镜像」

    跟上面1.18的镜像一样,先在manager节点上拉取镜像,然后scp到132 133两台主机上,生产环境我们可以使用私服拉取镜像,不需要打包,这里只是练习scp命令

    #拉取nginx:1.19.3-alpine镜像
    docker pull nginx:1.19.3-alpine

    #打成一个tar 包
    mkdir -p data/nginx
    docker save nginx:1.19.3-alpine -o data/nginx/nginx:1.19.3.tar

    #执行下面命令之前,要确保132 133 两个节点有指定的目录 data/nginx
    #注意nginx\:1.18.0.tar 中间有一个反斜杠
    scp data/nginx/nginx\:1.19.3.tar root@192.168.242.132:/data/nginx
    scp data/nginx/nginx\:1.19.3.tar root@192.168.242.133:/data/nginx

    #分别在132 133 主机上执行解压1.19.3.tar
    cd /data/nginx
    docker load -i nginx:1.19.3.tar

  • 「升级Nginx」

    在manager节点执行以下命令,将nginx从1.18.0-alpine升级到1.19.3-alpine

    docker service update --image nginx:1.19.3-alpine nginx

  • 「添加一个对外端口」

    #将8090 也映射到容器的80端口
    docker service update --publish-add 8090:80 nginx

5.4 删除Nginx服务

  • 「删除service」

    docker service rm nginx

  • 「删除之前创建的nginx-net」

    docker network rm nginx-net

5.5 Docker-service命令汇总

命令描述
docker service create创建服务
docker service inspect显示一个或多个服务的详细信息
docker service logs获取服务的日志
docker service ls列出服务
docker service rm删除一个或多个服务
docker service scale设置服务的实例数量
docker service update更新服务
docker service rollback恢复服务至update之前的配置

六、Docker-stack

6.1 Docker-stack的使用

「Stack是一组Service,和docker-compose类似,它也可以通过yml的将一组service放在一起操作,docker stack命令可以方便地操作一个Stack,而不用一个个地操作Service」

默认情况下,一个Stack共用一个Network,相互可访问,与其它Stack网络隔绝

下面还是以上面的nginx集群为例,通过docker stack 来构建集群

  • 「编写docker-stack.yml文件」

    docker stack 文件的语法基本与docker-compose类似,

    #版本写高一点,不支持 1 2
    version: '3'
    services:
    edwin-nginx:
    image: nginx:1.19.3-alpine
    container_name: edwin-nginx
    # 指定一个网络
    networks:
    - edwin-net
    restart: always
    ports:
    - 80:80
    deploy:
    replicas: 7
    # 创建nginx网络 networks中也可以不指定driver:overlay,因为docker swarm默认网络类型是overlay。
    networks:
    edwin-net:
    driver: overlay

  • 「上传docker-stack.yml」

    将docker-stack.yml上传到manager节点的/data/nginx目录下

  • 「启动镜像」

    在manager节点中创建docker-stack.yml文件。执行如下命令:

    #nginx-stack 是stack的名字
    docker stack deploy nginx-stack --compose-file=docker-stack.yml
    #或者是
    docker stack deploy nginx-stack -c docker-stack.yml

  • 「查看stack服务」

    docker stack services nginx-stack

  • 「查看运行的节点」

    查看7个nginx-stack容器分别运行在哪个节点中,可以通过以下命令

    # 查看service的服务名为:nginx-stack_edwin-nginx
    docker service ls
    #查看7个nginx-stack容器分别运行在哪个节点中
    docker service ps nginx-stack_edwin-nginx

    • 查看的前提是我们要修改各个主机的名字,不然都会显示localhost.localdomain

    • 「修改主机名字」

      # 第一步 在各个主机执行  docker-swarm-work-02 为当前主机要设置的主机名
      hostnamectl set-hostname docker-swarm-manager-01
      #第二步
      vi /etc/hosts
      # 将其中的 localhost.localdomain 替换成 docker-swarm-work-02
      127.0.0.1 localhost docker-swarm-work-02 localhost4 localhost4.localdomain4
      ::1 localhost docker-swarm-work-02 localhost6 localhost6.localdomain6
      #第三步 重启服务器
      reboot
      #第四步 查看hostname
      hostname

    • 分别按照上述步骤修改主机名字后,再次查看查看7个nginx-stack容器分别运行在哪个节点中,结果如下

  • 「删除stack服务」

    docker stack rm nginx-stack

6.2 docker-stack命令汇总

命令描述
docker stack deploy部署新的stack或更新现有stack
docker stack ls列出现有stack
docker stack ps列出stack中的任务
docker stack rm删除一个或多个stack
docker stack services列出stack中的服务

6.2 Docker Stack和Docker Compose区别

  • Docker stack没有构建指令,无法使用stack命令构建新镜像,需要镜像是预先准备镜像。 docker-compose可以直接构建镜像,所以docker-compose更适合于开发场景;
  • Docker Compose是Python写的,需要安装,Docker Stack是swarm mode的一部分,包含在Docker引擎中
  • Docker stack 不支持version版本为3以下的yml
  • Docker stack 的功能基本上包含了docker compose。

七、Docker-Task

Task是 Swarm 集群中的最小的调度单位,任务包含一个Docker容器和在容器内运行的命令,如果某一个任务奔溃,那么协调器将创建一个新的副本任务,该任务将生成一个新的容器。

「Task调度主要分为Manager节点的任务分配和Worker节点的任务执行两部分」

  • 「Manager节点的任务分配」
    • 通过 Docker Engine Client 在manage节点使用命令 docker service create 提交 Service 定义
    • Manager节点根据定义创建相应的 Task,并分配IP地址
    • 将Task分发到对应的节点上
    • 节点进行相应的初始化使得它可以执行Task
  • 「Worker节点的任务执行」
    • 连接Manager节点的分配器检查该Task相关定义的信息
    • 验证通过以后在 Worker 节点上执行Task

Task 的执行是一种单向机制,它会按顺序的依次经历 assigned, prepared 和 running 等执行状态,如果Task执行失败了,Manager的编排器会直接将该 Task 以及它的 Container 给删除掉,然后在其它节点上另外创建并执行该 Task




文章转载自星河之码,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论