本文介绍关于Kubernetes集群域名解析异常的常见检查命令和检查步骤。

检查业务Pod的DNS配置

  • 命令
    #查看foo容器的YAML配置,并确认DNSPolicy字段是否符合预期。
    kubectl get pod foo -o yaml
    
    #当DNSPolicy符合预期时,可以进一步进入Pod容器中,查看实际生效的DNS配置。
    
    #通过bash命令进入foo容器,若bash不存在可使用sh代替。
    kubectl exec -it foo bash
    
    #进入容器后,可以查看DNS配置,nameserver后面为DNS服务器地址。
    cat /etc/resolv.conf
  • DNS Policy配置说明

    DNS Policy示例如下所示。

    apiVersion: v1
    kind: Pod
    metadata:
      name: <pod-name>
      namespace: <pod-namespace>
    spec:
      containers:
      - image: <container-image>
        name: <container-name>
    
    #默认场景下的DNS Policy。
      dnsPolicy: ClusterFirst
    #使用了NodeLocal DNSCache时的DNS Policy。
      dnsPolicy: None
      dnsConfig:
        nameservers:
        - 169.254.20.10
        - 172.21.0.10
        options:
        - name: ndots
          value: "3"
        - name: timeout
          value: "1"
        - name: attempts
          value: "2"
        searches:
        - default.svc.cluster.local
        - svc.cluster.local
        - cluster.local
    
      securityContext: {}
      serviceAccount: default
      serviceAccountName: default
      terminationGracePeriodSeconds: 30
    DNSPolicy字段值 使用的DNS服务器
    Default 只适用于不需要访问集群内部服务的场景。Pod创建时会从ECS节点/etc/resolv.conf文件继承DNS服务器列表。
    ClusterFirst 此为DNSPolicy默认值,Pod会将CoreDNS提供的kube-dns服务IP作为DNS服务器。开启HostNetwork的Pod,如果选择ClusterFirst模式,效果等同于Default模式。
    ClusterFirstWithHostNet 开启HostNetwork的Pod,如果选择ClusterFirstWithHostNet模式,效果等同于ClusterFirst。
    None 配合DNSConfig字段,可用于自定义DNS服务器和参数。在NodeLocal DNSCache开启注入时,DNSConfig会将DNS服务器指向本地缓存IP及CoreDNS提供的kube-dns服务IP。

检查CoreDNS Pod运行状态

命令
  • 执行以下命令,查看容器组信息。
    kubectl -n kube-system get pod -o wide -l k8s-app=kube-dns
    预期输出:
    NAME                      READY   STATUS    RESTARTS   AGE   IP            NODE
    coredns-xxxxxxxxx-xxxxx   1/1     Running   0          25h   172.20.6.53   cn-hangzhou.192.168.0.198
  • 执行以下命令,查看Pod的实时资源使用情况。
    kubectl -n kube-system top pod -l k8s-app=kube-dns
    预期输出:
    NAME                      CPU(cores)   MEMORY(bytes)
    coredns-xxxxxxxxx-xxxxx   3m           18Mi
  • 如果Pod不处于Running状态,可以通过kubectl -n kube-system describe pod <CoreDNS Pod名称>命令,查询问题原因。

检查CoreDNS运行日志

命令

执行以下命令,检查CoreDNS运行日志。
kubectl -n kube-system logs -f --tail=500 --timestamps coredns-xxxxxxxxx-xxxxx
参数 描述
f 持续输出。
tail=500 输出最后500行日志。
timestamps 同时显示日志打印的时间。
coredns-xxxxxxxxx-xxxxx CoreDNS Pod副本的名称。

检查CoreDNS DNS查询请求日志

命令

DNS查询请求日志仅会在开启CoreDNS的Log插件后,才会打印到容器日志中。关于开启Log插件的具体操作,请参见DNS原理和配置说明

命令与检查CoreDNS运行日志相同,请参见检查CoreDNS运行日志

检查CoreDNS Pod的网络连通性

操作步骤

  1. 登录CoreDNS Pod所在集群节点。
  2. 执行ps aux | grep coredns,查询CoreDNS的进程ID。
  3. 执行nsenter -t <pid> -n bash,进入CoreDNS所在容器网络命名空间,其中pid为上一步得到的进程ID。
  4. 测试网络连通性。
    1. 运行telnet <apiserver_slb_ip> 443,测试Kubernetes APIServer的连通性。

      其中apiserver_slb_ip为default命名空间下Kubernetes服务的IP地址。

    2. 运行dig <domain> @<upstream_dns_server_ip>,测试CoreDNS Pod到上游DNS服务器的连通性。

      其中domain为测试域名,upstream_dns_server_ip为上游DNS服务器地址,默认为100.100.2.136和100.100.2.138。

常见问题

现象 原因 处理方案
CoreDNS无法连通Kubernetes APIServer APIServe异常、机器负载高、kube-proxy 没有正常运行等。 提交工单排查。
CoreDNS无法连通上游DNS服务器 机器负载高、CoreDNS配置错误、专线路由问题等。 提交工单排查。

检查业务Pod到CoreDNS的网络连通性

操作步骤

  1. 选择以下任意一种方式,进入客户端Pod容器网络。
    • 方法一:使用kubectl exec命令。
    • 方法二:
      1. 登录业务Pod所在集群节点。
      2. 执行ps aux | grep <业务进程名>命令,查询业务容器的进程ID。
      3. 执行nsenter -t <pid> -n bash命令,进入业务Pod所在容器网络命名空间。

        其中pid为上一步得到的进程ID。

    • 方法三:如果频繁重启,请按以下步骤操作。
      1. 登录业务Pod所在集群节点。
      2. 执行docker ps -a | grep <业务容器名>命令,查询k8s_POD_ 开头的沙箱容器,记录容器ID。
      3. 执行docker inspect <沙箱容器 ID> | grep netns命令,查询/var/run/docker/netns/xxxx的容器网络命名空间路径。
      4. 执行nsenter -n<netns 路径> bash命令,进入容器网络命名空间。

        其中netns 路径为上一步得到的路径。

        说明 -n<netns 路径>之间不加空格。
  2. 测试网络连通性。
    1. 执行dig <domain> @<kube_dns_svc_ip>命令,测试业务Pod到CoreDNS服务kube-dns解析查询的连通性。

      其中<domain>为测试域名,<kube_dns_svc_ip>为kube-system命名空间中kube-dns的服务IP。

    2. 执行ping <coredns_pod_ip>命令,测试业务Pod到CoreDNS容器副本的连通性。

      其中<coredns_pod_ip>为kube-system命名空间中CoreDNS Pod的IP。

    3. 执行dig <domain> @<coredns_pod_ip>命令,测试业务Pod到CoreDNS容器副本解析查询的连通性。

      其中<domain>为测试域名,<coredns_pod_ip>为kube-system命名空间中CoreDNS Pod的IP。

常见问题

现象 原因 处理方案
业务Pod无法通过CoreDNS服务kube-dns解析 机器负载高、kube-proxy没有正常运行、安全组没有放开UDP协议53端口等。 检查安全组是否放开UDP 53端口,若已放开请提交工单排查。
业务Pod无法连通CoreDNS容器副本 容器网络异常或安全组没有放开ICMP。 运行容器网络诊断。
业务Pod无法通过CoreDNS容器副本解析 机器负载高、安全组没有放开UDP协议53端口等。 检查安全组是否放开UDP 53端口,若已放开请提交工单排查。

容器网络诊断

  1. 登录容器服务管理控制台
  2. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  3. 在控制台左侧导航栏中,单击集群
  4. 在集群管理页左侧导航栏中,选择运维管理 > 集群检查
  5. 容器智能运维的左侧导航栏,选择检查 > 故障诊断
  6. 故障诊断页面,单击网络诊断页签。
  7. 源地址输入业务Pod IP,在目标地址输入CoreDNS服务kube-dns IP,在端口输入53,同时选中报文跟踪,选中我已知晓并同意,单击发起诊断
  8. 在故障诊断列表,单击目标诊断项右侧操作列的诊断详情
    根据诊断结果访问全图展开所有访问路径查看网络诊断详情,诊断结果将包含异常原因。关于网络诊断的具体操作,请参见通过集群故障诊断功能定位集群问题

抓包

当无法定位问题时,需要抓包进行辅助诊断。

  1. 登录出现异常的业务Pod、CoreDNS Pod所在节点。
  2. 在ECS(非容器内)执行以下命令,可以将最近所有的53端口信息抓取到文件中。
    tcpdump -i any port 53 -C 20 -W 200 -w /tmp/client_dns.pcap
  3. 结合业务日志的报错定位到精准的报错时间的报文信息。
    说明
    • 在正常情况下,抓包对业务无影响,仅会增加小部分的CPU负载和磁盘写入。
    • 以上命令会对抓取到的包进行rotate,最多可以写200个20 MB的.pcap文件。