如何获取Docker Swarm中overlay网络下跨节点容器的全部IP地址
获取Docker Swarm集群中Overlay网络的所有容器IP
以下是几个符合你需求的解决方案,无需使用IP扫描工具:
1. 在Swarm Manager节点批量查询所有节点的网络信息
Swarm Manager节点拥有整个集群的控制权,可以直接通过docker node exec在所有集群节点上执行网络检查命令,批量提取容器IP:
# 获取所有集群节点ID,逐个执行网络检查并提取IPv4地址(自动去除子网掩码) docker node ls -q | xargs -I {} docker node exec {} docker network inspect my-net --format '{{range .Containers}}{{.IPv4Address}}{{"\n"}}{{end}}' | cut -d'/' -f1
解释:
docker node ls -q:输出所有集群节点的ID(静默模式)docker node exec {} docker network inspect my-net:在每个节点上执行网络检查命令--format '{{range .Containers}}{{.IPv4Address}}{{"\n"}}{{end}}':通过Go模板只提取容器的IPv4地址字段cut -d'/' -f1:去除地址中的子网掩码部分(比如把10.0.0.2/24转为10.0.0.2)
如果需要过滤特定容器,还可以在模板中添加容器名称判断,比如只提取名称包含compute-的容器:
docker node ls -q | xargs -I {} docker node exec {} docker network inspect my-net --format '{{range .Containers}}{{if contains "compute-" .Name}}{{.IPv4Address}}{{"\n"}}{{end}}{{end}}' | cut -d'/' -f1
2. 基于Swarm服务部署的场景优化
如果你的计算容器是通过docker service create部署的Swarm服务,可直接通过服务相关命令获取所有任务的容器IP:
# 获取指定服务下所有任务的容器ID,再逐个查询IP docker service ps <你的服务名> -q | xargs docker inspect --format '{{range .NetworkSettings.Networks.my-net}}{{.IPAddress}}{{"\n"}}{{end}}'
或者用更简洁的Go模板直接从服务任务中提取:
docker service inspect <你的服务名> --format '{{range .Spec.TaskTemplate.Networks}}{{if eq .Target "my-net"}}{{range ../../Status.RunningTasks}}{{.Status.ContainerStatus.ContainerID}}{{"\n"}}{{end}}{{end}}{{end}}' | xargs docker inspect --format '{{.NetworkSettings.Networks.my-net.IPAddress}}'
3. 容器内通过Docker API获取集群信息(需安全配置)
如果需要在容器内部直接获取全集群的容器IP,可以挂载Manager节点的Docker socket到容器中,然后通过Docker API查询:
- 启动容器时挂载Docker socket(仅建议在可信环境中使用,避免权限风险):
docker run -d --name ip-collector --network my-net -v /var/run/docker.sock:/var/run/docker.sock alpine:latest sleep infinity
- 在容器内安装curl并调用Docker API查询所有节点的网络信息:
# 进入容器 docker exec -it ip-collector sh # 安装curl和jq apk add curl jq # 查询所有节点ID NODE_IDS=$(curl -s --unix-socket /var/run/docker.sock http://localhost/nodes | jq -r '.[].ID') # 遍历节点查询网络信息 for id in $NODE_IDS; do EXEC_ID=$(curl -s --unix-socket /var/run/docker.sock http://localhost/nodes/$id/exec -X POST -H "Content-Type: application/json" -d '{"AttachStdout":true,"Cmd":["docker","network","inspect","my-net","--format","{{range .Containers}}{{.IPv4Address}}{{"\n"}}{{end}}"]}' | jq -r '.Id') curl -s --unix-socket /var/run/docker.sock http://localhost/exec/$EXEC_ID/start -X POST -H "Content-Type: application/json" -d '{"Detach":false,"Tty":false}' done | cut -d'/' -f1
注意:
- 挂载Docker socket会赋予容器主机级别的Docker权限,需严格控制容器的信任度
- 此方法适合需要动态实时获取IP的应用场景
4. 利用Swarm内置KV存储查询(进阶)
Docker Swarm使用etcd作为内置KV存储,所有网络和容器信息都存储在此。可以通过docker node inspect获取etcd的访问信息,然后用etcdctl查询:
- 获取Swarm集群的etcd端点和证书信息(在Manager节点执行):
# 获取etcd端点 ETCD_ENDPOINT=$(docker node inspect self --format '{{.ManagerStatus.Addr}}') # 证书文件默认路径 CERT_DIR="/var/lib/docker/swarm/certificates/"
- 使用
etcdctl查询网络容器信息:
ETCDCTL_API=3 etcdctl --endpoints=$ETCD_ENDPOINT --cacert=${CERT_DIR}ca.crt --cert=${CERT_DIR}node.crt --key=${CERT_DIR}node.key get --prefix /docker/network/v1.0/networks/my-net/containers
说明:
- 此方法较为底层,适合需要深度定制的场景,需要熟悉etcd的KV结构
内容的提问来源于stack exchange,提问作者Green 绿色
相关产品推荐
相关产品推荐

