K8s 中 /etc/resolv.conf 断链引发 connect: connection refused 错误排查记录


在一次 Kubernetes 单节点集群部署中,我遇到一个令人困惑的问题:Pod 启动失败、Kubernetes 控制面组件无法解析 DNS、etcd 报错……最终发现元凶竟然是 /etc/resolv.conf 的“断链”!

本文将记录问题发生的背景、分析过程和最终解决方案,并解释为什么这种事在“什么都没动”的情况下仍然会发生。

问题现场

在我的hyperv环境更换vswitch后,做kubectl get操作

kubectl get nodes

报出如下错误:

E0521 15:16:21.293830    2123 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://k8sm01.lab.com:6443/api?timeout=32s\": dial tcp 172.20.32.247:6443: connect: connection refused"

解读如下:

    1. E0521
      E 代表 Error,表示这是一个错误级别的日志。
      0521 表示发生的日期是 5 月 21 日(即 05 月 21 日)。
    1. 15:16:21.293830
      表示错误发生的 时间,精确到微秒:
      15 点 16 分 21 秒 293830 微秒。
    1. 2123
      这是日志产生的 进程 ID (PID),即哪个程序进程产生了这条日志。
    1. memcache.go:265
      表示出错的文件和行数:
      在源码文件 memcache.go 的 第 265 行。
    1. “Unhandled Error”
      这是一个通用错误标签,表示这个错误没有被特别处理(即程序没有处理它,只是记录下来)。
    1. err=“couldn’t get current server API group list: …”
      这是错误的具体内容:
Get \"https://k8sm01.lab.com:6443/api?timeout=32s\": 
dial tcp 172.20.32.247:6443: connect: connection refused"

说明客户端(kubectl 或 kubelet)尝试访问 API Server 时,目标 IP 172.20.32.247 上的端口 6443 无响应,连接被拒绝。

查因过程

查看kubelet状态

systemctl status kubelet.service

输出:

 systemctl status kubelet.service
● kubelet.service - kubelet: The Kubernetes Node Agent
     Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; preset: enabled)
    Drop-In: /usr/lib/systemd/system/kubelet.service.d
             └─10-kubeadm.conf
     Active: active (running) since Wed 2025-05-21 15:07:30 UTC; 39min ago
       Docs: https://kubernetes.io/docs/
   Main PID: 2046 (kubelet)
      Tasks: 10 (limit: 2194)
     Memory: 26.0M (peak: 27.9M)
        CPU: 1min 16.014s
     CGroup: /system.slice/kubelet.service
             └─2046 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/>

May 21 15:47:02 k8sm01.lab.com kubelet[2046]: E0521 15:47:02.112556    2046 pod_workers.go:1301] "Error syncing pod, skipping" err="failed to \"CreatePodSandbox\" for >
May 21 15:47:02 k8sm01.lab.com kubelet[2046]: E0521 15:47:02.113034    2046 dns.go:284] "Could not open resolv conf file." err="open /run/systemd/resolve/resolv.conf: >
May 21 15:47:02 k8sm01.lab.com kubelet[2046]: E0521 15:47:02.113069    2046 kuberuntime_sandbox.go:45] "Failed to generate sandbox config for pod" err="open /run/syste>
May 21 15:47:02 k8sm01.lab.com kubelet[2046]: E0521 15:47:02.113090    2046 kuberuntime_manager.go:1170] "CreatePodSandbox for pod failed" err="open /run/systemd/resol>
May 21 15:47:02 k8sm01.lab.com kubelet[2046]: E0521 15:47:02.113137    2046 pod_workers.go:1301] "Error syncing pod, skipping" err="failed to \"CreatePodSandbox\" for 

由于systemctl输出的日志被截断,使用journalctl获取完整日志:

 journalctl -b 0 --since=today -u kubelet --no-pager

输出:

......
May 21 15:51:50 k8sm01.lab.com kubelet[2046]: E0521 15:51:50.122721    2046 dns.go:284] "Could not open resolv conf file." err="open /run/systemd/resolve/resolv.conf: no such file or directory"
May 21 15:51:50 k8sm01.lab.com kubelet[2046]: E0521 15:51:50.122778    2046 kuberuntime_sandbox.go:45] "Failed to generate sandbox config for pod" err="open /run/systemd/resolve/resolv.conf: no such file or directory" pod="kube-system/kube-scheduler-k8sm01.lab.com"
May 21 15:51:50 k8sm01.lab.com kubelet[2046]: E0521 15:51:50.122814    2046 kuberuntime_manager.go:1170] "CreatePodSandbox for pod failed" err="open /run/systemd/resolve/resolv.conf: no such file or directory" pod="kube-system/kube-scheduler-k8sm01.lab.com"
May 21 15:51:50 k8sm01.lab.com kubelet[2046]: E0521 15:51:50.122879    2046 pod_workers.go:1301] "Error syncing pod, skipping" err="failed to \"CreatePodSandbox\" for \"kube-scheduler-k8sm01.lab.com_kube-system(0b6d714931c0469558b131ba4fad4975)\" with CreatePodSandboxError: \"Failed to generate sandbox config for pod \\\"kube-scheduler-k8sm01.lab.com_kube-system(0b6d714931c0469558b131ba4fad4975)\\\": open /run/systemd/resolve/resolv.conf: no such file or directory\"" pod="kube-system/kube-scheduler-k8sm01.lab.com" podUID="0b6d714931c0469558b131ba4fad4975"
May 21 15:51:50 k8sm01.lab.com kubelet[2046]: E0521 15:51:50.369772    2046 controller.go:145] "Failed to ensure lease exists, will retry" err="Get \"https://k8sm01.lab.com:6443/apis/coordination.k8s.io/v1/namespaces/kube-node-lease/leases/k8sm01.lab.com?timeout=10s\": dial tcp 172.20.32.247:6443: connect: connection refused" interval="7s"
.......

kubelet 日志已经揭示了关键问题:Kubelet 在尝试创建 Pod 的 Sandbox 时失败了,而根本原因是它无法读取 DNS 配置文件 /run/systemd/resolve/resolv.conf

根因

在使用 systemd-resolved 的 Linux 系统中(如 Ubuntu 18+),/etc/resolv.conf 默认是个符号链接,指向:

ls -alh /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Apr 23  2024 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

由于某些原因, /etc/resolv.conf 仍指向那个已不存在的文件,就会造成容器(例如 etcd、kubelet、CoreDNS)无法解析 DNS。

解决方案

方法一:恢复 /etc/resolv.conf 到标准格式

检查当前链接:

ls -l /etc/resolv.conf

如果输出类似:

/etc/resolv.conf -> /run/systemd/resolve/resolv.conf

但 /run/systemd/resolve/resolv.conf 不存在,那么可以临时替换为传统 resolv.conf:

sudo rm /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

重新启动 kubelet:

sudo systemctl restart kubelet

方法二:重新启用 systemd-resolved(如需要)

如果你之前禁用了 systemd-resolved,可以启用它:

sudo systemctl enable systemd-resolved --now

然后检查:

ls -l /etc/resolv.conf
# 如果还没有指向 /run/systemd/resolve/resolv.conf
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

验证

确保 /etc/resolv.conf 文件有效:

cat /etc/resolv.conf

应该能看到:

nameserver 8.8.8.8

然后再检查做kubectl get操作恢复正常。

kubectl get nodes
NAME             STATUS     ROLES           AGE   VERSION
k8sm01.lab.com   Ready      control-plane   17d   v1.31.8
k8sw01.lab.com   NotReady   <none>          17d   v1.31.8

总结

这个错误的根本原因是:/etc/resolv.conf 指向了一个不存在的文件,导致 Kubernetes 组件无法进行 DNS 解析。
最直接修复方法 是用 echo “nameserver 8.8.8.8” > /etc/resolv.conf 方式写入一个有效 DNS 配置,然后重启 kubelet。

### 解决 Ubuntu Kylin `apt-get update` 连接被拒 (Connection Refused Error 111) 的方法 当遇到 `apt-get update` 出现连接被拒绝错误时,这通常意味着客户端无法成功建立到服务器的网络连接。对于 Ubuntu Kylin 用户而言,可以尝试以下几种解决方案来修复此问题。 #### 修改软件源地址 由于官方镜像站点可能出现访问不稳定的情况,建议切换至国内稳定可靠的镜像源。编辑 `/etc/apt/sources.list` 文件,将默认的源替换为中国科学技术大学、阿里云或其他可信赖的中国境内镜像站提供的链接[^1]: ```bash sudo vi /etc/apt/sources.list ``` #### 清理并重置 APT 缓存 有时旧缓存数据也会引发此类异常现象。通过清理现有APT包管理器中的残留记录再重新索引能有效改善状况。 ```bash sudo rm -rf /var/lib/apt/lists/* sudo mkdir -p /var/lib/apt/lists/partial sudo apt-get clean sudo apt-get update ``` #### 配置代理设置(如果适用) 若当前环境处于企业内部网或者学校校园网之中,则可能需要配置HTTP/HTTPS形式的Web代理才能正常获取外部资源。可以通过修改全局环境变量或是在特定应用程序里指定代理参数两种方式实现。 ```bash export http_proxy=http://your.proxy.server:port/ export https_proxy=https://your.proxy.server:port/ ``` #### 更新 DNS 设置 不正确的DNS解析同样会造成类似的故障表现。考虑更换成更加快捷稳定的公共域名服务提供商比如Google Public DNS(8.8.8.8),或是本地运营商推荐使用的IP地址作为首选DNS服务器。 ```bash sudo nano /etc/resolv.conf nameserver 8.8.8.8 ``` 以上措施能够帮助大多数用户克服因网络因素而导致的更新失败难题。当然,在实际操作过程中还需结合具体情况进行调整优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值