大家好,今天给大家分享一个k8s 集群内部 pod 解析 service 域名异常的故障,如果觉得文章不错,可关注公众号运维日常手记,谢谢。

事情是这样的,有天有个客户找到我,说他在k8s集群里面部署了一套KubeFlow,pod状态都是正常的,但是登录的时候界面报了一个500错误,并给我发了下面这张截图,我当时也不知道KubeFlow是啥,但是我注意到了截图上面显示的url地址,“oauth2/callback”看名称是一个认证回调相关的地址,初步怀疑是调用这个oauth2接口异常了所以报错。
file

于是我让客户打开浏览器F12查看了登录调用的接口,确实是调用oauth2接口异常,验证了我的猜想。
file

为什么这个接口会返回500状态码呢?只能去提供这个接口的pod里找日志了,以下是客户部署的KubeFlow的pod,注意到最底下的2个pod,就是提供认证接口的pod,于是让客户去这2个pod里找日志。
file

经过一阵等待,功夫不负有心人,客户找到了这样一条错误日志,日志提示找不到“dex.auth.svc.cluster.local ”这个地址,了解过k8s知识的同学应该可以猜到,这是一个service的地址,指向的是auth这个命名空间下的dex service。
file

难道是这个auth命名空间下没有dex这个service吗?经过查询,发现这个service是存在的,且service关联的pod也是正常的。
file
file

既然service是存在的,难道是coredns pod异常无法解析这个service?查询coredns pod的状态,以及日志,也没发现任何异常。
file
file

既然日志也没有异常那我们就在集群中运行一个busybox pod,手动解析一下域名看看情况,进入pod执行nslookup dex.auth.svc.cluster.local 手动解析这个service的地址,发现确实无法解析。
`
在default命名空间下启动一个busybox pod
kubectl run busybox --rm -ti --image crpi-u3f530xi0zgtvmy0.cn-beijing.personal.cr.aliyuncs.com/image-infra/busybox /bin/sh
`
file

会不会是dex这个service有问题呢?换个集群默认创建的service测试一下,执行nslookup kubernetes.default.svc.cluster.local ,意外的是kubernetes 这个集群默认创建service也解析不了。
file

查看busybox容器里面的/etc/resolv.conf配置,nameserver指向的是coredns的service ip 10.96.0.10 没有问题,但是search这一行的配置好像有点奇怪,“search default.svc.nolenlinux.cn svc.nolenlinux.cn nolenlinux.cn”,这个配置的意思是当我们访问一个非FQDN域名的时候,会自动替我们逐一添加对应的后缀去匹配域名,比如执行nslookup kubernetes,如自动匹配 kubernetes.default.svc.nolenlinux.cn, kubernetes.svc.nolenlinux.cn, kubernetes.nolenlinux.cn 域名。但如果我们指定的是一个FQDN域名比如nslookup dex.auth.svc.cluster.local 它会直接解析,不会在添加后缀,似乎集群只解析nolenlinux.cn后缀结尾的域名,不会解析cluster.local的域名。
file

测试一下,如下在default命名空间下的busybox容器里面执行nslookup kubernetes,显示分别匹配了kubernetes.svc.nolenlinux.cn、kubernetes.nolenlinux.cn和kubernetes.default.svc.nolenlinux.cn域名,最后正确解析了kubernetes.default.svc.nolenlinux.cn这个域名,和我们上面的猜想一致。
file

那“search default.svc.nolenlinux.cn svc.nolenlinux.cn nolenlinux.cn”这个配置是怎么来的呢?通过查询文档我们发现这个nolenlinux.cn其实是通过kubelet的clusterDomain配置指定的,查看kubelet的配置文件cat /var/lib/kubelet/config.yaml,确实有这个配置,最后询问客户,原来是他们在使用kubeadm init 初始化集群的时候加了“--service-dns-domain=nolenlinux.cn”这个配置。
file

解决方案

解决方案有两种,一种是用户修改KubeFlow的配置,把 dex.auth.svc.cluster.local 改成dex.auth.svc.nolenlinux.cn,还有一种是修改coredns的配置,因为开源软件里面的chart模板很多是写死为cluster.local的,为了兼容决定使用方式二。

编辑coredns配置文件
kubectl edit cm coredns -n kube-system

在kubernetes nolenlinux.cn in-addr.arpa ip6.arpa 处添加cluster.local,如下。
`apiVersion: v1
data:
Corefile: |

.:53 {
    errors
    health {
       lameduck 5s
    }
    ready
    kubernetes cluster.local nolenlinux.cn in-addr.arpa ip6.arpa {
       pods insecure
       fallthrough in-addr.arpa ip6.arpa
       ttl 30
    }
    prometheus :9153
    forward . /etc/resolv.conf {
       max_concurrent 1000
    }
    cache 30 {
       disable success nolenlinux.cn
       disable denial nolenlinux.cn
    }
    loop
    reload
    loadbalance
}

kind: ConfigMap
metadata:
creationTimestamp: "2025-05-26T03:08:21Z"
name: coredns
namespace: kube-system
resourceVersion: "8111"
uid: 4b8698b7-6306-43b3-8783-3d98391eda55`


添加完成后,测试nslookup kubenetes.default.svc.cluster.local和kubernetes.default.svc.nolenlinux.cn都能正常解析。
![file](/img/bVdjz8a)
![file](/img/bVdjz8b)

至此,故障顺利解决,如果觉得文章对你有用,麻烦关注一下,谢谢。
本文由博客一文多发平台 OpenWrite 发布!

用户bPcLWff
937 声望130 粉丝