kubernetes之DNS

Kubernetes 从 1.3 版本起, DNS 是内置的服务,通过插件管理器 集群插件 自动被启动。Kubernetes DNS 在集群中调度 DNS Pod 和 Service ,配置 kubelet 以通知个别容器使用 DNS Service 的 IP 解析 DNS 名字。

怎样获取 DNS 名字:

在集群中定义的每个 Service(包括 DNS 服务器自身)都会被指派一个 DNS 名称。 默认,一个客户端 Pod 的 DNS 搜索列表将包含该 Pod 自己的 Namespace 和集群默认域。 通过如下示例可以很好地说明:
例如,有一个名称为 nginx-serviceService,它在 Kubernetes 集群中名为 kube-systemNamespace 中,会创建一条为 nginx-service.kube-system.svc.cluster.local. 的DNS 记录。
资源记录的格式为:SVC_NAME.NS_NAME.DOMAIN.LTD.
SVC_NAME:service名称
NS_NAME:(Namespace )名称空间
DOMAIN.LTD: 默认的集群service 的A记录:svc.cluster.local.
redis服务创建的A记录:redis.default.svc.cluster.local.

支持的 DNS 模式:

Service:

  • A 记录
    “正常” Service(除了 Headless Service)会以 my-svc.my-namespace.svc.cluster.local 这种名字的形式被指派一个 DNS A 记录。这会解析成该 Service 的 Cluster IP。

“Headless” Service(没有Cluster IP)也会以 my-svc.my-namespace.svc.cluster.local 这种名字的形式被指派一个 DNS A 记录。 不像正常 Service,它会解析成该 Service 选择的一组 Pod 的 IP。 希望客户端能够使用这一组 IP,否则就使用标准的 round-robin 策略从这一组 IP 中进行选择

  • SRV 记录
    命名端口需要创建 SRV 记录,这些端口是正常 Service或 Headless Services 的一部分。 对每个命名端口,SRV 记录具有 _my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local 这种形式。 对普通 Service,这会被解析成端口号和 CNAME:my-svc.my-namespace.svc.cluster.local。 对 Headless Service,这会被解析成多个结果,Service 对应的每个 backend Pod 各一个,包含 auto-generated-name.my-svc.my-namespace.svc.cluster.local 这种形式 Pod 的端口号和 CNAME。

Pod:

  • A 记录
    如果启用,Pod 会以 pod-ip-address.my-namespace.pod.cluster.local 这种形式被指派一个 DNS A 记录。
    例如,default Namespace 具有 DNS 名字 cluster.local,在该 Namespace 中一个 IP 为 1.2.3.4 的 Pod 将具有一个条目:1-2-3-4.default.pod.cluster.local。

Kubernetes配置使用CoreDNS:

kubelet的大多数命令行参数都改为推荐在--config指定位置的配置文件中进行配置,包括--cluster-dns和--cluster-domain两个参数,在kubelet的配置文件中配置如下:

dns1

1
2
3
4
5
6
7
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
......
clusterDNS:
- 10.254.0.2
clusterDomain: cluster.local
......

其中clusterDNS指定了集群中所有容器将使用的DNS Server,即kubelet会在每个Pod内部设置DNS服务的地址为clusterDNS配置的地址。前面的配置中设置了Kubernetes集群访问内DNS服务器的地址是10.254.0.2,将由起完成Service Name到Cluster Ip的解析。有了这个配置,我们还需要在集群内部署DNS服务,DNS服务一般都是作为addon组件部署在Kubernetes集群内的。

在Kubernetes中部署CoreDNS作为集群内的DNS服务有很多种方式。这里继承我们之前部署kubeDNS的传统,使用Kubernetes中addon库中的yaml文件部署,地址在这里:
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/coredns

查看transforms2sed.sed的内容:
dns2

将$DNS_SERVER_IP和DNS_DOMAIN替换成kubelet配置的内容。这里将$DNS_SERVER_IP替换成10.254.0.2,将DNS_DOMAIN替换成cluster.local.。

1
2
#执行下面的命令,生成部署coreDNS所需的coredns.yaml文件:
sed -f transforms2sed.sed coredns.yaml.base > coredns.yaml
1
2
#对coredns.yaml做微调,如修改镜像地址为私有镜像仓库,调整副本数量等等。
kubectl apply -f coredns.yaml #注意使用镜像加速器不然可能无法下载镜像
1
2
3
4
5
6
7
8
9
#查看coredns的Pod,确认所有Pod都处于Running状态:

kubectl get pods -n kube-system -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
coredns-699477c54d-9fsl2 1/1 Running 0 5m
coredns-699477c54d-d6tb2 1/1 Running 0 5m
coredns-699477c54d-qh54v 1/1 Running 0 5m
coredns-699477c54d-vvqj9 1/1 Running 0 5m
coredns-699477c54d-xcv8h 1/1 Running 0 6m
1
2
#测试一下DNS功能是否好用:
dig -t A nginx-service.default.svc.cluster.local. @10.254.0.2

修改master节点和所有node节点的/etc/systemd/system/kube-kubelet.service,修改–cluster-dns和 –cluster-domain内容如下,与上面的Corefile中的值对应。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/usr/k8s/bin/kubelet \
--fail-swap-on=false \
--cgroup-driver=cgroupfs \
--address=192.168.91.21 \
--hostname-override=192.168.91.21 \
--experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
--cert-dir=/etc/kubernetes/ssl \
--cluster-dns=10.254.0.2 \
--cluster-domain=cluster.local. \
--hairpin-mode promiscuous-bridge \
--allow-privileged=true \
--serialize-image-pulls=false \
--logtostderr=true \
--v=2
Restart=on-failure
RestartSec=5

kubernetes之DNS
https://system51.github.io/2019/08/23/kubernetes-DNS/
作者
Mr.Ye
发布于
2019年8月23日
许可协议