解决 Docker Swarm 主节点返回 0.0.0.0 IP 地址的问题

114次阅读
没有评论

问题描述

在一个包含 3 个节点的 Docker Swarm 集群中,尝试通过以下命令获取每个节点的 IP 地址:

docker node inspect node-1 --format '{{ .Status.Addr  }}'

但在请求主节点(leader node)的 IP 地址时(例如上述命令中的 node-1),却得到了 0.0.0.0。而其他节点则正常工作。
用户希望了解在这种情况下发生了什么,以及如何使用 Docker 命令通过主机名或 docker node ls 获取所有节点的 IP 地址。

解决方案

以下解决方案假设你已经熟悉 Docker Swarm 的基本概念和命令操作。

问题原因

当你使用命令 docker node inspect node-1 --format '{{ .Status.Addr }}' 获取节点的 IP 地址时,有可能遇到一个问题:主节点(leader node)返回的 IP 地址是 0.0.0.0。而其他节点正常工作。

这是因为 Status.Addr 在获取节点地址时使用了 gRPC 库来确定节点在管理器视图下的地址。这意味着,例如,如果一个工作节点位于代理后面,它会将代理的地址作为 Status.Addr,即使工作节点本身并不“知道”它位于代理后面。对于 ManagerStatus.Addr,给出的地址是管理器的广告地址,可能在执行 init 或 join 时使用 --advertise-addr 设置。广告地址必须正确,因为其他管理器知道要连接到该地址。

引用自:https://github.com/moby/moby/issues/35437

使用正确的属性获取节点 IP

要解决这个问题,你可以使用 ManagerStatus.Addr 属性来获取节点的 IP 地址。以下是在 Linux 环境中使用 Bash 脚本的示例,用于获取所有管理节点(manager nodes)的 IP 地址并去除端口号:

#!/bin/bash
for NODE in $(docker node ls -f 'role=manager' --format '{{.Hostname}}'); do
  IP=$(docker node inspect --format '{{.ManagerStatus.Addr}}' ${NODE})
  IP_WITHOUT_PORT=$(echo $IP | sed 's/:2377//')
  echo "Node ${NODE} IP: ${IP_WITHOUT_PORT}"
done

在上面的示例中,我们首先使用 docker node ls 命令筛选出所有管理节点的主机名,并保存在变量 NODE 中。然后,我们使用 docker node inspect 命令获取每个节点的 ManagerStatus.Addr,并将结果保存在变量 IP 中。最后,我们使用 sed 命令去除端口号(默认是 2377),得到纯净的 IP 地址,保存在变量 IP_WITHOUT_PORT 中,并打印出来。

通过这个脚本,你可以获取所有管理节点的 IP 地址,并处理可能的端口号问题。

总结

在 Docker Swarm 集群中,获取节点 IP 地址时,主节点返回 0.0.0.0 的问题可能是由于属性选择引起的。为了解决这个问题,你可以使用 ManagerStatus.Addr 属性来获取节点的 IP 地址。上述示例演示了如何使用 Bash 脚本来获取并处理管理节点的 IP 地址,以确保得到正确的结果。

请注意,上述解决方案假设你的 Docker Swarm 集群已经正确配置,并且你对 Docker Swarm 的基本概念和操作有一定的了解。

正文完