使用Docker Swarm Overlay网络实现跨宿主机容器互通
背景
在Java微服务架构中,当Nacos作为配置中心时,容器默认使用Docker内网IP进行服务注册,这会导致跨宿主机的服务无法正常发现。为解决此问题,需要构建跨主机的容器网络。
前置条件
1. 宿主机防火墙端口配置
Swarm集群需要开放以下端口以确保节点间正常通信:
- 2377/tcp:集群管理端口,用于Manager与Worker节点间的任务调度和集群状态维护。
- 2375/tcp:Docker API通信端口,通常仅在Manager节点开启。
- 2376/tcp:TLS加密版Docker API端口。
- 4789/udp:VXLAN隧道端口,overlay网络跨节点通信的核心。
- 7946/tcp + 7946/udp:节点发现与心跳保活,用于Raft协议集群状态同步。
2. Docker版本要求
Swarm模式自Docker 1.12起集成到Docker引擎中,因此版本必须高于1.12。本方案使用Docker 27.1.1(Ubuntu 22.04环境)。
Docker安装(阿里源)
# 添加GPG密钥
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 配置阿里源仓库
sudo sh -c 'echo "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list'
# 安装并验证
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
sudo systemctl status docker
docker --version
Swarm集群搭建
Manager节点初始化
docker swarm init --advertise-addr=192.168.0.1
# 输出示例:
# Swarm initialized: current node (maw28ll7mlxuwp47z5c5vo2v1) is now a manager.
# To add a worker to this swarm, run the following command:
# docker swarm join --token SWMTKN-xxxxxxxx 192.168.0.1:2377
Worker节点加入集群
# 执行Manager节点输出的join命令
docker swarm join --token SWMTKN-xxxxxxxx 192.168.0.1:2377
# 若需离开集群:docker swarm leave
验证节点状态
root@ubuntu22:~# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
7r4vvml8kd2jem850rqfl158h * ubuntu22 Ready Active Leader 27.1.1
lrvsq6quwaxleqejf0w1nawvu ubuntu22 Ready Active 27.1.1
u4v4os8zats4ro795a4l6lw3y ubuntu22 Ready Active 27.1.1
创建Overlay网络
# 必须使用 --attachable 参数,否则docker-compose无法引用该网络
docker network create -d overlay --attachable test
# 查看网络列表
root@ubuntu22:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
c2147e916c72 docker_gwbridge bridge local
7jczo6vw7mig test overlay swarm
ypqnzuafqukz ingress overlay swarm
激活Overlay网络(使所有节点可见)
1. 创建测试镜像
# Dockerfile
FROM busybox
MAINTAINER devops@example.com
ENTRYPOINT ["tail","-f","/etc/hosts"]
2. 构建并部署服务
docker build -t busybox-test .
# 创建跨节点服务,副本数3确保覆盖所有节点
docker service create --replicas 3 --name busytest --network test busybox-test
3. 验证部署
root@ubuntu22:~# docker service ls
ID NAME MODE REPLICAS IMAGE
iicn2h7rw3af busytest replicated 3/3 busybox-test:latest
root@ubuntu22:~# docker service ps busytest
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
s9reawp6seu5 busytest.1 busybox-test:latest ubuntu22 Running Running 5 min
iw3fvcy3tu14 busytest.2 busybox-test:latest ubuntu22 Running Running 5 min
vn16j18a2jzd busytest.3 busybox-test:latest ubuntu22 Running Running 5 min
4. 跨节点连通性测试
# 使用docker inspect查看各容器IP
# 进入任意容器测试网络互通
docker exec -it <container_id> sh
# 在容器内执行 ping <另一节点的容器IP>
Docker Compose集成Overlay网络
version: '3.8'
services:
app:
image: your-app:latest
networks:
- test
networks:
test:
external: true
在docker-compose.yml中声明外部网络后,服务容器即可自动加入test overlay网络,实现跨宿主机的容器间通信。