【重识云原生】第六章容器基础6.4.9.6节——Service 与 Pod 的DNS

2022-11-21 11:04:59 浏览数 (1)

 1 Service 与 Pod 的 DNS

        Kubernetes 为 Service 和 Pod 创建 DNS 记录。 你可以使用一致的 DNS 名称而非 IP 地址访问 Service。

        Kubernetes DNS 除了在集群上调度 DNS Pod 和 Service, 还配置 kubelet 以告知各个容器使用 DNS Service 的 IP 来解析 DNS 名称。

        集群中定义的每个 Service (包括 DNS 服务器自身)都被赋予一个 DNS 名称。 默认情况下,客户端 Pod 的 DNS 搜索列表会包含 Pod 自身的命名空间和集群的默认域。

1.1 Service 的命名空间

        DNS 查询可能因为执行查询的 Pod 所在的命名空间而返回不同的结果。 不指定命名空间的 DNS 查询会被限制在 Pod 所在的命名空间内。 要访问其他命名空间中的 Service,需要在 DNS 查询中指定命名空间。

        例如,假定命名空间 test 中存在一个 Pod,prod 命名空间中存在一个服务 data。

        Pod 查询 data 时没有返回结果,因为使用的是 Pod 的命名空间 test。

        Pod 查询 data.prod 时则会返回预期的结果,因为查询中指定了命名空间。

        DNS 查询可以使用 Pod 中的 /etc/resolv.conf 展开。kubelet 会为每个 Pod 生成此文件。例如,对 data 的查询可能被展开为 data.test.svc.cluster.local。 search 选项的取值会被用来展开查询。要进一步了解 DNS 查询,可参阅 resolv.conf 手册页面。

代码语言:javascript复制
nameserver 10.32.0.10 
search <namespace>.svc.cluster.local svc.cluster.local cluster.local 
options ndots:5

        概括起来,命名空间 test 中的 Pod 可以成功地解析 data.prod 或者data.prod.svc.cluster.local。

1.2 DNS 记录

哪些对象会获得 DNS 记录呢?

  1. Services
  2. Pods

        以下各节详细介绍已支持的 DNS 记录类型和布局。 其它布局、名称或者查询即使碰巧可以工作,也应视为实现细节, 将来很可能被更改而且不会因此发出警告。 有关最新规范请查看 Kubernetes 基于 DNS 的服务发现。

1.2.1 Service的DNS记录

1.2.1.1 A/AAAA 记录

        “普通” Service(除了无头 Service)会以 my-svc.my-namespace.svc.cluster-domain.example 这种名字的形式被分配一个 DNS A 或 AAAA 记录,取决于 Service 的 IP 协议族。 该名称会解析成对应 Service 的集群 IP。

        “无头(Headless)” Service (没有集群 IP)也会以 my-svc.my-namespace.svc.cluster-domain.example 这种名字的形式被指派一个 DNS A 或 AAAA 记录, 具体取决于 Service 的 IP 协议族。 与普通 Service 不同,这一记录会被解析成对应 Service 所选择的 Pod IP 的集合。 客户端要能够使用这组 IP,或者使用标准的轮转策略从这组 IP 中进行选择。

1.2.1.2 SRV 记录

        Kubernetes 根据普通 Service 或 Headless Service 中的命名端口创建 SRV 记录。每个命名端口, SRV 记录格式为 _my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster-domain.example。 普通 Service,该记录会被解析成端口号和域名:my-svc.my-namespace.svc.cluster-domain.example。 无头 Service,该记录会被解析成多个结果,及该服务的每个后端 Pod 各一个 SRV 记录, 其中包含 Pod 端口号和格式为 auto-generated-name.my-svc.my-namespace.svc.cluster-domain.example 的域名。

1.2.2 Pod的DNS记录

1.2.2.1 A/AAAA 记录

        一般而言,Pod 会对应如下 DNS 名字解析:

代码语言:javascript复制
pod-ip-address.my-namespace.pod.cluster-domain.example

        例如,对于一个位于 default 命名空间,IP 地址为 172.17.0.3 的 Pod, 如果集群的域名为 cluster.local,则 Pod 会对应 DNS 名称:

代码语言:javascript复制
172-17-0-3.default.pod.cluster.local

        通过 Service 暴露出来的所有 Pod 都会有如下 DNS 解析名称可用:

代码语言:javascript复制
pod-ip-address.service-name.my-namespace.svc.cluster-domain.example

1.2.2.2 Pod 的 hostname 和 subdomain 字段

        当前,创建 Pod 时其主机名取自 Pod 的 metadata.name 值。

        Pod 规约中包含一个可选的 hostname 字段,可以用来指定 Pod 的主机名。 当这个字段被设置时,它将优先于 Pod 的名字成为该 Pod 的主机名。 举个例子,给定一个 hostname 设置为 "my-host" 的 Pod, 该 Pod 的主机名将被设置为 "my-host"。

        Pod 规约还有一个可选的 subdomain 字段,可以用来指定 Pod 的子域名。 举个例子,某 Pod 的 hostname 设置为 “foo”,subdomain 设置为 “bar”, 在命名空间 “my-namespace” 中对应的完全限定域名(FQDN)为 “foo.bar.my-namespace.svc.cluster-domain.example”。

        示例:

代码语言:javascript复制
apiVersion: v1 
kind: Service 
metadata: 
  name: default-subdomain 
spec: 
  selector: 
    name: busybox 
  clusterIP: None 
  ports: 
    - name: foo # 实际上不需要指定端口号 
      port: 1234 
      targetPort: 1234 
--- 
apiVersion: v1 
kind: Pod 
metadata: 
  name: busybox1 
  labels: 
    name: busybox 
spec: 
  hostname: busybox-1 
  subdomain: default-subdomain 
  containers: 
    - image: busybox:1.28 
      command: 
        - sleep 
        - "3600" 
      name: busybox 
--- 
apiVersion: v1 
kind: Pod 
metadata: 
  name: busybox2 
  labels: 
    name: busybox 
spec: 
  hostname: busybox-2 
  subdomain: default-subdomain 
  containers:     
    - image: busybox:1.28 
      command: 
        - sleep 
        - "3600" 
      name: busybox

        如果某无头 Service 与某 Pod 在同一个命名空间中,且它们具有相同的子域名, 集群的 DNS 服务器也会为该 Pod 的全限定主机名返回 A 记录或 AAAA 记录。 例如,在同一个命名空间中,给定一个主机名为 “busybox-1”、 子域名设置为 “default-subdomain” 的 Pod,和一个名称为 “default-subdomain” 的无头 Service,Pod 将看到自己的 FQDN 为 "busybox-1.default-subdomain.my-namespace.svc.cluster-domain.example"。 DNS 会为此名字提供一个 A 记录或 AAAA 记录,指向该 Pod 的 IP。 “busybox1” 和 “busybox2” 这两个 Pod 分别具有它们自己的 A 或 AAAA 记录。

EndpointSlice 对象可以为任何端点地址及其 IP 指定 hostname。

说明: 由于不是为 Pod 名称创建 A 或 AAAA 记录的,因此 Pod 的 A 或 AAAA 需要 hostname。 没有设置 hostname 但设置了 subdomain 的 Pod 只会为 无头 Service 创建 A 或 AAAA 记录(default-subdomain.my-namespace.svc.cluster-domain.example) 指向 Pod 的 IP 地址。 另外,除非在服务上设置了 publishNotReadyAddresses=True,否则只有 Pod 进入就绪状态 才会有与之对应的记录。

1.2.2.3 Pod 的 setHostnameAsFQDN 字段特性状态: 

Kubernetes v1.22 [stable]

        当 Pod 配置为具有全限定域名 (FQDN) 时,其主机名是短主机名。 例如,如果你有一个具有完全限定域名 busybox-1.default-subdomain.my-namespace.svc.cluster-domain.example 的 Pod, 则默认情况下,该 Pod 内的 hostname 命令返回 busybox-1,而 hostname --fqdn 命令返回 FQDN。

        当你在 Pod 规约中设置了 setHostnameAsFQDN: true 时,kubelet 会将 Pod 的全限定域名(FQDN)作为该 Pod 的主机名记录到 Pod 所在命名空间。 在这种情况下,hostname 和 hostname --fqdn 都会返回 Pod 的全限定域名。

说明: 在 Linux 中,内核的主机名字段(struct utsname 的 nodename 字段)限定最多 64 个字符。

        如果 Pod 启用这一特性,而其 FQDN 超出 64 字符,Pod 的启动会失败。 Pod 会一直出于 Pending 状态(通过 kubectl 所看到的 ContainerCreating), 并产生错误事件,例如 "Failed to construct FQDN from Pod hostname and cluster domain, FQDN long-FQDN is too long (64 characters is the max, 70 characters requested)." (无法基于 Pod 主机名和集群域名构造 FQDN,FQDN long-FQDN 过长,至多 64 个字符,请求字符数为 70)。 对于这种场景而言,改善用户体验的一种方式是创建一个 准入 Webhook 控制器, 在用户创建顶层对象(如 Deployment)的时候控制 FQDN 的长度。

1.2.2.4 Pod 的 DNS 策略

        DNS 策略可以逐个 Pod 来设定。目前 Kubernetes 支持以下特定 Pod 的 DNS 策略。 这些策略可以在 Pod 规约中的 dnsPolicy 字段设置:

  • "Default": Pod 从运行所在的节点继承名称解析配置。 参考相关讨论获取更多信息。
  • "ClusterFirst": 与配置的集群域后缀不匹配的任何 DNS 查询(例如 "www.kubernetes.io") 都将转发到从节点继承的上游名称服务器。集群管理员可能配置了额外的存根域和上游 DNS 服务器。 参阅相关讨论 了解在这些场景中如何处理 DNS 查询的信息。
  • "ClusterFirstWithHostNet":对于以 hostNetwork 方式运行的 Pod,应显式设置其 DNS 策略 "ClusterFirstWithHostNet"。
    • 注意:这在 Windows 上不支持。 有关详细信息,请参见下文。
  • "None": 此设置允许 Pod 忽略 Kubernetes 环境中的 DNS 设置。Pod 会使用其 dnsConfig 字段所提供的 DNS 设置。 参见 Pod 的 DNS 配置节。

说明: "Default" 不是默认的 DNS 策略。如果未明确指定 dnsPolicy,则使用 "ClusterFirst"。

        下面的示例显示了一个 Pod,其 DNS 策略设置为 "ClusterFirstWithHostNet", 因为它已将 hostNetwork 设置为 true。

代码语言:javascript复制
apiVersion: v1 
kind: Pod 
metadata: 
  name: busybox 
  namespace: default 
spec: 
  containers: 
    - image: busybox:1.28 
      command: 
        - sleep 
        - "3600" 
      imagePullPolicy: IfNotPresent 
      name: busybox 
  restartPolicy: Always 
  hostNetwork: true 
  dnsPolicy: ClusterFirstWithHostNet

1.2.2.5 Pod 的 DNS 配置特性状态: 

Kubernetes v1.14 [stable]

        Pod 的 DNS 配置可让用户对 Pod 的 DNS 设置进行更多控制。

        dnsConfig 字段是可选的,它可以与任何 dnsPolicy 设置一起使用。 但是,当 Pod 的 dnsPolicy 设置为 "None" 时,必须指定 dnsConfig 字段。

        用户可以在 dnsConfig 字段中指定以下属性:

  • nameservers:将用作于 Pod 的 DNS 服务器的 IP 地址列表。 最多可以指定 3 个 IP 地址。当 Pod 的 dnsPolicy 设置为 "None" 时, 列表必须至少包含一个 IP 地址,否则此属性是可选的。 所列出的服务器将合并到从指定的 DNS 策略生成的基本名称服务器,并删除重复的地址。
  • searches:用于在 Pod 中查找主机名的 DNS 搜索域的列表。此属性是可选的。 指定此属性时,所提供的列表将合并到根据所选 DNS 策略生成的基本搜索域名中。 重复的域名将被删除。Kubernetes 最多允许 6 个搜索域。
  • options:可选的对象列表,其中每个对象可能具有 name 属性(必需)和 value 属性(可选)。 此属性中的内容将合并到从指定的 DNS 策略生成的选项。 重复的条目将被删除。

        以下是具有自定义 DNS 设置的 Pod 示例:service/networking/custom-dns.yaml

代码语言:javascript复制
apiVersion: v1 
kind: Pod 
metadata: 
  namespace: default 
  name: dns-example 
spec: 
  containers: 
    - name: test 
      image: nginx 
  dnsPolicy: "None" 
  dnsConfig: 
    nameservers: 
      - 1.2.3.4 
    searches: 
      - ns1.svc.cluster-domain.example 
      - my.dns.search.suffix 
    options: 
      - name: ndots 
        value: "2" 
      - name: edns0

        创建上面的 Pod 后,容器 test 会在其 /etc/resolv.conf 文件中获取以下内容:

代码语言:javascript复制
nameserver 1.2.3.4 
search ns1.svc.cluster-domain.example my.dns.search.suffix 
options ndots:2 edns0

        对于 IPv6 设置,搜索路径和名称服务器应按以下方式设置:

代码语言:javascript复制
kubectl exec -it dns-example -- cat /etc/resolv.conf

        输出类似于:

代码语言:javascript复制
nameserver 2001:db8:30::a 
search default.svc.cluster-domain.example svc.cluster-domain.example cluster-domain.example 
options ndots:5

1.3 DNS 搜索域列表限制特性 

Kubernetes 1.26 [beta]

        Kubernetes 本身不限制 DNS 配置,最多可支持 32 个搜索域列表,所有搜索域的总长度不超过 2048。 此限制分别适用于节点的解析器配置文件、Pod 的 DNS 配置和合并的 DNS 配置。说明:

        早期版本的某些容器运行时可能对 DNS 搜索域的数量有自己的限制。 根据容器运行环境,那些具有大量 DNS 搜索域的 Pod 可能会卡在 Pending 状态。

        众所周知 containerd v1.5.5 或更早版本和 CRI-O v1.21 或更早版本都有这个问题。

1.4 Windows 节点上的 DNS 解析

  • 在 Windows 节点上运行的 Pod 不支持 ClusterFirstWithHostNet。 Windows 将所有带有 . 的名称视为全限定域名(FQDN)并跳过全限定域名(FQDN)解析。
  • 在 Windows 上,可以使用的 DNS 解析器有很多。 由于这些解析器彼此之间会有轻微的行为差别,建议使用 Resolve-DNSName powershell cmdlet 进行名称查询解析。
  • 在 Linux 上,有一个 DNS 后缀列表,当解析全名失败时可以使用。 在 Windows 上,你只能有一个 DNS 后缀, 即与该 Pod 的命名空间相关联的 DNS 后缀(例如:mydns.svc.cluster.local)。 Windows 可以解析全限定域名(FQDN),和使用了该 DNS 后缀的 Services 或者网络名称。 例如,在 default 命名空间中生成一个 Pod,该 Pod 会获得的 DNS 后缀为 default.svc.cluster.local。 在 Windows 的 Pod 中,你可以解析 kubernetes.default.svc.cluster.local 和 kubernetes, 但是不能解析部分限定名称(kubernetes.default 和 kubernetes.default.svc)。

2 DNS实操

2.1 DNS服务发展概述

        service发现是k8s中的一个重要机制,其基本功能为:在集群内通过服务名对服务进行访问,即需要完成从服务名到ClusterIP的解析。

        k8s主要有两种service发现机制:环境变量和DNS。没有DNS服务的时候,k8s会采用环境变量的形式,但一旦有多个service,环境变量会变复杂,为解决该问题,我们使用DNS服务。

        DNS服务在kubernetes中经历了三个阶段(SkyDNS-》KubeDNS-》CoreDNS):

  1. 【第一阶段】在kubernetes 1.2版本时,dns服务使用的是由SkyDNS提供的,由4个容器组成:kube2sky、skydns、etcd和healthz。etcd存储dns记录;kube2sky监控service变化,生成dns记录;skydns读取服务,提供查询服务;healthz提供健康检查。
  2. 【第二阶段】在kubernetes 1.4版本开始使用KubeDNS,有3个容器组成:kubedns、dnsmasq和sidecar。kubedns监控service变化,并记录到内存(存到内存提高性能)中;dnsmasq获取dns记录,提供dns缓存,提供dns查询服务;sidecar提供健康检查。
  3. 【第三阶段】从kubernetes >=1.11版本开始,dns服务有CoreDNS提供,coredns支持自定义dns记录及配置upstream dns server,可以统一管理内部dns和物理dns。coredns只有一个coredns容器。下面是coredns的架构。

 2.2 CoreDNS名称解析组件

        CoreDNS:是一个DNS服务器,Kubernetes默认采用,以Pod部署在集群中,CoreDNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析。CoreDNS YAML文件:https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/coredns。ClusterIP A记录格式:..svc.cluster.local,示例:my-svc.my-namespace.svc.cluster.local。

        CoreDNS工作流程图

 2.2.1 CoreDNS配置解析

        下面是coredns的配置模板

代码语言:javascript复制
apiVersion: v1 
kind: ConfigMap 
metadata: 
  name: coredns 
  namespace: namespace-test 
data: 
  Corefile: | 
    .:53 { 
      errors 
      health 
      ready 
      kubernetes cluster.local 10.200.0.0/16 { 
        pods insecure 
        upstream 114.114.114.114 
        fallthrough in-addr.arpa ip6.arpa 
        namespaces namespace-test 
      } 
      prometheus :9153 
      forward . /etc/resolv.conf 
      cache 30 
      loop 
      reload 
      loadbalance 
    }

        CoreDNS的主要功能是通过插件系统实现的。它实现了一种链式插件的结构,将dns的逻辑抽象成了一个个插件。常见的插件如下:

  • loadbalance:提供基于dns的负载均衡功能
  • loop:检测在dns解析过程中出现的简单循环问题
  • cache:提供前端缓存功能
  • health:对Endpoint进行健康检查
  • kubernetes:从kubernetes中读取zone数据
  • etcd:从etcd读取zone数据,可以用于自定义域名记录
  • file:从文件中读取zone数据
  • hosts:使用/etc/hosts文件或者其他文件读取zone数据,可以用于自定义域名记录
  • auto:从磁盘中自动加载区域文件
  • reload:定时自动重新加载Corefile配置文件的内容
  • forward:转发域名查询到上游dns服务器
  • proxy:转发特定的域名查询到多个其他dns服务器,同时提供到多个dns服务器的负载均衡功能
  • prometheus:为prometheus系统提供采集性能指标数据的URL
  • pprof:在URL路径/debug/pprof下提供运行是的西能数据
  • log:对dns查询进行日志记录
  • errors:对错误信息镜像日志记录

 2.3 测试CoreDNS

1)pod验证

        现在我们来创建一个busybox的pod,测试一下pod内是否可以解析

代码语言:javascript复制
$ cat >busybox.yaml<<EOF 
apiVersion: v1 
kind: Pod 
metadata: 
  name: busybox 
  namespace: default 
spec: 
  containers: 
    - name: busybox 
      image: busybox:1.28 
      command: 
        - sleep 
        - "3600" 
      imagePullPolicy: IfNotPresent 
  restartPolicy: Always 
EOF

        创建并测试解析kubernetes.default:

代码语言:javascript复制
$ kubectl apply -f busybox.yaml 
$ kubectl get pods busybox 
$ kubectl exec busybox -- cat /etc/resolv.conf 
$ kubectl exec -ti busybox -- nslookup kubernetes.default 
$ kubectl exec -ti busybox -- nslookup kubernetes.default.svc.cluster.local

 2)创建service和Deployment来验证

代码语言:javascript复制
cat >dns-Service-Deployment-test001.yaml<<EOF 
apiVersion: v1 
kind: Service 
metadata: 
  name: nginx-svc-old 
  labels: 
    app: nginx-svc 
spec: 
  selector: 
    app: nginx 
  ports: 
    - protocol: TCP 
      port: 80 
      targetPort: 80 
--- 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: nginx-old 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      app: nginx 
  template: 
    metadata: 
      labels: 
        app: nginx 
    spec: 
      containers: 
        - name: nginx 
          image: nginx 
          ports: 
            - containerPort: 80 
EOF

创建

代码语言:javascript复制
$ kubectl apply -f dns-Service-Deployment-test001.yaml 
$ kubectl get pod|grep nginx-old 
$ kubectl get svc nginx-svc-old

        直接在宿主机上验证:

代码语言:javascript复制
$ nslookup nginx-svc-old.default.svc

        发现直接在宿主机上是不能解析域名的。然后用以下yaml创建了一个busybox作为调试工具:

代码语言:javascript复制
$ cat >dns-Deployment-test002.yaml<<EOF 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: busybox-deployment 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      app: busybox 
  template: 
    metadata: 
      labels: 
        app: busybox 
    spec: 
      restartPolicy: Always 
      containers: 
        - name: busybox 
          command: 
            - sleep 
            - "3600" 
          image: busybox 
EOF

        这里用的是截止2021/10/08,busybox的最新镜像。创建好之后,exec进入容器,执行测试命令。

代码语言:javascript复制
$ kubectl apply -f dns-Deployment-test002.yaml 
$ kubectl get pod|grep busybox-deployment 
$ kubectl exec -ti busybox-deployment-5bc85cc8d9-gkjgj -- sh 
# 访问上面service的域名 
$ nslookup nginx-svc-old.default.svc

        发现也是无法解析。根据coredns解析集群内域名原理可知:

        服务 a 访问服务 b,对于同一个 Namespace下,可以直接在 pod 中,通过 curl b 来访问。对于跨 Namespace 的情况,服务名后边对应 Namespace即可,比如 curl b.default。DNS 如何解析,依赖容器内 resolv 文件的配置。

        查看busybox容器内的resolve.conf文件:

代码语言:javascript复制
$ kubectl exec -ti busybox-deployment-5bc85cc8d9-gkjgj -- sh 
$ nslookup nginx-svc-old.default.svc 
$ cat /etc/resolv.conf

         这个文件中,配置的 DNS Server,一般就是 K8S 中,coredns的 Service 的 ClusterIP,这个IP是虚拟IP,无法ping,但可以访问。

         在容器内发请求时,会根据 /etc/resolv.conf 进行解析流程。选择 nameserver 10.1.0.10 进行解析,然后用nginx-svc-old ,依次带入 /etc/resolve.conf 中的 search 域,进行DNS查找,分别是:

        search 内容类似如下(不同的pod,第一个域会有所不同)

search default.svc.cluster.local svc.cluster.local cluster.local

nginx-svc-old.default.svc.cluster.local -> nginx-svc-old.svc.cluster.local -> nginx-svc-old.cluster.local

代码语言:javascript复制
$ kubectl exec -ti busybox-deployment-5bc85cc8d9-gkjgj -- sh 
$ ping nginx-svc-old 
$ ping nginx-svc-old.default

         直到找到为止。所以,我们执行 ping nginx-svc-old,或者执行 ping nginx-svc-old.default,都可以完成DNS请求,这2个不同的操作,会分别进行不同的DNS查找步骤。

        根据以上原理,查看到busybox内的域名/etc/resolv.conf没有问题,nameserver指向正确的kube-dns的service clusterIP。

        这下更加怀疑core-dns有问题了。

        但查看coredns日志,可以看到并没有报错:

代码语言:javascript复制
$ kubectl get pod -n kube-system|grep dns 
$ kubectl logs -f coredns-7f6cbbb7b8-cn44w -n kube-system 
$ kubectl logs -f coredns-7f6cbbb7b8-gf82k -n kube-system

         那就说明不是coredns问题了。经过一番查找,发现是busybox版本问题。busybox

         发现都说是busybox镜像的问题,从1.28.4以后的镜像都存在这问题。把镜像换成1.28.4试试?修改yaml版本号:

代码语言:javascript复制
$ kubectl apply -f dns-Deployment-test002.yaml 
$ kubectl get pod|grep busybox-deployment 
$ kubectl exec -ti busybox-deployment-564c775bbd-g6228 -- sh 
$ nslookup nginx-svc-old.default.svc #exit 
$ kubectl get svc

        确实可以成功解析域名了。所以这样看还真是busybox版本问题了。

3)宿主机上解析域名验证

        nameserver关键字,如果没指定nameserver就找不到DNS服务器,其它关键字是可选的。nameserver表示解析域名时使用该地址指定的主机为域名服务器。其中域名服务器是按照文件中出现的顺序来查询的,且只有当第一个nameserver没有反应时才查询下面的nameserver,一般不要指定超过3个服务器。

        在宿主上/etc/resolv.conf中nameserver如下:

代码语言:javascript复制
$ kubectl get svc -n kube-system 
$ kubectl get pod -n kube-system -o wide|grep dns 
$ kubectl exec -ti busybox-deployment-564c775bbd-g6228 -- cat /etc/resolv.conf 
$ cat /etc/resolv.conf

         后面四个是k8s dns的配置,把后面四个都放到前面来,再验证:

nameserver 10.1.0.10

nameserver 10.244.2.137

nameserver 10.244.2.138

search default.svc.cluster.local svc.cluster.local cluster.local

代码语言:javascript复制
$ nslookup nginx-svc-old $ cat /etc/resolv.conf $ nslookup baidu.com

         可以看到现在可以解析了。也不影响外网域名解析,但是最好还是不要指定超过3个服务器。

参考链接

Service 与 Pod 的 DNS | Kubernetes

Kubernetes中DNS服务简介 - 知乎

k8s网络配置DNS - 简书

【线上分享】Kubernetes如何使用kube-dns实现服务发现-创头条

k8s service的DNS名称解析之CoreDNS - 七月流星雨 - 博客园

Kubernetes(k8s)浅谈 Service 和 DNS_oceanweave的博客-CSDN博客

Kubernetes(k8s)DNS(CoreDNS)介绍_大数据老司机的博客-CSDN博客_k8s coredns

kube-dns · Kubernetes指南

详解 DNS 与 CoreDNS 的实现原理 - 面向信仰编程

0 人点赞