K3s升级后etcd连接拒绝通常因成员信息未同步或残留旧节点元数据,需检查member-list、清理异常成员、核对证书与地址配置、确认systemd依赖顺序,并验证etcd健康及apiserver日志。

这通常不是服务真的挂了,而是 K3s 升级后 etcd 成员信息未同步或残留旧节点元数据,导致新进程尝试连接已不存在或配置错位的 peer 地址,从而报 “connection refused”。
检查 etcd 成员列表是否一致
K3s 使用嵌入式 etcd,默认监听在本地 2379/2380,但升级时若节点名(--node-name)、advertise 地址或初始集群配置变更,etcd 会认为这是个“新成员”,而旧成员信息仍留在集群中,造成握手失败。
- 执行
k3s etcd member-list(K3s v1.25+)或进入容器运行etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/var/lib/rancher/k3s/server/tls/etcd/server-ca.crt --cert=/var/lib/rancher/k3s/server/tls/etcd/client.crt --key=/var/lib/rancher/k3s/server/tls/etcd/client.key member list - 确认输出中没有重复、宕机未清理、或 IP/端口明显错误的成员(比如显示旧内网 IP、已下线主机名)
- 若有异常成员,用
k3s etcd member-remove清理(确保该节点确实不再参与集群)
确认静态 pod 和 kubelet 是否使用正确证书与地址
升级后,K3s 可能生成新证书,但 kubelet 或 static pod(如 kube-apiserver)仍在尝试用旧 CA 或旧 advertise 地址连 etcd。
- 检查
/var/lib/rancher/k3s/server/manifests/kube-apiserver.yaml(如有)或通过ps aux | grep apiserver看启动参数,确认--etcd-servers指向https://127.0.0.1:2379(非 localhost、非旧 IP) - 确认
--etcd-cafile、--etcd-certfile、--etcd-keyfile路径存在且可读,对应文件时间戳应接近升级时间 - 临时用
curl -k --cert /var/lib/rancher/k3s/server/tls/etcd/client.crt --key /var/lib/rancher/k3s/server/tls/etcd/client.key https://127.0.0.1:2379/health验证 etcd 自身健康
排查 systemd 服务依赖与启动顺序
K3s v1.24+ 默认启用 etcd 的 systemd 依赖管理。若升级后 k3s.service 启动太快,etcd 还没 ready,apiserver 就去连,就会触发批量 connection refused。
- 运行
systemctl status k3s,看是否有 “Failed to connect to etcd” 类似日志出现在 early 启动阶段 - 检查
/etc/systemd/system/k3s.service.d/override.conf是否存在自定义After=network.target但漏了etcd.service - 建议显式添加:After=etcd.service,并确保
etcd.service已启用(systemctl is-enabled etcd)
跳过 etcd 直接验证核心组件状态
如果 etcd 确实健康但控制平面仍不就绪,可能是 apiserver 未正确加载 client cert 或 RBAC 初始化卡住。
- 用
k3s kubectl get nodes --insecure-skip-tls-verify测试是否能绕过证书直接通到 apiserver(需确保--disable-agent未启用) - 检查
/var/lib/rancher/k3s/server/logs/kube-apiserver.log,搜索 “failed to list *”、“x509”、“no endpoints available” - 临时加
--debug到 k3s 启动参数(修改/etc/systemd/system/k3s.service),重启后看更细粒度连接日志









