K8s域名解析方案CoreDNS(K8s Domain Name Resolution Solution CoreDNS)

 💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

本人主要分享计算机核心技术:系统维护、数据库、网络安全、自动化运维、容器技术、云计算、人工智能、运维开发、算法结构、物联网、JAVA 、Python、PHP、C、C++等。
不同类型针对性训练,提升逻辑思维,剑指大厂,非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。

Kubernetes的域名解析方案CoreDNS

1. CoreDNS与Kubernetes

1.1 CoreDNS简介

CoreDNS 是一个灵活可扩展的 DNS 服务器,可以作为 Kubernetes 集群 DNS。与 Kubernetes 一样,CoreDNS 项目由 CNCF 托管。

借助CoreDNS 服务器,可以将 Kubernetes 服务名称解析为相应的 IP 地址。支持正向查找(A 和 AAAA 记录)、端口发现(SRV 记录)、反向 IP 地址发现(PTR 记录)等。

通过替换现有集群部署中的 kube-dns,或者使用 kubeadm 等工具来为你部署和升级集群,可以在你的集群中使用 CoreDNS 而非 kube-dns。

1.2 CoreDNS 插件架构

CoreDNS是一种灵活、可扩展的 DNS 服务器,借助插件架构,允许用户根据需求自定义功能。与其他 DNS 服务器BIND、Knot、PowerDNS不同,CoreDNS 非常灵活,几乎所有功能都交给插件去实现。

默认的 CoreDNS 安装中包含了大约 30 个插件,还可以编译许多外部插件到 CoreDNS 中,以扩展其功能。

CoreDNS 的插件架构使其具有很强的可扩展性。每个插件负责处理特定类型的 DNS 请求或提供特定的功能。例如:

  • kubernetes 插件:用于解析 Kubernetes 服务和 Pod 的 DNS 名称。

  • hosts 插件:用于从 hosts 文件中解析名称。

  • file 插件:用于从区域文件中解析名称。

1.3 版本配套情况

Kubernetes从1.09版本开始支持CoreDNS作为集群的DNS应用。在 Kubernetes 1.21 版本中,kubeadm 移除了对将 kube-dns 作为 DNS 应用的支持;在 kubeadm v1.31,CoreDNS是支持的唯一的集群 DNS 应用。

当你使用 kubeadm 升级使用 kube-dns 的集群时,你还可以执行到 CoreDNS 的迁移。在这种场景中,kubeadm 将基于 kube-dns ConfigMap 生成 CoreDNS 配置("Corefile"), 保存存根域和上游名称服务器的配置。

Kubernetes 中的 CoreDNS 版本 页面记录了 kubeadm 安装的 Kubernetes 版本和 CoreDNS 版本配套关系。以下是部分内容:

Kubernetes VersionCoreDNS version installed by kubeadmChanges in CoreDNS from previous release to Kubernetes
v1.30v1.11.1
v1.29v1.11.1
v1.28v1.10.1
v1.27v1.10.1
v1.26v1.9.3
v1.25v1.9.3
v1.24v1.8.6
v1.23v1.8.6https://github.com/coredns/coredns/blob/master/notes/coredns-1.8.5.md https://github.com/coredns/coredns/blob/master/notes/coredns-1.8.6.md
v1.22v1.8.4https://github.com/coredns/coredns/blob/master/notes/coredns-1.8.1.md https://github.com/coredns/coredns/blob/master/notes/coredns-1.8.2.md https://github.com/coredns/coredns/blob/master/notes/coredns-1.8.3.md https://github.com/coredns/coredns/blob/master/notes/coredns-1.8.4.md  ---NOTE--- CoreDNS must be granted list and watch access to EndpointSlices
v1.21v1.8.0https://github.com/coredns/coredns/blob/master/notes/coredns-1.7.1.md https://github.com/coredns/coredns/blob/master/notes/coredns-1.8.0.md  ---DEPRECATIONS---  The transfer option in the kubernetes plugin has been removed. Zone transfers can be enabled with the new transfer plugin.
v1.20v1.7.0
.........
v1.09v1.0.1The v1.0.1 was the first version of CoreDNS to be shipped with Kubernetes.

1.4 CoreDNS在kubernetes下的工作原理

CoreDNS 在 Kubernetes 中作为一个 Deployment 运行,通常会部署两个或多个副本以确保高可用性。它主要通过以下步骤工作:

  • 启动与配置:CoreDNS 读取 ConfigMap 配置文件,根据配置启动相应的插件。

  • 监听 DNS 请求:CoreDNS 监听来自 Kubernetes 集群内部的 DNS 请求。

  • 解析 DNS 请求:根据请求的类型,CoreDNS 调用相应的插件进行解析。例如,对于 kube-dns 插件,CoreDNS 会查询 Kubernetes API 服务器以获取服务的 IP 地址。

  • 返回解析结果:将解析结果返回给请求方。

2. 理解CoreDNS配置

下面是由kubeadm附带的CoreDNS配置,保存在kubernetes集群名为coredns的configmap中:

[root@k8s ~]# kubectl -n kube-system get configmap coredns -oyaml
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local 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
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2024-06-11T14:02:11Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "250"
  uid: 3b716ad5-50a7-4d87-9178-a47797b91c8a

.:53: 这里的 . 表示 CoreDNS 处理所有域名请求(根域名),53 是 CoreDNS 监听的端口号(标准 DNS 端口)。

Corefile 部分是 CoreDNS 的配置。这份配置基于以下 CoreDNS 插件:

  • errors:errors 插件会将错误信息输出到 标准输出。当 DNS 请求过程中发生错误时,该插件会将错误日志记录下来,方便调试和排错。

  • health:health 插件提供了一个 HTTP 健康检查接口,默认监听地址是 http://localhost:8080/health,提供 CoreDNS 的健康报告。kubelet 会定期检查 CoreDNS 的健康状况,确定其是否正常运行。lameduck 是一个新增加的选项。它指定在 CoreDNS 被标记为不健康后,CoreDNS 在关闭之前仍然会继续响应请求的时间(这里是 5 秒)。这允许在 CoreDNS 实例停止或被替换时,已有的请求有一个缓冲期可以继续完成,而不会立即中断。

  • ready:ready 插件用于确保在 CoreDNS 完全准备好处理 DNS 请求之前,不会将其标记为可用,在端口 8181 上提供的一个 HTTP 端点, 当所有能够表达自身就绪的插件都已就绪时,在此端点返回 200 OK。这在启动时非常有用,确保其他服务只有在 CoreDNS 完全加载所有配置并处于健康状态时,才会开始依赖它的解析服务。

  • kubernetes:kubernetes 插件是 CoreDNS 的核心部分,它为 Kubernetes 集群提供 DNS 服务,基于服务和 Pod 的 IP 来应答 DNS 查询。。

    • kubernetes 插件根据 Kubernetes 的服务和 Pod 的 IP 地址解析 DNS 查询。

    • cluster.local 是默认的 Cluster Domain(集群域名),即服务的默认后缀,比如 foo.default.svc.cluster.local

    • in-addr.arpa 和 ip6.arpa 处理反向 DNS 查询(将 IP 地址解析为域名)。

    • pods insecure 选项表示为了向后兼容 kube-dns。

    • fallthrough 选项用于指定如果某个域没有被 CoreDNS 处理,则将该请求传递给下一个 DNS 解析插件处理。

    • ttl选项用于定制响应的 TTL。默认值是 5 秒钟。TTL 的最小值可以是 0 秒钟, 最大值为 3600 秒。将 TTL 设置为 0 可以禁止对 DNS 记录进行缓存。

  • prometheus:prometheus 插件用于暴露 CoreDNS 的指标,供 Prometheus 监控系统收集。CoreDNS 的度量指标值以 Prometheus 格式(也称为 OpenMetrics)在 http://localhost:9153/metrics 上提供。

  • forward:不在 Kubernetes 集群域内的任何查询都将转发到预定义的解析器 (/etc/resolv.conf)。max_concurrent 1000 指定了 forward 插件在处理 DNS 查询时的最大并发请求数,这里设置为 1000。这个选项可以限制 CoreDNS 向上游 DNS 服务器同时发出的请求数量,避免因为过多的并发查询导致上游服务器超载或 DNS 查询超时。

  • cache:cache 插件用于启用前端缓存,以提高 DNS 查询的响应速度并减少对上游 DNS 服务器的依赖。即当 DNS 请求命中缓存时,会直接返回缓存结果,而不再进行外部查询。这里配置 30 秒的DNS 解析缓存生存时间(TTL),TTL 控制了客户端的 DNS 缓存持续时间,TTL 较短意味着 DNS 解析会更频繁地更新,而较长的 TTL 可以减少解析请求的频率,但可能会延迟变更的生效。

  • loop:loop 插件用于检测和防止 DNS 循环(DNS 循环是指 DNS 请求在多级 DNS 服务器之间不断循环而无法得到解析结果的情况)。如果发现死循环,则中止 CoreDNS 进程。

  • reload: reload 插件允许 CoreDNS 在 Corefile 文件内容发生变更时自动重新加载配置。当你对 Corefile 文件进行修改后,不需要重启 CoreDNS 进程,它会自动应用新的配置。编辑 ConfigMap 配置后,请等待两分钟,以使更改生效。

  • loadbalance: 这是一个轮转式 DNS 负载均衡器, 它在应答中随机分配 A、AAAA 和 MX 记录的顺序。这对分散流量到多个后端服务特别有用。

此外,在较老版本中,DNS转发配置还可能见到upstreamproxy配置。

# kubectl -n kube-system get configmap coredns -oyaml
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health
        kubernetes cluster.local 10.96.0.0/12 {
           pods insecure
           upstream /etc/resolv.conf
        }
        prometheus :9153
        proxy . /etc/resolv.conf
        cache 30
    }
kind: ConfigMap
metadata:
  creationTimestamp: 2017-12-21T12:55:15Z
  name: coredns
  namespace: kube-system
  resourceVersion: "161"
  selfLink: /api/v1/namespaces/kube-system/configmaps/coredns
  uid: 30bf0882-e64e-11e7-baf6-0cc47a8055d6

在较新的版本中,上述功能已经被forward插件替代。

3. CoreDNS功能验证

在CoreDNS部署运行正常后,测试Kubernetes内部域名的解析功能:

[root@k8s ~]# kubectl get svc -A
NAMESPACE      NAME                  TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                   AGE
default        kubernetes            ClusterIP      10.96.0.1        <none>        443/TCP                   80d
harbor         harbor-core           ClusterIP      10.101.2.50      <none>        80/TCP                    47d
harbor         harbor-database       ClusterIP      10.99.23.171     <none>        5432/TCP                  47d
harbor         harbor-jobservice     ClusterIP      10.99.108.96     <none>        80/TCP                    47d
harbor         harbor-portal         ClusterIP      10.99.110.218    <none>        80/TCP                    47d
harbor         harbor-redis          ClusterIP      10.103.117.94    <none>        6379/TCP                  47d
harbor         harbor-registry       ClusterIP      10.104.89.36     <none>        5000/TCP,8080/TCP         47d
harbor         harbor-trivy          ClusterIP      10.107.222.192   <none>        8080/TCP                  47d
kube-system    kube-dns              ClusterIP      10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP    80d
kubernetes-dashboard   dashboard-metrics-scraper    ClusterIP 10.102.9.117    <none>        8000/TCP         76d
kubernetes-dashboard   kubernetes-dashboard    NodePort  10.97.21.53      <none>        443:31930/TCP        76d

# 在节点上使用dig命令解析kubernetes服务,指定dns为kube-dns
[root@k8s ~]# dig @10.96.0.10  kubernetes.default.svc.cluster.local +noall +answer

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> @10.96.0.10 kubernetes.default.svc.cluster.local +noall +answer
; (1 server found)
;; global options: +cmd
kubernetes.default.svc.cluster.local. 30 IN A   10.96.0.1

# 解析 kubernetes-dashboard服务
[root@k8s ~]# dig @10.96.0.10  kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local +noall +answer

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> @10.96.0.10 kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local +noall +answer
; (1 server found)
;; global options: +cmd
kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local. 30 IN A 10.97.21.53

# 在容器内部解析集群服务域名
[root@k8s ~]# kubectl run -i --tty --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default.svc.cluster.local

Server:         10.96.0.10
Address:        10.96.0.10:53

Name:   kubernetes.default.svc.cluster.local
Address: 10.96.0.1


pod "debug" deleted

可以看到通过dig指定kube-dns解析集群内的svc,可以获取到svc对应的IP。

4. 使用CoreDNS配置外部域名解析

4.1 使用 CoreDNS 配置存根域和上游域名服务器

CoreDNS 能够使用 forward 插件配置存根域和上游域名服务器,这样对于非Kubernetes集群的域名访问,可以将解析任务交给上游域名服务器。示例如下:

如果集群操作员在 "10.150.0.1" 处运行了 Consul 域服务器, 且所有 Consul 名称都带有后缀 .consul.local。要在 CoreDNS 中对其进行配置, 集群管理员可以在 CoreDNS 的 ConfigMap 中创建加入以下字段。

consul.local:53 {
    errors
    cache 30
    forward . 10.150.0.1
}

要显式强制所有非集群 DNS 查找通过特定的域名服务器(位于 172.16.0.1),可将 forward 指向该域名服务器,而不是 /etc/resolv.conf

forward .  172.16.0.1

最终的包含默认的 Corefile 配置的 ConfigMap 如下所示:

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . 172.16.0.1
        cache 30
        loop
        reload
        loadbalance
    }
    consul.local:53 {
        errors
        cache 30
        forward . 10.150.0.1
    }    

说明:

CoreDNS 不支持 FQDN 作为存根域和域名服务器(例如 "ns.foo.com")。转换期间,CoreDNS 配置中将忽略所有的 FQDN 域名服务器。

4.2 配置hosts解析

CoreDNS 的 hosts 插件用于将域名解析指向固定的 IP 地址,类似于操作系统中的 /etc/hosts 文件。该插件允许将域名解析存储在 CoreDNS 的配置中,以便在 CoreDNS 收到相应的查询时,直接返回这些 IP 地址,而无需再向上游 DNS 服务器请求解析。

hosts 插件配置示例

以下是一个简单的 Corefile 示例,展示了如何配置 hosts 插件:

.:53 {
    errors
    health
    hosts /etc/coredns/hosts {
        ttl 60
        fallthrough
    }
    kubernetes cluster.local in-addr.arpa ip6.arpa
    prometheus :9153
    forward . 8.8.8.8
    cache 30
    reload
    loadbalance
}

解释:

  1. hosts /etc/coredns/hosts:

    指定一个外部的 hosts 文件(类似于 /etc/hosts),该文件中包含域名与 IP 地址的静态映射。例如:

    192.168.1.10 example.com
    192.168.1.20 another-example.com
    

    CoreDNS 会读取此文件,并根据文件中的映射返回相应的 IP 地址。

  2. ttl 60: 指定返回的 DNS 记录的生存时间(TTL),这里设置为 60 秒。也就是说,客户端可以在 60 秒内缓存这个解析结果。

  3. fallthrough: 如果查询的域名不在 hosts 文件中,将继续传递给下一个插件处理,比如 kubernetes 或 forward 插件。如果不加这个选项,未匹配到的查询会被丢弃。

内联配置 hosts

hosts 插件也可以直接在 Corefile 中定义静态域名解析,不依赖于外部的 hosts 文件:

.:53 {
    errors
    health
    hosts {
        192.168.1.10 example.com
        192.168.1.20 another-example.com
        fallthrough
    }
    kubernetes cluster.local in-addr.arpa ip6.arpa
    prometheus :9153
    forward . 8.8.8.8
    cache 30
    reload
    loadbalance
}

5. CoreDNS的安装、迁移及升级

5.1 安装 CoreDNS

如果是较新版本的kubeadm部署的Kubernetes环境,默认就会使用CoreDNS作为默认DNS方案。有关手动部署或替换 kube-dns,请参阅 CoreDNS 网站。

5.2 迁移到CoreDNS

在 Kubernetes 1.21 版本中,kubeadm 移除了对将 kube-dns 作为 DNS 应用的支持。对于 kubeadm v1.31,所支持的唯一的集群 DNS 应用是 CoreDNS。

当你使用 kubeadm 升级使用 kube-dns 的集群时,你还可以执行到 CoreDNS 的迁移。在这种场景中,kubeadm 将基于 kube-dns ConfigMap 生成 CoreDNS 配置("Corefile"), 保存存根域和上游名称服务器的配置。

5.3 升级 CoreDNS

如果你只想升级 CoreDNS 或使用自己的定制镜像,也可以手动升级 CoreDNS。参看指南和演练 文档了解如何平滑升级。在升级你的集群过程中,请确保现有 CoreDNS 的配置("Corefile")被保留下来。

如果使用 kubeadm 工具来升级集群,则 kubeadm 可以自动处理保留现有 CoreDNS 配置这一事项。

如果使用 kubeadm 工具来升级集群,则 kubeadm 可以自动处理保留现有 CoreDNS 配置这一事项。

6. DNS 问题排查

如果DNS解析遇到问题,可以参考下面的流程进行troubshooting,内容参考自调试 DNS 问题 | Kubernetes。

6.1 创建一个简单的 Pod 作为测试环境(可选)

创建一个Pod用作测试环境。

# admin/dns/dnsutils.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dnsutils
  namespace: default
spec:
  containers:
  - name: dnsutils
    image: registry.k8s.io/e2e-test-images/jessie-dnsutils:1.3
    command:
      - sleep
      - "infinity"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always

说明:

此示例在 default 名字空间创建 Pod。DNS 名字解析取决于 Pod 的名字空间。详细信息请查阅 Pod 与 Service 的 DNS。

使用上面的清单来创建一个 Pod:

kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
pod/dnsutils created

验证其状态:

kubectl get pods dnsutils
NAME       READY     STATUS    RESTARTS   AGE
dnsutils   1/1       Running   0          <some-time>

一旦 Pod 处于运行状态,你就可以在该环境里执行 nslookup。如果你看到类似下列的内容,则表示 DNS 是正常运行的。

kubectl exec -i -t dnsutils -- nslookup kubernetes.default

输出为:

Server:    10.0.0.10
Address 1: 10.0.0.10

Name:      kubernetes.default
Address 1: 10.0.0.1

如果 nslookup 命令执行失败,按照下面的思路进行排查。

6.2 排查思路

这里以上面创建的jessie-dnsutils作为示例说明一下排查思路,实践中可根据自己的环境对有问题的应用进行排查。

先检查本地的 DNS 配置

查看 resolv.conf 文件的内容:

kubectl exec -ti dnsutils -- cat /etc/resolv.conf

验证 search 和 nameserver 的配置是否与下面的内容类似 (注意 search 根据不同的云提供商可能会有所不同):

search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
nameserver 10.0.0.10 # 10.0.0.10为kube-dns的svc cluster-ip
options ndots:5

下列错误表示 CoreDNS (或 kube-dns)插件或者相关服务出现了问题:

kubectl exec -i -t dnsutils -- nslookup kubernetes.default

输出为:

Server:    10.0.0.10
Address 1: 10.0.0.10

nslookup: can't resolve 'kubernetes.default'

提示无法解析'kubernetes.default

检查 DNS Pod 是否运行

使用 kubectl get pods 命令来验证 DNS Pod 是否运行。

kubectl get pods --namespace=kube-system -l k8s-app=kube-dns

输出为:

NAME                       READY     STATUS    RESTARTS   AGE
...
coredns-7b96bf9f76-5hsxb   1/1       Running   0           1h
coredns-7b96bf9f76-mvmmt   1/1       Running   0           1h
...

说明:

对于 CoreDNS 和 kube-dns 部署而言,标签 k8s-app 的值都应该是 kube-dns

如果你发现没有 CoreDNS Pod 在运行,或者该 Pod 的状态是 failed 或者 completed, 那可能这个 DNS 插件在你当前的环境里并没有成功部署,你将需要手动去部署它。

检查 DNS Pod 里的错误

使用 kubectl logs 命令来查看 DNS 容器的日志信息。

如查看 CoreDNS 的日志信息:

kubectl logs --namespace=kube-system -l k8s-app=kube-dns

下列是一个正常运行的 CoreDNS 日志信息:

.:53
2018/08/15 14:37:17 [INFO] CoreDNS-1.2.2
2018/08/15 14:37:17 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.2
linux/amd64, go1.10.3, 2e322f6
2018/08/15 14:37:17 [INFO] plugin/reload: Running configuration MD5 = 24e6c59e83ce706f07bcc82c31b1ea1c

查看是否日志中有一些可疑的或者意外的消息。

检查是否启用了 DNS 服务

使用 kubectl get service 命令来检查 DNS 服务是否已经启用。

kubectl get svc --namespace=kube-system

输出为:

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
...
kube-dns     ClusterIP   10.0.0.10      <none>        53/UDP,53/TCP        1h
...

说明

不管是 CoreDNS 还是 kube-dns,这个服务的名字都会是 kube-dns

如果你已经创建了 DNS 服务,或者该服务应该是默认自动创建的但是它并没有出现, 请阅读调试服务 来获取更多信息。

DNS 的端点公开了吗?

你可以使用 kubectl get endpoints 命令来验证 DNS 的端点是否公开了。

kubectl get endpoints kube-dns --namespace=kube-system
NAME       ENDPOINTS                       AGE
kube-dns   10.180.3.17:53,10.180.3.17:53    1h

如果你没看到对应的端点,请阅读 调试服务的端点部分。

DNS 查询有被接收或者执行吗?

你可以通过给 CoreDNS 的配置文件(也叫 Corefile)添加 log 插件来检查查询是否被正确接收。CoreDNS 的 Corefile 被保存在一个叫 coredns 的 ConfigMap 里,使用下列命令来编辑它:

kubectl -n kube-system edit configmap coredns

然后按下面的例子给 Corefile 添加 log

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        log
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          upstream
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }    

保存这些更改后,你可能会需要等待一到两分钟让 Kubernetes 把这些更改应用到 CoreDNS 的 Pod 里。

接下来,发起一些查询并依照前文所述查看日志信息,如果 CoreDNS 的 Pod 接收到这些查询, 你将可以在日志信息里看到它们。

下面是日志信息里的查询例子:

.:53
2018/08/15 14:37:15 [INFO] CoreDNS-1.2.0
2018/08/15 14:37:15 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.0
linux/amd64, go1.10.3, 2e322f6
2018/09/07 15:29:04 [INFO] plugin/reload: Running configuration MD5 = 162475cdf272d8aa601e6fe67a6ad42f
2018/09/07 15:29:04 [INFO] Reloading complete
172.17.0.18:41675 - [07/Sep/2018:15:29:11 +0000] 59925 "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd,ra 106 0.000066649s
CoreDNS 是否有足够的权限?

CoreDNS 必须能够列出 service 和 endpoint 相关的资源来正确解析服务名称。

示例错误消息:

2022-03-18T07:12:15.699431183Z [INFO] 10.96.144.227:52299 - 3686 "A IN serverproxy.contoso.net.cluster.local. udp 52 false 512" SERVFAIL qr,aa,rd 145 0.000091221s

首先,获取当前的 ClusterRole system:coredns

kubectl describe clusterrole system:coredns -n kube-system

预期输出:

PolicyRule:
  Resources                        Non-Resource URLs  Resource Names  Verbs
  ---------                        -----------------  --------------  -----
  endpoints                        []                 []              [list watch]
  namespaces                       []                 []              [list watch]
  pods                             []                 []              [list watch]
  services                         []                 []              [list watch]
  endpointslices.discovery.k8s.io  []                 []              [list watch]

如果缺少任何权限,请编辑 ClusterRole 来添加它们:

kubectl edit clusterrole system:coredns -n kube-system

EndpointSlices 权限的插入示例:

...
- apiGroups:
  - discovery.k8s.io
  resources:
  - endpointslices
  verbs:
  - list
  - watch
...
你的服务在正确的名字空间中吗?

未指定名字空间的 DNS 查询仅作用于 Pod 所在的名字空间。如果 Pod 和服务的名字空间不相同,则 DNS 查询必须指定服务所在的名字空间。

该查询仅限于 Pod 所在的名字空间:

kubectl exec -i -t dnsutils -- nslookup <service-name>

指定名字空间的查询:

kubectl exec -i -t dnsutils -- nslookup <service-name>.<namespace>

要进一步了解名字解析,请查看 Pod 与 Service 的 DNS。

6.3 已知问题

有些 Linux 发行版本(比如 Ubuntu)默认使用一个本地的 DNS 解析器(systemd-resolved)。systemd-resolved 会用一个存根文件(Stub File)来覆盖 /etc/resolv.conf 内容, 从而可能在上游服务器中解析域名产生转发环(forwarding loop)。这个问题可以通过手动指定 kubelet 的 --resolv-conf 标志为正确的 resolv.conf(如果是 systemd-resolved, 则这个文件路径为 /run/systemd/resolve/resolv.conf)来解决。kubeadm 会自动检测 systemd-resolved 并对应的更改 kubelet 的命令行标志。

Kubernetes 的安装并不会默认配置节点的 resolv.conf 文件来使用集群的 DNS 服务,因为这个配置对于不同的发行版本是不一样的。这个问题应该迟早会被解决的。

Linux 的 libc(又名 glibc)默认将 DNS nameserver 记录限制为 3, 而 Kubernetes 需要使用 1 条 nameserver 记录。这意味着如果本地的安装已经使用了 3 个 nameserver,那么其中有些条目将会丢失。要解决此限制,节点可以运行 dnsmasq,以提供更多 nameserver 条目。你也可以使用 kubelet 的 --resolv-conf 标志来解决这个问题。

如果你使用 Alpine 3.17 或更早版本作为你的基础镜像,DNS 可能会由于 Alpine 的设计问题而无法工作。在 musl 1.24 版本之前,DNS 存根解析器都没有包括 TCP 回退, 这意味着任何超过 512 字节的 DNS 调用都会失败。请将你的镜像升级到 Alpine 3.18 或更高版本。

CoreDNS是一个用于Kubernetes集群的域名解析器。它负责将域名解析为相应的IP地址,以便Kubernetes集群中的各个组件可以相互通信。 当coredns解析k8s域名偶尔失败时,可能是由于以下几个原因: 1. 配置错误:coredns的配置文件可能存在错误,导致解析过程中出现问题。可以通过检查coredns的配置文件来确认是否存在错误,并进行相应的修复。 2. 网络问题:解析k8s域名的过程中,可能出现网络问题,导致解析失败。这可能是由于网络延迟、故障或不稳定等原因引起的。可以通过检查网络连接、排除网络故障来解决此问题。 3. DNS缓存问题:coredns可能会在本地缓存解析结果,以提高性能并减少对外部DNS服务器的依赖。但有时候,这些缓存可能过期或损坏,导致解析失败。可以尝试清除corednsDNS缓存,并重新进行解析。 4. 资源不足:在解析域名时,coredns可能会耗尽CPU、内存或网络资源,导致解析失败。可以通过增加集群的资源配额或调整coredns的资源限制来解决此问题。 5. 其他故障:还有一些其他因素可能导致coredns解析k8s域名失败,例如coredns的版本问题、操作系统或硬件故障等。可以尝试升级coredns到最新版本,或者联系相关技术支持人员进行故障排除和解决。 总之,当coredns解析k8s域名偶尔失败时,我们需要综合考虑可能的原因,并采取相应的措施进行故障排除和解决。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux运维老纪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值