Docker Swarm集群的深度总结

2023-12-20 17:04:29

swarm集群操作命令

TCP协议端口 2377 :集群管理端口
TCP协议端口 7946 :节点之间通讯端口(不开放则会负载均衡失效)
UDP协议端口 4789 :overlay网络通讯端口

1.防火墙关闭

查看firewalld防火墙状态
systemctl status firewalld
查看所有打开的端口 
firewall-cmd --zone=public --list-ports
防火墙开放端口(更新firewalld防火墙规则后生效)
firewall-cmd --zone=public --add-port=要开放的端口/tcp --permanent
选项:
–zone 				# 作用域
–add-port=80/tcp 	# 添加端口,格式为:端口/通讯协议
–permanent 			#永久生效,没有此参数重启后失效
示例:
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewalld防火墙关闭接口(更新firewalld防火墙规则后生效)
firewall-cmd --zone=public --remove-port=要关闭的端口/tcp --permanent
更新firewalld防火墙规则(并不中断用户连接,即不丢失状态信息)
firewall-cmd --reload
启动firewalld防火墙
systemctl start firewalld
关闭firewalld防火墙:
systemctl stop firewalld
开机禁用firewalld防火墙
systemctl disable firewalld
开机启用firewalld防火墙: 
systemctl enable firewalld

2.集群相关

2.1.管理集群

2.1.1.初始化Swarm

如果主机有多个网卡,拥有多个IP,必须使用 --advertise-addr 指定 IP。

docker swarm init --advertise-addr 192.168.50.43

查看swarm的情况

docker info

默认CA证书只有3个月的有效期

CA Configuration:
   Expiry Duration: 3 months
   Force Rotate: 0

在swarm管理节点执行这两个命令(延长99年)

docker swarm update --cert-expiry 867240h0m0s
docker swarm ca --rotate | openssl x509 -text -noout

更新 swarm 集群的配置

docker swarm update [OPTIONS]
选项:
    --autolock							# 更改管理器自动锁定设置(true|false)
    --cert-expiry duration         		# 节点证书有效期(ns|us|ms|s|m|h)(默认为2160h0m0s)
    --dispatcher-heartbeat duration		# 调度程序心跳周期(ns|us|ms|s|m|h)(默认为5s)
2.1.2.卸载Swarm

若想解散整个集群,则需先移除所有work-node节点主机,然后所有管理节点也退出集群

移除一个work-node节点主机的完整步骤:

1.在管理节点上操作,清空work-node节点的容器。id 可以使用命令 docker node ls 查看
docker node update --availability drain [id]
2.在work-node节点主机上操作,退出集群
docker swarm leave --force
3.在管理节点上操作,删除work-node节点
docker node rm [id]

移除该节点是manager节点,在移除之前,必须首先降级为worker节点。

将manager降级为worker
docker node demote [id]
2.1.3.加入节点
获取加入swarm集群管理节点的token
docker swarm join-token manager
返回:
To add a manager to this swarm, run the following command:

	docker swarm join --token SWMTKN-1-0xx4ofwfzox9uoezmb6gwcyxa5reo2sucm8f0teh60o7zyajhr-1tnuudlgifis931ou9y3l1r4c 192.168.50.43:2377

获取加入swarm集群工作节点的token
docker swarm join-token worker

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

    docker swarm join --token SWMTKN-1-0xx4ofwfzox9uoezmb6gwcyxa5reo2sucm8f0teh60o7zyajhr-bm0jav650avvrzvqaxbd0bwsl 192.168.50.43:2377

2.2.管理集群节点(docker node)

2.2.1.查看集群中的节点
docker node ls
选项:
    -f, --filter filter   	# 根据所提供的条件过滤输出。(格式:key=value)
    -q, --quiet				# 只显示id
2.2.2.查看运行的一个或多个及节点任务数

默认当前节点

docker node ps [OPTIONS] [NODE...]
选项:
    -f, --filter filter   	# 根据所提供的条件过滤输出
    -q, --quiet				# 只显示id
2.2.3.将worker角色升级为manager
docker node promote NODE [NODE...]
2.2.4.将manager角色降级为worker
docker node demote NODE [NODE...]
2.2.5.查看节点的详细信息

默认json格式,也可以平铺方式–pretty

docker node inspect 主机名
2.2.6.从swarm中强制删除一个节点
docker node rm -f 主机名

2.3.服务管理(docker service)

2.3.1.列出服务列表
docker service ls
2.3.2.列出服务任务信息
docker service ps [OPTIONS] SERVICE [SERVICE...]
选项:
	--no-trunc			# 显示完整的信息
    -f, --filter filter   	# 根据所提供的条件过滤输出。过滤只运行的任务信	息:"desired-state=running"
    -q, --quiet				# 只显示任务id
2.3.3.查看服务日志输出
docker service logs [OPTIONS] SERVICE|TASK
选项:
	--details        # 显示提供给日志的额外细节
    -f, --follow         # 跟踪日志输出
        --since string   # 显示自时间戳 (2013-01-02T13:23:37Z) 或相对时间戳 (42m for 42 minutes) 以来的日志
    -n, --tail string    # 从日志末尾显示的行数(默认为“all”)
    -t, --timestamps     # 显示时间戳
2.3.4.更新服务的相关配置
docker service update [options] 服务名
选项
    --args "指令"			# 容器加入指令
    --image IMAGE		 # 更新服务容器镜像
    --rollback				# 回滚服务容器版本
    --network-add 网络名	  # 添加容器网络
    --network-rm 网络名	  # 删除容器网络
    --reserve-cpu int			# 更新分配的cpu
    --reserve-memory bytes		# 更新分配的内存(示例:512m)
    --publish-add 暴露端口:容器端口		# 映射容器端口到主机
    --publish-rm 暴露端口:容器端口		# 移除暴露端口
    --endpoint-mode dnsrr		 # 修改负载均衡模式为dnsrr
    --force						 # 强制重启服务
    --config-rm 配置文件名称		 # 删除配置文件
    --constraint-add list		 # 新增一个约束 
    --constraint-rm list		 # 移除一个约束 
    --placement-pref-add pref	 # 新增一个偏好 
    --placement-pref-rm pref	 # 移除一个偏好
    --config-add 配置文件名,target=/../容器内配置文件名
2.3.5.查看服务详细信息

默认json格式,也可以平铺方式–pretty

docker service inspect [OPTIONS] 服务名 [SERVICE...]
2.3.6. 删除服务
docker service rm [OPTIONS] 服务名 [SERVICE...]
2.3.7. 缩容扩容服务容器副本数量
docker service scale 服务名=副本数 [SERVICE=REPLICAS...]
2.3.8. 服务创建
docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]
选项:
    --name string			# 指定容器名称
    --replicas int			# 指定副本数
    --network 网络名		  # 添加网络组
    --mode string			# 服务模式(复制或全局)(replicated | global)
    --reserve-cpu int		# 预留的cpu
    --reserve-memory bytes	# 预留的内存(512m)
    --limit-cpu	int			# 限制CPU
    --limit-memory bytes	# 限制内存(512m)
    -l,	--label list			# 服务的标签(key=value)
    --container-label list		# 容器标签(key=value)
    -p, --publish 暴露端口:容器端口	  # 映射容器端口到主机
    -e,	--env MYVAR=myvalue			# 配置环境变量
    -w,	--workdir string			# 指定工作目录(示例:/tmp)
    -restart-condition string		# 满足条件时重新启动(no | always | on-failure | unless-stopped)
    --restart-delay duration		# 重新启动尝试之间的延迟 (ns/us/ms/s/m/h)
    --restart-max-attempts int		# 放弃前的最大重启次数
    --restart-window duration			# 用于评估重启策略的窗口 (ns/us/ms/s/m/h)
    --stop-grace-period duration		# 强制杀死容器前的等待时间 (ns/us/ms/s/m/h)
    --update-delay duration				# 更新之间的延迟(ns/us/ms/s/m/h)(默认 0s)
    --update-failure-action	string		# 更新失败的操作("pause"停止|"continue"继续)(默认pause)
    --update-max-failure-ratio float	# 更新期间容忍的失败率
    --update-monitor duration			# 每次任务更新后监控失败的持续时间(ns/us/ms/s/m/h)(默认 0s)
    --update-parallelism int			# 同时更新的最大任务数(0表示一次更新全部任务)(默认为1)  
    --endpoint-mode string				# 负载均衡模式(vip or dnsrr) (默认 "vip")
    --rollback-monitor 20s		  	    # 每次容器与容器之间的回滚时间间隔
    --rollback-max-failure-ratio .数值	# 回滚故障率如果小于百分比允许运行(“.2”为%20)
    --mount type=volume,src=volume名称,dst=容器目录	 # 创建volume类型数据卷
    --mount type=bind,src=宿主目录,dst=容器目录			# 创建bind读写目录挂载
    --mount type=bind,src=宿主目录,dst=容器目录,readonly	 # 创建bind只读目录挂载
    --config source=docker配置文件,target=配置文件路径		# 创建docker配置文件到容器本地目录

2.4.管理配置文件(docker config)

2.4.1. 查看已创建配置文件
docker config ls [OPTIONS]
选项:
    -f, --filter filter   	# 根据所提供的条件过滤输出
    -q, --quiet				# 只显示id
2.4.2. 查看配置详细信息
docker config inspect 配置文件名
2.4.3. 删除配置
docker config rm CONFIG [CONFIG...]
2.4.4. 创建配置文件
docker config create 配置文件名 本地配置文件

# 示例:新建配置文件并添加新配置文件到服务
# 1.创建配置文件
docker config create nginx2_config nginx2.conf 
# 2.删除旧配置文件
docker service update --config-rm ce_nginx_config 服务名
# 3.添加新配置文件到服务
docker service update --config-add src=nginx2_config,target=/etc/nginx/nginx.conf ce_nginx

2.5.管理网络(docker network)

2.5.1. 查看集群网络列表
docker network ls
2.5.2. 将容器连接到集群网络中
docker network connect [OPTIONS] NETWORK CONTAINER
选项
    --alias strings				# 为容器添加网络范围的别名
    --driver-opt string		·	# 指定网络驱动程序
    --ip string					# 指定IPv4地址(如172.30.100.104)
    --ip6 string				# 指定IPv6地址(例如,2001:db8::33)
    --link list					# 添加到另一个容器的链接
    --link-local-ip string		# 为容器添加一个链接本地地址
示例
docker network connect mynet nginx
2.5.3. 断开一个容器与集群网络的连接
docker network disconnect [OPTIONS] NETWORK CONTAINER
选项
	-f, --force		# 强制容器从网络断开连接  
2.5.4. 显示一个或多个集群网络的详细信息
docker network inspect [OPTIONS] NETWORK [NETWORK...]
选项
  -f, --format string   # 使用给定的Go模板格式化输出
  -v, --verbose         # 输出详细的诊断信息
2.5.5. 创建一个集群网络
docker network create [OPTIONS] NETWORK
选项
      --attachable           # 准许手动容器连接
      --aux-address map      # 网络驱动使用的辅助IPv4或IPv6地址(默认映射[])
      --config-from string   # 要从其中复制配置的网络
      --config-only          # 创建仅配置网络
  -d, --driver string        # 管理网络的驱动程序(默认为“"bridge”)。选项:bridge、overlay、macvlan
      --gateway strings      # 指定IPv4或IPv6主子网网关。示例:172.20.0.1
      --ingress              # 创建群路由-网格网络
      --internal             # 限制外部访问网络
      --ip-range strings     # 从子范围分配容器ip
      --ipam-driver string   # IP管理驱动(默认为“default”)
      --ipam-opt map         # 设置IPAM驱动程序的特定选项(默认map[])
      --ipv6                 # 启用IPv6网络
      --label list           # 在网络中设置元数据
  -o, --opt map              # 设置驱动程序特定选项(默认map[])
      --scope string         # 控制网络的范围
      --subnet strings       # 指定一个CIDR格式的网段。示例:172.20.0.0/24
示例:
docker network create -d overlay --attachable apps_net
2.5.6. 移除所有未使用的集群网络
docker network prune [OPTIONS]
选项
      --filter filter   # 提供过滤值(e.g. 'until=<timestamp>') 
  -f, --force           # 强制,没有提示确认
2.5.7. 删除一个或多个集群网络
docker network rm NETWORK [NETWORK...]
# 别名:rm, remove

2.6.管理敏感数据存储

2.6.1. 查看敏感数据卷列表
docker secret ls
2.6.2. 显示一个或多个敏感数据卷的详细信息
docker secret inspect [OPTIONS] SECRET [SECRET...]
选项
	--pretty		# 易读的格式打印信息
2.6.3. 从文件或标准输入创建一个敏感数据卷作为内容
docker secret create [OPTIONS] SECRET [file|-]
选项
  -d, --driver string            # 指定驱动
  -l, --label list               # 指定标签
      --template-driver string   # 指定模板驱动程序
2.6.4. 移除一个或多个敏感数据卷
docker secret rm SECRET [SECRET...]
别名:rm, remove

3.nfs 数据共享存储

NFS(Network File System)即网络文件系统,它允许网络中的计算机之间通过TCP/IP网络共享资源。
在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样

3.1.nfs安装

所有节点安装NFS,包括服务端和客户端

yum -y install nfs-utils

所有节点做域名和IP的映射

192.168.119.21 manager21
192.168.119.22 worker22
192.168.119.23 worker23

3.2.NFS服务器端,开启NFS服务

192.168.119.21作为NFS服务端

systemctl enable nfs
systemctl start nfs

创建NFS的目录

mkdir /root/nfs

编辑NFS配置文件

vi /etc/exports

输入以下内容:
/root/nfs *(rw,sync,no_root_squash)

参数说明:
    /root/nfs : 共享的目录
    * : 可以访问的主机网段,星号表示所有网段。
    rw : 可读写权限,只读权限ro
    sync : 同步,数据更安全,速度慢
    async : 异步,速度快,效率高,安全性低
    no_root_squash :NFS 服务共享的目录的属性, 如果用户是root, 对这个目录就有root的权限

重启NFS

systemctl restart nfs

3.3.启动NFS客户端

systemctl start rpcbind

测试挂载nfs共享目录

mkdir /root/nfs
mount -t nfs manager21:/root/nfs /root/nfs

其中:manager21为NFS服务器的地址

卸载NFS目录

umount /root/nfs

4.Swam和nfs的集成

除了 NFS 共享存储外,还有 Ceph、ClusterFS 等存储也能实现

4.1.Docker Volume模式

缺点:每个 swarm 节点均创建相同名称的 Docker Volume

4.1.1.创建docker volume
docker volume create --driver local \
  --opt type=nfs \
  --opt o=addr=manager21,rw \
  --opt device=:/data/sharedir \
  nfsdata
4.1.2.查看 Volume 是否创建成功
docker volume ls
4.1.3.查看 Volume 详情
docker volume inspect nfsdata
4.1.4.Swarm中使用Volume
docker service create \
  --name nginx-nfs-test \
  --publish 1180:80 \
  --mount type=volume,source=nfsdata,destination=/data/web \
  --replicas 3 \
  nginx:1.20.2

4.2.Docker Stack模式

使用 Docker Stack 方式时,就不需要手动创建 Docker Volume 了

创建编排文件web.yml:

version: '3'
services:
  web:
    image: nginx:latest
    ports:
      - 3010:3010
    volumes:
      - ngxin_data:/usr/share/nginx/html
      - ngxin_config:/etc/nginx/conf.d
    environment:
      - TZ=Asia/Shanghai
    deploy:
      mode: replicated
      replicas: 3
    networks:
      - test_net
volumes:
  ngxin_config:
    driver: local
    driver_opts:
      type: "nfs"
      o: "addr=manager21,rw"
      device: ":/root/nfs/nginx/conf.d"
  ngxin_data:
    driver: local
    driver_opts:
      type: "nfs"
      o: "addr=manager21,rw"
      device: ":/root/nfs/nginx/html"
networks:
  test_net:
    driver: overlay
4.2.1.docker stack启动
docker stack deploy -c web.yml nginx

5.Mongodb数据库高可用

思路:
1.采用docker swarm集群搭建mongo多副本
2.利用docker swarm跨主机overlay网络模式,结合docker-compose文件,搭建mongo主从模式的副本集集群
3.利用docker的overlay网络模式和服务发现consul,结合docker-compose文件,搭建mongo主从模式的副本集集群
4.利用docker的host网络模式,结合docker-compose文件,搭建mongo主从模式的副本集集群

5.1.创建keyfile安全文件

openssl rand -base64 756 > ./mongodb.key

注意该文件要分配用户和用户组,mongodb:mongodb

useradd mongodb
chmod 600 mongodb.key
chown 999 mongodb.key 或者chown mongodb:mongodb mongodb.key

可以进到容器里查看mongo的用户组是多少,执行命令
cat /etc/passwd
返回结果中:mongodb:x:999:999::/home/mongodb
否则不是报Permission denied,就是报文件的权限不能太大,因为mongo会进行效验

5.2.初始化脚本init.sh

#!/usr/bin/env bash
sleep 5

mongo --host mongo_master1:27017 -u admin -p admin << EOF
use admin
db.auth('admin','admin')
const cf = {
  "_id": "omcMongoSet",
  "members":[
     {
       "_id": 0,
       "host": "mongo_master1:27017",
       "priority": 1
     },
     {
       "_id": 1,
       "host": "mongo_slave2:27017",
       "priority": 1
     },
     {
       "_id": 2,
       "host": "mongo_slave3:27017",
       "priority": 1
     }

  ]
}
rs.initiate(cf, { force: true })
rs.slaveOk()
rs.isMaster()
EOF
echo "============================================"

sleep 30

mongo --host mongo_master1:27017 -u admin -p admin << EOF
use admin
db.auth('admin','admin')
use 5g_tr
db.createUser({user:"root",pwd:"Admin100%",roles:[{role:"dbOwner",db:"5g_tr"}]})
EOF
echo "============================================"

DATA_DIR=./data
DB_NAME=5g_tr
USER=root
PWD=Admin100%

for file in $DATA_DIR/*.json; do
  COLLECTION_NAME=$(basename "$file" .json)
  mongoimport --host mongo_master1:27017  --db $DB_NAME --collection $COLLECTION_NAME --type json --file "$file"  -u $USER -p $PWD
done

echo "============================================"

5.3.mongo多副本模式

生成文件mongo.yml

version: '3'
services:
  mongo:
    image: mongo:4.0.20
    command: mongod --serviceExecutor adaptive
    ports:
      - 27017:27017
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=Admin100%
      - MONGO_INITDB_DATABASE=5g_tr
      - TZ=Asia/Shanghai
    volumes:
      - mongo_data:/data/db
      - mongo_init:/docker-entrypoint-initdb.d
    deploy:
      mode: replicated
      replicas: 3
    networks:
      - overlay_net
volumes:
  mongo_data:
    driver: local
    driver_opts:
      type: "nfs"
      o: "addr=manager21,rw"
      device: ":/root/nfs/db/data"
  mongo_init:
    driver: local
    driver_opts:
      type: "nfs"
      o: "addr=manager21,rw"
      device: ":/root/nfs/db/init"
networks:
  overlay_net:
    driver: overlay

5.4.overlay网络+compose模式

5.4.1.调整docker swam集群节点

确保当前集群的所有节点是manager管理节点

这是因为当在管理节点上创建自定义网络的时候,集群默认提供的"ingress"覆盖网络只会同步到manager节点上,而worker节点只有接到任务的时候,swarm集群才会把该网络扩展到该worker节点上,换句话说这个worker节点被swarm调度器分配了运行服务的任务时,才被扩展到自定义网络

worker节点升级成manager节点

docker node promote NODE [NODE...]
5.4.2.自定义overlay跨主机网络
docker network create -d overlay --attachable mongodbs 
5.4.3.编写docker-compose文件

在各个节点上,生成docker-compose.yml文件

version: '3.7'
services:
  mongo_master:
    image: mongo:4.0.20
    volumes:
      - /root/nfs/db/data:/data/db
      - /root/nfs/db/mongodb.key:/data/mongodb.key
      - ./init:/init
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=admin
      - TZ=Asia/Shanghai
    command: mongod --replSet omcMongoSet --keyFile /data/mongodb.key --dbpath /data/db --bind_ip_all --port 27017
    networks:
      - mongodbs
networks:
  mongodbs:
    external: true

结合init.sh脚本文件,执行启停命令

docker-compose up -d
docker-compose down

5.5.host网络+compose模式

在各个节点上,生成docker-compose.yml文件

version: '3.7'
services:
  mongo_master:
    image: mongo:4.0.20
    volumes:
      - /root/nfs/db/data:/data/db
      - /root/nfs/db/mongodb.key:/data/mongodb.key
      - ./init:/init
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=admin
      - TZ=Asia/Shanghai
    command: mongod --replSet omcMongoSet --keyFile /data/mongodb.key --dbpath /data/db --bind_ip_all --port 27017
    network_mode: host

结合init.sh脚本文件,执行启停命令

docker-compose up -d
docker-compose down

6.Docker UI部署

6.1.portainer UI

6.1.1.编排文件编写

生成docker-compose.yml文件

version: '3.7'
services:
  portainer:
    image: 6053537/portainer-ce:latest
    restart: always
    container_name: portainer
    ports:
      - 9000:9000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data:/data
    networks:
      - portainer-net
networks:
  ui-net:
    driver: bridge
6.1.2.访问地址
http://192.168.119.21:9000/

用户名:admin
密码:Admin100%123456

6.2.dockerui UI

6.2.1.编排文件编写

生成docker-compose.yml文件

version: '3.7'
services:
  dockerui:
    image: joinsunsoft/docker.ui:latest
    restart: always
    container_name: dockerui
    ports:
      - 8999:8999
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - iso-net
networks:
  ui-net:
    driver: bridge
6.2.2.访问地址
http://192.168.119.21:8999/

附录

1.节点日志无法查看

报:Error grabbing logs: rpc error: code = Unknown desc = warning: incomplete log stream. some logs could not be retrieved for the following reasons: node xw411xvzxn5sm29dd8u7culla is not available

执行命令:
docker swarm ca --rotate

2.节点rm报错

报:Error response from daemon: rpc error: code = FailedPrecondition desc = node cw5bome4a9g1rzelivxejd31c is a cluster manager and is a member of the raft cluster. It must be demoted to worker before removal

执行命令:
docker node demote cw5bome4a9g1rzelivxejd31c

文章来源:https://blog.csdn.net/weixin_42211693/article/details/135108397
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。