Docker Swarm

Docker Swarm

在单机容器排布中,我们定义容器启动顺序,和一件启动,采用了Docker Compose,如果是生产环境多机器部署,我们需要用到Docker Swarm ,下面请看官网描述:

  • 集群模式是管理 Docker 守护进程集群的高级功能
  • 如果您打算将 Swarm 用作生产运行时环境,请使用 Swarm 模式
  • 如果您不打算使用 Swarm 进行部署,请改用 Docker Compose

Docker Swarm的先决条件

你必须要有docker,如果已经运行了Docker Swarm 输入命令docker system info 查看信息

如果没有运行 需要初始化Swarm集群 docker swarm init

Swarm 服务和Kubernetes 服务

这两个编排器对"服务"一词的定义截然不同。在 Swarm 中,服务同时提供调度和网络功能,负责创建容器并提供将流量路由到这些容器的工具。而在 Kubernetes 中,调度和网络功能是分开处理的,部署(或其他控制器)负责将容器调度为 Pod,而服务仅负责为这些 Pod 添加网络功能

创建和加入Swarm集群

所有机器都可通过网络通信,并都安装了Docker引擎 端口设置
必须启用以下端口。在某些系统中,这些端口默认是开放的

  • 2377用于与管理节点通信的 TCP端口
  • 7946用于覆盖网络节点发现的 TCP/UDP端口
  • 4789用于覆盖网络流量的 UDP端口(可配置)

端口4789是 Swarm 数据路径端口(也称为 VXLAN 端口)的默认值。务必阻止任何不受信任的流量到达此端口,因为 VXLAN 不提供身份验证。此端口只能对受信任的网络开放,切勿在边界防火墙上开放

bash 复制代码
# 临时关闭防火墙(测试环境)
systemctl stop firewalld
# 生产环境推荐开放指定端口(2377集群管理、7946节点通信、4789网络通信)
firewall-cmd --permanent --add-port=2377/tcp
firewall-cmd --permanent --add-port=7946/tcp
firewall-cmd --permanent --add-port=7946/udp
firewall-cmd --permanent --add-port=4789/udp
firewall-cmd --reload

--advertise-addr标志将管理节点配置为发布其地址IP。集群中的其他节点必须能够通过该 IP 地址访问管理节点

bash 复制代码
docker swarm init --advertise-addr <MANAGER-IP>

## 输出信息有加入本集群的token
docker swarm init --advertise-addr 192.168.99.100
Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager.

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

    docker swarm join \
    --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
    192.168.99.100:2377

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

此时查看node情况,会出现已经准备好的Manager 节点信息

bash 复制代码
docker node ls

ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
dxn1zf6l61qsb1josjja83ngz *  manager1  Ready   Active        Leader

加入Swarm集群

在另一台工作机器上输入join --token命令即可加入Swarm集群,集群中的manager和worker可以指定,也可以修改升级或者降级

bash 复制代码
docker swarm join \
  --token  SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
  192.168.99.100:2377

This node joined a swarm as a worker.

Docker Swarm 部署服务

  • docker service create命令用于创建服务。
  • --name标志用于指定服务helloworld
  • --replicas标志指定 1 个正在运行的实例的期望状态。
  • 这些参数alpine ping docker.com将服务定义为执行命令的 Alpine Linux 容器ping docker.com
bash 复制代码
docker service create --replicas 1 --name helloworld alpine ping docker.com

9uk4639qpg7npwf3fn2aasksr

运行docker service ls以下命令查看正在运行的服务列表,如果我们集群只有三台机器,但是我指定的副本是4个,也可以,会随机分配,并不一定是一台机器一个

bash 复制代码
docker service ls

ID            NAME        SCALE  IMAGE   COMMAND
9uk4639qpg7n  helloworld  1/1    alpine  ping docker.com

运行docker service inspect --pretty <SERVICE-ID>以显示有关服务的详细信息

如果要以 json 格式返回服务详细信息,请运行不带--pretty标志的相同命令

bash 复制代码
[manager1]$ docker service inspect --pretty helloworld

ID:		9uk4639qpg7npwf3fn2aasksr
Name:		helloworld
Service Mode:	REPLICATED
 Replicas:		1
Placement:
UpdateConfig:
 Parallelism:	1
ContainerSpec:
 Image:		alpine
 Args:	ping docker.com
Resources:
Endpoint Mode:  vip

运行以下命令docker service ps <SERVICE-ID>查看哪些节点正在运行该服务

bash 复制代码
[manager1]$ docker service ps helloworld

NAME                                    IMAGE   NODE     DESIRED STATE  CURRENT STATE           ERROR               PORTS
helloworld.1.8p1vev3fq5zm0mi8g0as41w35  alpine  worker2  Running        Running 3 minutes

在集群中扩展服务

docker service scale <SERVICE-ID>=<NUMBER-OF-TASKS>

bash 复制代码
docker service scale helloworld=5

helloworld scaled to 5

在集群中删除服务

bash 复制代码
docker service rm helloworld

helloworld

服务滚动更新

部署一个基于 Redis 7.4.0 容器镜像的服务。然后,将使用滚动更新的方式将该服务升级到 Redis 7.4.1 容器镜像
--update-delay标志位用于配置服务任务或任务集更新之间的延迟时间

bash 复制代码
docker service create \
  --replicas 3 \
  --name redis \
  --update-delay 10s \
  redis:7.4.0

0u6a4s31ybk7yw2wyvtikmu50

发布服务端口

创建服务时,可以使用该--publish标志发布端口。` --port`target 用于指定容器内部的端口,` published--bind` 用于指定路由网格上绑定的端口。如果省略端口published ,则每个服务任务都会绑定一个随机的高位端口

eg:将 nginx 容器中的 80 端口发布到 swarm 集群中任何节点的 8080 端口

bash 复制代码
docker service create \
  --name my-web \
  --publish published=8080,target=80 \
  --replicas 2 \
  nginx

绕过路由网格

默认情况下,发布端口的 Swarm 服务会使用路由网格。当您连接到任何 Swarm 节点上发布的端口时(无论该节点是否运行特定服务),您都会被透明地重定向到运行该服务的工作节点。实际上,Docker 充当了 Swarm 服务的负载均衡器

要绕过路由网格,必须使用长--publish服务并设置mode`--password` 参数host。如果省略该mode参数或将其设置为 `--password` ingress,则会使用路由网格

bash 复制代码
docker service create --name dns-cache \
  --publish published=53,target=53,protocol=udp,mode=host \
  --mode global \
  dns-cache

overlay网络

Docker集群会产生两种不同的流量:

  • 控制和管理平面流量:这包括集群管理消息,例如加入或离开集群的请求。此类流量始终加密。

  • 应用数据平面流量:包括容器流量以及与外部客户端之间的流量。

当您初始化一个集群或将 Docker 主机加入现有集群时,会在该 Docker 主机上创建两个新网络:

  • 一个名为 `<overlay_network>` 的覆盖网络ingress,用于处理与 Swarm 服务相关的控制和数据流量。当您创建 Swarm 服务但未将其连接到用户定义的覆盖网络时,它ingress 默认连接到该网络。
  • 一个名为 的桥接网络docker_gwbridge,它将各个 Docker 守护进程连接到参与集群的其他守护进程

创建覆盖网络

在Manager 节点创建网络

创建名为 test-network 的overlay网络(自定义网络名可修改)

  • --driver overlay:指定网络类型为 overlay,这是 Swarm 集群跨节点通信的唯一支持类型;
  • --attachable:允许手动创建的容器(非 Swarm Service)也能加入该网络,提升灵活性;
  • think-big-network:自定义网络名称,后续部署服务时需引用该名称
bash 复制代码
docker network create --driver overlay --attachable test-network

验证网络是否创建成功,在Manager节点上执行

bash 复制代码
docker network ls | grep test-network

部署服务指定ip和网络(用主机名约束更加稳妥

bash 复制代码
# 方式1:用IP约束部署
docker service create \
  --name redis-service \
  --network test-network \  # 加入自定义网络
  --constraint node.ip==10.19.1.2 \  # 强制部署到10.19.1.2
  --publish 6379:6379 \  # 端口映射
  --replicas 1 \  # 单副本
  redis:latest  # 镜像名

# 方式2:用主机名约束(替换为10.19.1.2的实际主机名,如redis-node)
# docker service create \
#   --name redis-service \
#   --network test-network \
#   --constraint node.hostname==redis-node \
#   --publish 6379:6379 \
#   --replicas 1 \
#   redis:latest

数据持久化,例如Mysql(--mount)

bash 复制代码
# 部署MySQL时添加数据挂载
docker service create \
  --name db-service \
  --network think-big-network \
  --constraint node.ip==10.19.3.1 \
  --publish 3306:3306 \
  --replicas 1 \
  --env MYSQL_ROOT_PASSWORD=123456 \
  --mount type=bind,src=/home/ubuntu/mysql/data,dst=/var/lib/mysql \  # 数据持久化挂载
  mysql:8.0

验证网络通信(直接用服务名,overlay网络自动解析

bash 复制代码
# 进入app-service容器
docker exec -it $(docker ps | grep app-service | awk '{print $1}') /bin/bash
# ping Redis服务(直接用服务名,overlay网络自动解析)
ping redis-service
# ping 数据库服务
ping db-service
# ping MinIO服务
ping minio-service
相关推荐
阿洛学长2 小时前
解决服务器 4000端口占用方案
运维·服务器
stella·2 小时前
服务器割接,我所学习到的内容。
linux·运维·服务器·学习·shell·割接
胡萝卜3.02 小时前
Linux包管理器:高效安装软件的秘诀
linux·运维·服务器·人工智能·linux包管理·yum教程·apt入门
I · T · LUCKYBOOM2 小时前
iptables 防火墙(二)
linux·运维·服务器·网络·安全·centos
带鱼吃猫2 小时前
Linux 守护进程:会话、终端与后台运行的底层逻辑
linux·运维·服务器
FOREVER-Q2 小时前
《Docker Compose 部署前后端分离项目实战:Nginx + Spring Boot(含完整踩坑记录)》
运维·docker·容器
广东大榕树信息科技有限公司2 小时前
当机房环境出现异常时,如何利用动环监控系统快速定位问题?
运维·网络·物联网·国产动环监控系统·动环监控系统
Trouvaille ~2 小时前
【C++篇】让错误被温柔对待(上):异常基础与核心机制
运维·开发语言·c++·后端·异常·基础入门·优雅编程
科学熊2 小时前
kubekey安装工具快速安装k8s集群
云原生·容器·kubernetes