Docker Swarm

Docker Swarm

1、基础环境说明

第一步:启动4个服务器(保证在一个网段内)

192.168.0.111

192.168.0.112

192.168.0.113

192.168.0.114

第二步:命名服务器(方便查看)

第三步:每一个服务器都安装Docker

2、DockerSwarm架构

官网:https://docs.docker.com/engine/swarm/how-swarm-mode-works/nodes/

在这里插入图片描述

3、搭建集群环境

[root@node111 ~]# docker swarm --help

Usage:  docker swarm COMMAND

Manage Swarm

Commands:
  # 初始化节点
  init        Initialize a swarm
  
  # 加入节点
  join        Join a swarm as a node and/or manager

初始化第一个节点

# 暴露第一个节点
[root@node111 ~]# docker swarm init --advertise-addr 192.168.0.111
Swarm initialized: current node (h6cjybqx8m7fqc9vih7z1qcdy) is now a manager.

# 添加工作节点的命令
To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-019i2ettz5yuv6j62eqpwk4ensnmc50fauda6ohd6p0bgkn27b-dzbzn9jzsz9q3zrf6zvdena70 192.168.0.111:2377

# 添加管理节点的命令 docker swarm join-token manager
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

[root@node111 ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-019i2ettz5yuv6j62eqpwk4ensnmc50fauda6ohd6p0bgkn27b-bprv9pj27xgt5hq1m1b4xhguu 192.168.0.111:2377

如果你当前电脑上的docker已经加入了一个swarm集群,先要离开节点

docker swarm leave
docker swarm leave --force

将第二台机器加入节点,Work

[root@node112 ~]# docker swarm join --token SWMTKN-1-019i2ettz5yuv6j62eqpwk4ensnmc50fauda6ohd6p0bgkn27b-dzbzn9jzsz9q3zrf6zvdena70 192.168.0.111:2377
This node joined a swarm as a worker.

第三台机器加入节点,管理节点

[root@node113 ~]# docker swarm join --token SWMTKN-1-019i2ettz5yuv6j62eqpwk4ensnmc50fauda6ohd6p0bgkn27b-bprv9pj27xgt5hq1m1b4xhguu 192.168.0.111:2377
This node joined a swarm as a manager.

第四台同上

[root@node114 ~]# docker swarm join --token SWMTKN-1-019i2ettz5yuv6j62eqpwk4ensnmc50fauda6ohd6p0bgkn27b-bprv9pj27xgt5hq1m1b4xhguu 192.168.0.111:2377
This node joined a swarm as a manager.

查看集群是否搭建成功!

在这里插入图片描述

4、Raft协议

双主双从搭建完毕,但是现在我们只有两个管理节点,如果一个节点挂了,另外一个节点也不能用,Raft一致性算法,确保大多数节点存活才可以用,至少大于 1 台!生产环境最少3 manager

1、先保证有两个管理节点,挂掉其中一台。node ls 命名不可用。

2、如果有work节点离开了,状态会更新为down,不可用了。

3、可以没有Work节点,全是管理节点。

4、leader挂了,就全部都挂掉了。

结论:

Raft保证:至少要保证有两个及两个以上的管理者节点,集群才可以使用,否则直接挂掉。

全部移除,重新初始化才可以再次使用了。

这就是 Raft协议,确保大多数节点存活才可以用!高可用!

5、使用Swarm

docker service

集群、不是单机了 ,告别Docker run

以后告别 docker run!之前docker compose up 使用compose启动一个服务。docker compose是单机下的玩具

现在是集群,要使用:**docker service (使用docker管理服务。)容器升级为服务。**其实和容器一一样,只是集群下变成了服务!

容器:单个容器运行,docker run 流量太大扛不住

服务:多个容器运行,负载均衡。

企业中真实使用的,docker service

demo: nginx

# 单机下docker run   # 集群下  docker service create

[root@node111 ~]# docker service create -p 8888:80 --name my-nginx nginx

# 通过docker service启动服务,在任何服务器都可以访问到该服务,不需要在启动容器的节点中访问。
# 查看服务的详细信息
[root@node111 ~]# docker service inspect --pretty my-nginx

ID:		v3dzdnv1hokey3174ytg7ydbs
Name:		my-nginx
# 副本数量Replicated
Service Mode:	Replicated
 Replicas:	1
Placement:
UpdateConfig:
 Parallelism:	1
 On failure:	pause
 Monitoring Period: 5s
 Max failure ratio: 0
 Update order:      stop-first
RollbackConfig:
 Parallelism:	1
 On failure:	pause
 Monitoring Period: 5s
 Max failure ratio: 0
 Rollback order:    stop-first
ContainerSpec:
 Image:		nginx:latest@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
 Init:		false
Resources:
Endpoint Mode:	vip
Ports:
 PublishedPort = 8888
  Protocol = tcp
  TargetPort = 80
  PublishMode = ingress 

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

一台服务器不够用了,动态扩容。

所有和服务相关的命令 docker service

docker service create --replicas 3 my-nginx

[root@node111 ~]# 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 

回滚!

# 回滚到之前的状态!(当前和上一个来回回滚)
docker service rollback my-nginx

# 灰度发布
# --image nginx:1.18.0-alpine  新的容器镜像
# --update-parallelism 1 同时更新的数量
# --update-delay 10s 
[root@node111 ~]# docker service update --image nginx:1.18.0-alpine --update-parallelism 1 --update-delay 10s my-nginx

Tomcat

# 给服务创建一个专属网络
docker network create -d overlay tomcat-net

# 启动服务 
[root@node111 ~]# docker service create --name tomcat \
> --network tomcat-net \
> -p 8080:8080 \
> --replicas 3 \
> tomcat
yscxmfw6uchsivqrsald8tj11
overall progress: 3 out of 3 tasks 
1/3: running   
2/3: running   
3/3: running   
verify: Service converged 


# 扩缩容
# docker service scale tomcat=5

# 服务删除
#[root@node111 ~]# docker service rm tomcat
tomcat

# 服务一旦移除,所有节点上的容器就自动停止

wordpress

1、创建网络

2、创建 mysql 服务

[root@node111 ~]# docker service create --name mysql --env MYSQL_ROOT_PASSWROD=root --env MYSQL_DATABASE=wordpress --network demo --mount type=volume,source=mysql-data,destination=/var/lib/mysql mysql:5.7.24
# 如果做了数据共享,那么启动多份的话,是可以保证数据不同的。

3、创建 wordpress 服务

[root@node111 ~]# docker service create --name wordpress -p 80:80 --env WORDPRESS_DB_USER=root --env WORDPRESS_DB_PASSWORD=root --env WORDPRESS_DB_HOST=mysql:3306 --env WORDPRESS_DB_NAME=wordpress --network demo wordpress

4、访问测试

说明:服务模式

服务模式一共有两种:Ingress和Host,如果不指定,则默认的是Ingress;

  • Ingress模式(overlay网络)下,到达Swarm任何节点的8080端口的流量,都会映射到任何服务副本的内部80端口,就算该节点上没有tomcat服务副本也会映射;

  • Host模式下,仅在运行有容器副本的机器上开放端口,使用Host模式的命令如下:

    docker service create --name tomcat \
    --network host \
    --publish published=8080,target=8080,mode=host \
    --replicas 2 \
    tomcat:7.0.96-jdk8-openjdk
    

docker service ps tomcat

6、Swarm的一些概念

1.Swarm
集群的管理和编排是使用嵌入docker引擎的SwarmKit,可以在docker初始化时启动swarm模式或者加入已存在的swarm
init
join
2.Node
一个节点是docker引擎集群的一个实例。您还可以将其视为Docker节点。您可以在单个物理计算机或云服务器上运行一个或多个节点,但生产群集部署通常包括分布在多个物理和云计算机上的Docker节点。
要将应用程序部署到swarm,请将服务定义提交给 管理器节点。管理器节点将称为任务的工作单元分派 给工作节点。
Manager节点还执行维护所需群集状态所需的编排和集群管理功能。Manager节点选择单个领导者来执行编排任务。

工作节点接收并执行从管理器节点分派的任务(Task)。默认情况下,管理器节点还将服务作为工作节点运行,但您可以将它们配置为仅运行管理器任务并且是仅管理器节点。代理程序在每个工作程序节点上运行,并报告分配给它的任务。工作节点向管理器节点通知其分配的任务的当前状态,以便管理器可以维持每个工作者的期望状态。
3.Service
一个服务是任务的定义,管理机或工作节点上执行。它是群体系统的中心结构,是用户与群体交互的主要根源。创建服务时,你需要指定要使用的容器镜像。
说明:Docker service 不管镜像的构建的。必须要自己去构建镜像。通过dockerservice启动
4.Task
docker run xxx
任务是在docekr容器中执行的命令,Manager节点根据指定数量的任务副本分配任务给worker节点

在这里插入图片描述

Swarm特点

1. Docker Engine集成集群管理

使用Docker Engine CLI 创建一个Docker Engine的Swarm模式,在集群中部署应用程序服务。链接数以万计的docker节点。

2. 去中心化设计

Swarm角色分为Manager和Worker节点,Manager节点故障不影响应用使用,raft协议原则。

3. 扩容缩容

可以声明每个服务运行的容器数量,通过添加或删除容器数自动调整期望的状态。

4. 期望状态协调

Swarm Manager节点不断监视集群状态,并调整当前状态与期望状态之间的差异。例如,设置一个服务运行10个副本容器,如果两个副本的服务器节点崩溃,Manager将创建两个新的副本替代崩溃的副本。并将新的副本分配到可用的worker节点。

  • 一个节点上在运行3个容器,节点停止,运行,它会在其他节点上拉起这三个容器。

5. 多主机网络

可以为服务指定overlay网络。当初始化或更新应用程序时,Swarm manager会自动为overlay网络上的容器分配IP地址。

6. 服务发现

Swarm manager节点为集群中的每个服务分配唯一的DNS记录和负载均衡VIP。可以通过Swarm内置的DNS服务器查询集群中每个运行的容器。

7. 负载均衡

实现服务副本负载均衡,提供入口访问。也可以将服务入口暴露给外部负载均衡器再次负载均衡。

  • 多个服务,随机访问其中的服务
  • 读取容器的id信息,打印到日志

8. 安全传输

Swarm中的每个节点使用TLS相互验证和加密,确保安全的其他节点通信。

9. 滚动更新

升级时,逐步将应用服务更新到节点,如果出现问题,可以将任务回滚到先前版本。

7、工作模式

Node

在这里插入图片描述

Service

在这里插入图片描述

任务与调度

swarm manager:
    -- 1、API:这个请求直接由Swarm manager的API进行接收,接收命令并创建服务对象。
    -- 2、orchestrator:为服务创建一个任务。
    -- 3、allocater:为这个任务分配IP地址。
    -- 4、dispatcher:将任务分配到指定的节点。
    -- 5、scheduler:在该节点中下发指定命令。
worker node:接收manager任务后去运行这个任务。
    -- 1、container:创建相应的容器。
    -- 2、worker:连接到调度程序以检查分配的任务
    -- 3、executor:执行分配给工作节点的任务

在这里插入图片描述

服务副本与全局服务

在docker swarm中部署的service,有几种类型?

这个问题的答案,非常的简单,2种:

  • replicated(副本)
  • global(全局) ,启动一个服务,会在所有的节点,自动拉起,保证每个节点上都有该容器运行,日志、监控

下面的图表显示了一个有3个副本的service(黄色)和一个global的service(灰色):

在这里插入图片描述

调整service以什么方式运行

--mode string                        
Service mode (replicated or global) (default "replicated")

docker service create --mode replicated --name mytom tomcat:7 默认的

# 副本类型的service,就是你需要部署几个副本,指定一下就可以有几个task在swarm集群中运行

docker service create --mode global --name test alpine ping baidu.com
# 全局类型的service,类似于k8s的daemonset对象,就是在每个节点上都运行一个task,不需要预先指定副本的数量,如果有新的节点加入到集群中,也会自动的在这个节点上运行一个新的task.

补充Label的说明

我们讨论了 Service 部署的两种模式:global mode 和 replicated mode。无论采用 global mode 还是 replicated mode,副本运行在哪些节点都是由 Swarm 决定的,作为用户我们有没有可能精细控制 Service 的运行位置呢?
答:能,使用 label


逻辑分两步:
1、为每个 node 定义 label。
2、设置 service 运行在指定 label 的 node 上。

```shell
docker node update --label-add env=test 节点1
docker node update --label-add env=prod swarm-worker2

# 指定在那个机器上来拉起这个服务。很少用
docker service create \
      --constraint node.labels.env==test \
      --replicas 3 \
      --name my_web \
      --publish 8080:80 \
      httpd
      
#更新 service,将其迁移到生产环境:
docker service update --constraint-rm node.labels.env==test my_web  
docker service update --constraint-add node.labels.env==prod my_web

8、网络概念说明

在 Swarm Service 中有三个重要的网络概念:

  • Overlay networks 管理 Swarm 中 Docker 守护进程间的通信。你可以将服务附加到一个或多个已存在的 overlay 网络上,使得服务与服务之间能够通信
  • ingress network 是一个特殊的 overlay 网络,用于服务节点间的负载均衡:启动多个服务,访问的时候随机分配到一个服务上。当任何 Swarm 节点在发布的端口上接收到请求时,它将该请求交给一个名为 IPVS 的模块。IPVS 跟踪参与该服务的所有IP地址,选择其中的一个,并通过 ingress 网络将请求路由到它。
    初始化或加入 Swarm 集群时会自动创建 ingress 网络,大多数情况下,用户不需要自定义配置,但是 docker 17.05 和更高版本允许你自定义。
  • docker_gwbridge是一种桥接网络,将 overlay 网络(包括 ingress 网络)连接到一个单独的 Docker 守护进程的物理网络。默认情况下,服务正在运行的每个容器都连接到本地 Docker 守护进程主机的 docker_gwbridge 网络。
    docker_gwbridge 网络在初始化或加入 Swarm 时自动创建。大多数情况下,用户不需要自定义配置,但是 Docker 允许自定义。
名称 类型 注释
docker_gwbridge bridge none
ingress overlay none
custom-network overlay none
  • docker_gwbridge和ingress是swarm自动创建的,当用户执行了docker swarm init/connect之后。
  • docker_gwbridge是bridge类型的负责本机container和主机直接的连接。
  • ingress负责service在多个主机container之间的路由。
  • custom-network是用户自己创建的overlay网络,通常我们都需要创建自己的network并把service挂在上面。

ingress网络。vip(虚拟ip模式)

在这里插入图片描述

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

在这里插入图片描述

到这里 Docker 多机通信逻辑及实战就结束了,但 Docker Swarm 只是匆匆过客,最终还是要回到 Kubernetes 上。

上一篇:go 实现websocket以及详细设计流程过程,确保通俗易懂


下一篇:golang笔记-流程控制