kubernetes dns
环境信息
- Centos 7 5.4.225-1
- Kubernetes v1.24.7
Kubernetes DNS 服务的功能,是用来解析 Kubernetes 集群内的 Pod 和 Service 的域名,一般只供集群内部使用,不给外部使用。
默认情况下,Kubernetes DNS 应用部署后,会对外暴露一个 Service,集群内的容器通过访问该 Service 获得域名解析服务,这个 Service 的 ClusterIP 一般情况下都是固定的。
kubectl get services -n kube-system -o wide |
当 Kubernetes DNS 服务获得 ClusterIP 后,系统会给 Kubelet 配置启动参数指定 DNS Service 的 ClusterIP,DNS Service 的 IP 会在容器启动时传入,并写入容器系统的 DNS 配置中(一般为 /etc/resolv.conf
文件)
根据 kubelet
服务的启动命令,配置参数可以写在以下相关配置文件中
systemctl status kubelet -l |
DNS 的相关配置在文件 /var/lib/kubelet/config.yaml
中,主要选项为 clusterDNS
apiVersion: kubelet.config.k8s.io/v1beta1 |
Kubernetes DNS 解析基本原理
对于 Service,Kubernetes NDS 会生成三类记录,分别是 A 记录、SRV 记录、CNAME 记录。
A 记录
A 记录用于做正向解析,将域名解析到对应的 IP 地址。Kubernetes 为 normal
和 headless
类型的服务分配不同的 A 记录,不同之处在于 headless
类型的服务未分配 ClusterIP 且不执行负载均衡。
- DNS 为
normal
类型的 Service 分配一个 A 记录,域名遵循${your-svc-name}.${your-namespace}.svc.cluster.local
(其中cluster.local
为集群默认的根域,可在kubelet
设置clusterDomain
中更改),A 记录指向 Service 的 ClusterIP。 - DNS 为
headless
类型的 Service 分配一个 A 记录,域名遵循${your-svc-name}.${your-namespace}.svc.cluster.local
(其中cluster.local
为集群默认的根域,可在kubelet
设置clusterDomain
中更改),A 记录指向就绪的 Pod 的 IP。DNS 不会自动将此 IP 配置为特定 Pod 的 IP,后端如果有多个就绪的 Pod,DNS 会添加所有解析。
在集群内部,可以通过 ${your-svc-name}.${your-namespace}.svc.cluster.local
访问任何服务,也可以通过简写 ${your-svc-name}.${your-namespace}
直接访问。如果 Pod 和 Service 在同一个 namespace,可以通过 Service name (${your-svc-name}) 直接访问
Pod IP 的 A 记录
启用了 DNS 后,Pod 将被分配一个 DNS A 记录,格式如下
{Pod-ip}.${Pod namespace}.pod.${clusterDomain } --> Pod IP |
${Pod-ip} 为 Pod 的 IP 地址使用 -
替换 .
,如 Pod IP 为 1.2.3.4
,${Pod-ip} 为 1-2-3-4
如果在 Pod Spec 中指定了 hostname
和 subdomain
,那么 Kubernetes DNS 会为 Pod 额外生产 A 记录
{hostname}.${subdomain}.${Pod namespace}.pod.${clusterDomain } --> Pod IP |
SRV 记录
SRV 记录通过在 DNS 中定义服务协议和地址(域名及端口)来促进服务发现。SRV 记录通常定义了 服务名称、协议、请求端口、请求域名(主机)、权重、优先级等内容。以下是一个 SRV 记录的示例
_sip._tcp.example.com 3600 IN SRV 10 70 5060 srvrecord.example.com |
在上面的示例中:
_sip
- 是服务的名称_tcp
- 服务使用的协议10
- 表示优先级70
- 表示权重5060
- 服务要连接的 端口srvrecord.example.com
- 服务要连接的主机
Kubernetes 的 DNS 服务遵循以下规则为 Service 提供了服务端口的解析
{port name}._tcp.${service name}.${service namespace}.svc.cluster.local --> Service Port |
解析到的域名(主机)是
${service name}.${service namespace}.svc.cluster.local
如果是headless
类型的 Service ,解析到的域名(主机)是 Pod 的 域名。