POD使用DNS工作原理

POD使用DNS工作原理,第1张

tag: k8s coredns

有个同学不小心将CoreDNS干掉了,直接使用helm安装,但是DNS SVC的IP会重新分配一个。部署的POD的dns服务器地址不会变成新的(老的也不会改变)。

kubelet 通过 --cluster-dns=<dns-service-ip> 传递dns的地址。当创建POD时,如果使用ClusterDNS,则 /etc/resolv.conf 文件里的地址就使用这个。参考 官网

查看kubelet的PID,及启动配置。

--config=/etc/kubelet/node-config.yaml 节点配置,里面配置了dns的地址。

默认dns地址为: 172.16.56.10

以kubeadm部署集群为例,kubeadm默认获取svc网段下的第10个IP作为DNS的地址。

cmd/kubeadm/app/constants/constants.go:GetDNSIP

用户对pod的配置,会在内部进行转换,转为以下3种。

pkg/kubelet/network/dns/dns.go:getPodDNSType

https://kubernetes.io/zh/docs/concepts/services-networking/dns-pod-service/

pkg/kubelet/network/dns/dns.go:331

1)重新创建, svc的IP设置为之前的地址。

2)更换DNS地址,需要修改kubelet配置,重启kubelet。

Kubernetes支持Pod维度DNS策略设置,通过pod规约中dnsPolicy字段设置,最终配置落到 /etc/resolv.conf 文件中,也就说k8s最终还是通过设置Pod容器中/etc/resolv.conf 文件来做设置解析配置,跟普通的虚拟机或者实体机是一样,因为Pod容器本身就一个小的主机。

采用集群DNS,与配置的集群域后缀不匹配的任何 DNS 查询 都将转发到从节点继承的上游名称服务器。简单来说,就是使用 Kubernetes 中 kubedns 或 coredns 服务进行域名解析,如果解析不成功,才会使用宿主机的 DNS 配置进行解析。

example容器/etc/resolv.conf

options ndots:5 代表当待解析域名包含.大于等于5时就会先解析域名,只有域名解析不成功时才会继续匹配serach域或domain域

访问test名字空间下example-svc服务,可以直接通过 example-svc 访问,会与search域组合,最终组合成 example-svc.test.svc.cluster.local ,访问test1名字空间下example-svc1,通过 example-svc.test1 ,会与search域组合,最终组合成 example-svc.test1.svc.cluster.local

自定义DNS策略,设置允许 Pod 忽略 Kubernetes 环境中的 DNS 设置,Pod 会使用其 dnsConfig 字段 所提供的 DNS 设置。

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

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

Pod 从运行所在的节点继承名称解析配置,即跟所在节点主机一致

对于以 hostNetwork 方式运行的 Pod,应显式设置其 DNS 策略 为"ClusterFirstWithHostNet"

k8s新版本集群DNS服务是默认采用CoreDNS组件实现,1.13版本之前是采用Kube-dns

当 DNS 配置以及其它选项不合理的时候,通过向 Pod 的 /etc/hosts 文件中添加条目, 可以在 Pod 级别覆盖对主机名的解析。你可以通过 PodSpec 的 HostAliases 字段来添加这些自定义条目.

pod打印/etc/hosts文件,多了以下内容

Kubernetes DNS 在集群中会启动dns pod(coredns)和service(kube-dns)。集群中的container使用kube-dns service进行dns解析。

在集群中,每个service都会分配一个域名,默认一个pod会查找他自己namespace和集群中的default域。如:在bar namespace中分配一个service foo,运行在bar namespace中的pod可以通过foo查找这个服务,运行在quux namespace中的pod需要foo.bar查找这个服务

一个正常的service (非headless)会被分配一个dns A记录,如:my-svc.my-namespace.svc,cluster.local.被解析到集群中的serivce ip上。

测试DNS解析服务:

创建服务kubectl create service nodeport redis --tcp=6379:6379

 kubectl get service

NAME        TYPE        CLUSTER-IP    EXTERNAL-IP  PORT(S)          AGE

kubernetes  ClusterIP  10.96.0.1      <none>        443/TCP          2d13h

redis        NodePort    10.101.45.89  <none>        6379:32082/TCP  13s

运行测试pod kubectl run busybox --rm -ti --image=busybox /bin/sh

/ # nslookup redis

Server: 10.96.0.10

Address: 10.96.0.10:53

Name: redis.default.svc.cluster.local

Address: 10.101.45.89

/ # nslookup redis.default.svc.cluster.local.

Server: 10.96.0.10

Address: 10.96.0.10:53

Name: redis.default.svc.cluster.local

Address: 10.101.45.89

/ # nslookup kube-dns.kube-system.svc.cluster.local.

Server: 10.96.0.10

Address: 10.96.0.10:53

Name: kube-dns.kube-system.svc.cluster.local

Address: 10.96.0.10

可以发现域名被解析了。

Headless 服务,会解析一出来一个pod的ip list.客户端自己选择IP。

SRE解析记录格式为:_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local

对于无头服务,这将解析为多个答案,每个答案对应支持该服务的pod,并包含表单auto-generate -name.my- namespace - pace. svg .cluster.local的pod端口号和域名

每个pod都会分配一个:pod-ip-address.my-namespace.pod.cluster.local记录。比如一个pod在default namespace的IP为 1.2.3.4 ,它将有一个1-2-3-4.default.pod.cluster.local.记录。

/ # nslookup 10-32-0-3.default.pod.cluster.local.

Server: 10.96.0.10

Address: 10.96.0.10:53

Name: 10-32-0-3.default.pod.cluster.local

Address: 10.32.0.3

pod的hostname&subdomain也会有一个记录:foo(hostname).bar(subdomain).my-namespace.svc.cluster.local

POD里的DNS策略可以对每个pod进行设置,他支持四种策略default,ClusterFirst,ClusterFirstWithHostNet,None:

default: 表示 Pod 里面的 DNS 配置继承了宿主机上的 DNS 配置。简单来说,就是该 Pod 的 DNS 配置会跟宿主机完全一致。也就是和node上的dns配置是一样的

ClusterFirst:相对于上述的 Default,ClusterFirst 是完全相反的操作,它会预先把 kube-dns(或 CoreDNS)的信息当作预设参数写入到该 Pod 内的 DNS 配置。ClusterFirst 是默认的pod设置,若没有在 Pod 内特别描述 PodPolicy, 则会将 dnsPolicy 预设为 ClusterFirst.不过ClusterFirst 还有一个冲突,如果你的 Pod 设置了 HostNetwork=true,则 ClusterFirst 就会被强制转换成 Default。

ClusterFirstWithHostNet:如果pod是桥接的模式, dnsPolicy 将设置为ClusterFirstWithHostNet,他将同时解决default和ClusterFirst的DNS解析。

None: 表示会清除 Pod 预设的 DNS 配置,当 dnsPolicy 设置成这个值之后,Kubernetes 不会为 Pod 预先载入任何自身逻辑判断得到的 DNS 配置。因此若要将 dnsPolicy 的值设为 None,为了避免 Pod 里面没有配置任何 DNS,最好再添加 dnsConfig 来描述自定义的 DNS 参数

以下为pod DNS策略为none,然后自定义DNSpod

service/networking/custom-dns.yaml

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.local

      - my.dns.search.suffix

    options:

      - name: ndots

        value: "2"

      - name: edns0


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/663974.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-07-25
下一篇2023-07-25

发表评论

登录后才能评论

评论列表(0条)

    保存