【DNS系列-K8S排错】busybox 中使用 nslookup 进行域名解析时好时坏

busybox 解析时好时坏问题

[root@cluster2-master01 ~]# k get svc
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes              ClusterIP   10.233.0.1              443/TCP   16d
master-deploy           ClusterIP   10.233.27.218           80/TCP    8d
master-deploy-busybox   ClusterIP   10.233.4.215            80/TCP    103m

[root@cluster2-master01 ~]# k exec -it master-deploy-busybox-7744476478-ch5sh -- sh
/ # cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 169.254.25.10
options ndots:5

# 此时可以进行解析
/ # nslookup master-deploy   
Server:         169.254.25.10
Address:        169.254.25.10:53

Name:   master-deploy.default.svc.cluster.local
Address: 10.233.27.218

# 此时无法进行解析
/ # nslookup master-deploy
Server:         169.254.25.10
Address:        169.254.25.10:53

** server can't find master-deploy.default.svc.cluster.local: NXDOMAIN

使用 busybox 容器,其解析器的库可能无法解析 nodelocaldns 或 coredns 返回的结果(可能是 ipv6 部分,或是库不全 glibc 等,不清楚具体原因),因此导致时好时坏(有时可以解析,有时候解析不成功)

可以采用别的容器尝试,如 centos 镜像

如何证明不是 coredns 或 nodelocaldns 问题

在宿主机上直接进行测试,通过下面可以看到(nslookup 指定了 dns 解析地址),coredns 或 nodelocaldns 都可以进行解析

# 169.254.25.10 为 nodelocaldns 服务地址
[root@cluster2-master01 ~]# nslookup master-deploy-busybox.default.svc.cluster.local 169.254.25.10
Server:         169.254.25.10
Address:        169.254.25.10#53

Name:   master-deploy-busybox.default.svc.cluster.local
Address: 10.233.4.215

# 10.233.0.3 为 coredns 服务地址
[root@cluster2-master01 ~]# nslookup master-deploy-busybox.default.svc.cluster.local 10.233.0.3
Server:         10.233.0.3
Address:        10.233.0.3#53

Name:   master-deploy-busybox.default.svc.cluster.local
Address: 10.233.4.215

宿主机环路问题

[root@cluster2-master01 ~]# kubectl get svc -A | grep dns
kube-system   coredns                     ClusterIP   10.233.0.3              53/UDP,53/TCP,9153/TCP   16d

[root@cluster2-master01 ~]# cat /etc/resolv.conf
nameserver 10.233.0.3   		# 此 ip 为 coredns service,此配置会导致环路
nameserver 169.254.25.10 		# 此 ip 为 nodelocaldns 服务的ip(不是 k8s service 形式,而是在宿主机上, ip a 可查看) ,此配置会导致环路
nameserver 114.114.114.114 

[root@cluster2-master01 ~]# ip a
28: nodelocaldns:  mtu 1500 qdisc noop state DOWN group default 
    link/ether d2:ba:4c:e5:45:07 brd ff:ff:ff:ff:ff:ff
    inet 169.254.25.10/32 scope global nodelocaldns
       valid_lft forever preferred_lft forever

# 此处提示 递归,考虑 也就是 环路,导致无法解析
[root@cluster2-master01 ~]# nslookup master-deploy.default.svc.cluster.local
;; Got recursion not available from 10.233.0.3, trying next server

为什么会环路

看下面两个配置文件,可以得知

  • nodelocaldns 搜索路径为

    • 先在自身缓存查找 —> cluster.local 域 去 coredns 寻找域名解析 —> 前一步没找到,就找宿主机 /etc/resolv.conf 文件,通过其中的 nameserver 再继续寻找
  • coredns 搜索路径为

    • 先在自身缓存查找 —> 前一步没找到,就找宿主机 /etc/resolv.conf 文件,通过其中的 nameserver 再继续寻找
  • k8s 的搜索路径为

    1. nodelocaldns 本地缓存
    2. cluster.local 域(集群内的service),去 coredns 寻找解析
      • coredns 存储中寻找
      • 没找到,去找宿主机 /etc/resolv.conf 文件,通过其中的 nameserver 再继续寻找
    3. 其他情况(不属于集群内的 service 域名),就找宿主机 /etc/resolv.conf 文件,通过其中的 nameserver 再继续寻找
    • 相当于 nodelocaldns 的搜索路径(nodelocaldns 可以理解为本地的 dns 缓存,coredns 为核心 dns 存储)

因此可知,环路原因为:

  • /etc/resolv.conf 存在 nodelocaldns 或 coredns 的 nameserver,导致继续查找,还找不到,形成一个环
  • 若 /etc/resolv.conf 配置了 nodelocaldns nameserver 或 coredns 搜索路径,那么寻找集群内 service 域名的 IP ,解析为如下路径
    1. nodelocaldns 缓存寻找 —— 没找到,跳到下一步
    2. 集群内服务域名,跳到 coredns 中寻找 ——没找到,跳到下一步
    3. 根据 /etc/resolv.conf 中的 nameserver 进行寻找,因为配置了 nodelocaldns 或 coredns 的 nameserver
      • 没找到 —— 根据 nameserver 的 nodelocaldns ip,跳到了第1步
      • 没找到 —— 根据 nameserver 的 coredns ip,跳到了第2步

因此一直在循环查找中,一直没找到,但一直循环查找,导致没有结果

coredns 配置文件

Corefile 配置包括以下 CoreDNS 插件:

  • errors:错误记录到标准输出。

  • health:在 http://localhost:8080/health 处提供 CoreDNS 的健康报告。

  • ready:在端口 8181 上提供的一个 HTTP 末端,当所有能够 表达自身就绪的插件都已就绪时,在此末端返回 200 OK。

  • kubernetes:CoreDNS 将基于 Kubernetes 的服务和 Pod 的 IP 答复 DNS 查询。你可以在 CoreDNS 网站阅读更多细节。 你可以使用 ttl 来定制响应的 TTL。默认值是 5 秒钟。TTL 的最小值可以是 0 秒钟, 最大值为 3600 秒。将 TTL 设置为 0 可以禁止对 DNS 记录进行缓存。

    pods insecure 选项是为了与 kube-dns 向后兼容。你可以使用 pods verified 选项,该选项使得 仅在相同名称空间中存在具有匹配 IP 的 Pod 时才返回 A 记录。如果你不使用 Pod 记录,则可以使用 pods disabled 选项。

  • prometheus:CoreDNS 的度量指标值以 Prometheus 格式在 http://localhost:9153/metrics 上提供。

  • forward: 不在 Kubernetes 集群域内的任何查询都将转发到 预定义的解析器 (/etc/resolv.conf).

  • cache:启用前端缓存。

  • loop:检测到简单的转发环,如果发现死循环,则中止 CoreDNS 进程。

  • reload:允许自动重新加载已更改的 Corefile。 编辑 ConfigMap 配置后,请等待两分钟,以使更改生效。

  • loadbalance:这是一个轮转式 DNS 负载均衡器, 它在应答中随机分配 A、AAAA 和 MX 记录的顺序。

你可以通过修改 ConfigMap 来更改默认的 CoreDNS 行为。

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
            lameduck 5s
        }
        ready
        # 指明 cluster.local 后缀的域名,都是 kubernetes 内部域名,coredns 会监听 service 的变化来维护域名关系
        # 所以cluster.local 相关域名都在这里解析
        # kubernetes 插件介绍 https://coredns.io/plugins/kubernetes/
        kubernetes cluster.local in-addr.arpa ip6.arpa {
        	# pods insecure 为了与 kube-dns 向后兼容。
        	# 你可以使用 pods verified 选项,该选项使得 仅在相同名称空间中存在具有匹配 IP 的 Pod 时才返回 A 记录。
        	# 如果你不使用 Pod 记录,则可以使用 pods disabled 选项。
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
        }
        # # CoreDNS 的监控地址为:http://localhost:9153/metrics 
        prometheus :9153
        # proxy 指 coredns 中没有找到记录,则去 /etc/resolv.conf 中的 nameserver 请求解析,而 coredns 容器中的 /etc/resolv.conf 是继承自宿主机的。
        # 实际效果是如果不是 k8s 内部域名,就会去默认的 dns 服务器请求解析,并返回给 coredns 的请求者。
        forward . /etc/resolv.conf {
          prefer_udp
        }
        cache 30  	# 允许缓存
        loop				# 如果找到循环,则检测简单的转发循环并停止 CoreDNS 进
        reload			# 允许 Corefile 的配置自动更新。在更改 ConfigMap 后两分钟,修改生效
        loadbalance	# 这是一个循环 DNS 负载均衡器,可以在答案中随机化 A,AAAA 和 MX 记录的顺序
    }
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"Corefile":".:53 {\n    errors\n    health {\n        lameduck 5s\n    }\n    ready\n    kubernetes cluster.local in-addr.arpa ip6.arpa {\n      pods insecure\n      fallthrough in-addr.arpa ip6.arpa\n    }\n    prometheus :9153\n    forward . /etc/resolv.conf {\n      prefer_udp\n    }\n    cache 30\n    loop\n    reload\n    loadbalance\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"addonmanager.kubernetes.io/mode":"EnsureExists"},"name":"coredns","namespace":"kube-system"}}
  creationTimestamp: "2022-08-07T13:57:10Z"
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
  name: coredns
  namespace: kube-system
  resourceVersion: "959"
  uid: 4d28f52c-494d-44e5-9fd4-d91eb8d2a893

nodelocaldns配置文件

apiVersion: v1
data:
  Corefile: |
    cluster.local:53 {
        errors
        cache {
            success 9984 30	# 对于成功的缓存最多缓存9984条域名解析记录,缓存时间为30s
            denial 9984 5		# 对于失败的缓存最多缓存9984条域名解析记录,缓存时间为5s
        }
        reload
        loop
        bind 169.254.25.10
        forward . 10.233.0.3 {
            force_tcp
        }
        prometheus :9253
        health 169.254.25.10:9254
    }
    in-addr.arpa:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.25.10
        forward . 10.233.0.3 {
            force_tcp
        }
        prometheus :9253
    }
    ip6.arpa:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.25.10
        forward . 10.233.0.3 {
            force_tcp
        }
        prometheus :9253
    }
    .:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.25.10
        forward . /etc/resolv.conf
        prometheus :9253
    }
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"Corefile":"cluster.local:53 {\n    errors\n    cache {\n        success 9984 30\n        denial 9984 5\n    }\n    reload\n    loop\n    bind 169.254.25.10\n    forward . 10.233.0.3 {\n        force_tcp\n    }\n    prometheus :9253\n    health 169.254.25.10:9254\n}\nin-addr.arpa:53 {\n    errors\n    cache 30\n    reload\n    loop\n    bind 169.254.25.10\n    forward . 10.233.0.3 {\n        force_tcp\n    }\n    prometheus :9253\n}\nip6.arpa:53 {\n    errors\n    cache 30\n    reload\n    loop\n    bind 169.254.25.10\n    forward . 10.233.0.3 {\n        force_tcp\n    }\n    prometheus :9253\n}\n.:53 {\n    errors\n    cache 30\n    reload\n    loop\n    bind 169.254.25.10\n    forward . /etc/resolv.conf\n    prometheus :9253\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"addonmanager.kubernetes.io/mode":"EnsureExists"},"name":"nodelocaldns","namespace":"kube-system"}}
  creationTimestamp: "2022-08-07T13:57:15Z"
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
  name: nodelocaldns
  namespace: kube-system
  resourceVersion: "1032"
  uid: 6986875b-4461-480c-98ea-0c334e175768

你可能感兴趣的:(网络学习笔记,k8s排错及配置,Kubernetes学习笔记,kubernetes,容器,云原生)