• 【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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    使用 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    宿主机环路问题

    [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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    为什么会环路

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

    • 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
  • 相关阅读:
    系统移植第5天作业
    第五课:C++实现加密PDF文档解密
    .NET周报 【2月第2期 2023-02-11】
    可能是2022最详细的【Java SE 】顺序结构、分支结构、循环结构讲解
    idea plugin demo
    如何预防最新的Mallox变种malloxx勒索病毒感染您的计算机?
    机器人的组成
    15.位操作
    不小心清空了回收站怎么恢复,回收站删除的东西可以恢复吗
    新恒盛110kV变电站智能辅助系统综合监控平台+道巡检机器人
  • 原文地址:https://blog.csdn.net/qq_24433609/article/details/126548498