Docker Swarm 集群安装教程及跨主机网络访问的问题
环境说明
约定
本次安装准备至少3个节点若现场环境资源充足可准备多个节点,在部署安装前应先规划IP信息,为节点确定一个固定的IP,本文档默认以最小配置为前提,以下均使用3节点进行说明。
操作系统
Ubuntu 24.04 server 最小化安装
最低配置要求
3个节点 CPU 不低于16C,内存不低于64GB,存储不低于1TB
节点名称应在安装系统时指定
名称分别为 helionsvc-1 helionsvc-2 helionsvc-3
基础准备(本章节操作在所有节点执行)
# 设置 root 密码
sudo passwd root
# 安装vim
sudo apt install -y vim
安装Docker组件
#!/bin/bash
# 平台安装脚本
#
# @date 2024年8月5日
# @author ch
####################
# 卸载Docker旧版本
sudo apt-get remove -y docker-buildx-plugin
sudo apt-get remove -y docker-ce
sudo apt-get remove -y docker-ce-cli
sudo apt-get remove -y docker-ce-rootless-extras
sudo apt-get remove -y docker-compose-plugin
# 安装脚本
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -y -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
# 设置加速地址
sudo mkdir -p /etc/docker
sudo mkdir -p /home/docker-data
sudo tee /etc/docker/daemon.json <<EOF
{
"data-root": "/home/docker-data",
"registry-mirrors": ["https://w5qs80cb.mirror.aliyuncs.com"],
"log-driver": "json-file",
"log-opts": {
"cache-disabled": "false",
"cache-max-file": "5",
"cache-max-size": "20m",
"cache-compress": "true",
"env": "os,customer",
"labels": "somelabel",
"max-file": "5",
"max-size": "10m"
}
}
EOF
# 安装 docker
VERSION_STRING=5:27.1.1-1~ubuntu.24.04~noble
sudo apt-get install -y docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl daemon-reload
# 设置Dockers自启动
sudo systemctl enable docker
# 启动 Docker
sudo systemctl restart docker
# 将用户加入docker组 并且修改权限
sudo usermod -aG docker helionsvc
sudo sed -i 's/0660/6666/' /usr/lib/systemd/system/docker.socket
sudo cat /usr/lib/systemd/system/docker.socket
# 设置时区为上海
sudo timedatectl set-timezone "Asia/Shanghai"
将当前用户添加 Docker 权限(非Root用户)
sudo usermod -aG docker $USER
修改Hosts文件
xxx.xx.x.xx 应为现场真实IP
sudo tee -a /etc/hosts <<-'EOF'
xxx.xxx.x.xx helionsvc-1
xxx.xxx.x.xx helionsvc-2
xxx.xxx.x.xx helionsvc-3
EOF
构建Swarm集群
创建集群(主节点执行)
创建集群,当网卡有多个IP的时候需要指定–advertise-addr 参数来明确使用那个ip进行广播,为防止端口占用导致后续容器网络出现问题,此处使用 --data-path-port 来指定一个端口,可根据实际情况来更改这个端口本文默认为5000
docker swarm init --data-path-port 5000 --advertise-addr xxx.xxx.x.xxx
当集群创建完成后会输出其他节点加入集群的命令,请将该命令妥善保管
工作节点加入集群(在所有工作节点上依次执行)
查看集群情况
docker node ls
结果如下图所示
当能够查看到所有工作节点后即代表集群已经搭建完成
创建网络
仅在主节点执行
docker network create --driver overlay --attachable --subnet 10.10.10.0/24 --gateway 10.10.10.254 helionsvc-network
部署应用
部署脚本
#!/usr/bin/env bash
compose_file=$1
# 如果没有传递文件参数则结束
if [ ! -n "$1" ]; then
echo -e "\e[31mMisses compose file name\e[0m"
else
# 从传递的文件来获取 stack 名称
stack=`echo $compose_file | awk '{split($1,arr,"-"); print arr[1]}'`
# execute as a subcommand in order to avoid the variables remain set
(
# export variables excluding comments
[ -f .env ] && export $(sed '/^#/d' .env)
# Use dsd your_stack your_compose_file to override the defaults
echo 'exec: docker stack deploy --detach=true -c '$compose_file' '$stack
docker stack deploy --with-registry-auth --detach=true -c $compose_file $stack
)
fi
测试用的yaml文件
version: "3.8"
services:
gateway:
image: nginx:latest
ports:
- target: 8088
published: 80
protocol: tcp
mode: host
networks:
- helionsvc-network
healthcheck:
test: [ "CMD","curl","http://localhost:80" ]
interval: 20s
timeout: 10s
retries: 3
deploy:
replicas: 1
placement:
constraints:
- "node.role==manager"
redis:
image: redis:6.2.14-alpine
volumes:
- /home/helionsvc/data/redis:/data
- ./conf/redis.conf:/etc/redis/redis.conf
networks:
- helionsvc-network
ports:
- "6379:6379"
command: "redis-server /etc/redis/redis.conf"
deploy:
replicas: 1
placement:
constraints:
- "node.role==manager"
networks:
helionsvc-network:
external: true
部署
sh deploy.sh test-stack.yaml
注意事项(重点)
默认docker stack deploy 会将容器全部加入一个 内部网络 ingress 这个网络无法提供跨主机容器访问,比如我在多个stack 中 A stack 提供数据库的功能 B stack 是应用想要访问A stack 不在一个主机是无法访问的,此时我需要创建一个新的网络来解决这个问题,在这种情况下,我如果还希望 A stack 中的服务对外提供端口 就不能用短命令
ports:
- "6379:6379"
来指定了必须改为完整的,并且指定mode
ports:
- target: 8088
published: 80
protocol: tcp
mode: host