执行docker swarm init后节点显示NotReady,最常见原因是节点间基础通信失败:未指定--advertise-addr真实IP、防火墙未开放2377/7946/4789端口、hostname重复、SELinux限制、TLS认证失败、时间不同步或健康检查缺失。

直接用 docker swarm init 就能启动集群,不需要额外装 Swarm 工具或改内核——Docker 1.12+ 自带 Swarm 模式,关键在节点网络通、端口开对、角色配准。
为什么 docker swarm init 执行后节点显示 NotReady
最常见原因是节点间基础通信失败,不是 Docker 本身问题:
-
docker swarm init默认只监听本地回环(127.0.0.1),必须显式指定--advertise-addr为本机可被其他节点访问的真实 IP(如192.168.5.100),不能写0.0.0.0或留空 - 防火墙没放开
2377/tcp(管理通信)、7946/tcp+udp(节点状态同步)、4789/udp(overlay 网络)——firewall-cmd --permanent --add-port=2377/tcp后必须跟firewall-cmd --reload - 节点 hostname 重复或
/etc/hosts解析异常,导致docker node ls显示 ID 正常但状态卡在Unknown或Down - SELinux 未设为 permissive:临时关掉用
setenforce 0,长期方案是配container_manage_cgroup等策略
加节点时提示 rpc error: code = Unavailable desc = connection closed before server preface received
这是典型的 TLS 握手失败,Swarm 要求所有节点启用双向 TLS 认证:
- 确保所有节点运行的是同一版本 Docker(比如全是
24.0.0+),混用旧版(如20.10)和新版会因证书格式不兼容报此错 - 加入命令里的 token 有有效期(默认 24 小时),过期后必须在 manager 上重新生成:
docker swarm join-token worker或docker swarm join-token manager - 如果 manager 节点启用了自定义 CA(如通过
--cert-expires或外部 PKI),worker 必须同步根证书到/etc/docker/ca.pem,否则拒绝连接 - 时间不同步会导致 TLS 证书校验失败——三台节点的系统时间差不能超过 5 分钟,用
chrony或systemd-timesyncd统一校时
部署服务后容器不自动重建,docker service ps 显示 Rejected
Swarm 不会无条件重启失败容器,它只响应“任务失败”而非“进程退出”:
- 服务没定义健康检查时,Swarm 默认认为容器只要
start成功就健康;必须加HEALTHCHECK(Dockerfile 中)或--health-cmd(docker service create里)才能触发自愈 -
--restart-condition参数被忽略——Swarm 模式下该参数无效,重启策略由docker service update --force或任务失败类型决定 - 资源不足(如内存超限被 OOM killer 杀掉)时,
docker service ps可能显示Rejected+no resource found,需检查docker node inspect <node-id>的ManagerStatus和Resources字段 - 镜像拉取失败(如私有仓库认证失效)也会卡在
Rejected,此时看docker service logs <service-name>通常为空,要查journalctl -u docker | grep -i "pull\|auth"
Swarm 的“自动”是有前提的:节点必须持续上报心跳(依赖 7946 端口)、任务状态必须可被 Raft 日志记录(至少半数 manager 在线)、健康检查返回码必须明确(非 0 才算失败)。少开一个端口、多一秒钟时钟漂移、或者 HEALTHCHECK 里用了 curl -f 却没监听 /health 路径——都可能让自愈静默失效。


















