概述
在Kubernetes
(k8s)集群中,DNS
服务是其核心组件之一,用于实现服务发现,允许Pod
之间通过域名而非硬编码的IP
地址相互通信。早期K8s
使用SkyDNS
作为DNS
解决方案,之后过渡到了KubeDNS
,而现在默认的DNS
服务则是CoreDNS
。
CoreDNS
是一个高效、模块化且可扩展的DNS
服务器,它在k8s
集群中自动部署并配置,以响应集群内Pod和Service
的DNS
查询。当创建一个新的Service
后,Kubernetes
会自动为其生成对应的DNS
记录,使得其他Pod
可以通过服务名访问到该Service
的Cluster IP
。
在集群节点层面,kubelet
在启动时会配置相应的DNS
参数,确保Pod的/etc/resolv.conf
文件包含集群DNS服务的地址作为首选DNS
服务器。这样,Pod
内部发起的DNS
查询会被转发至CoreDNS
服务,进而解析成正确的服务IP
地址。
CoreDNS
架构图
查看RC、Pod、Service状态
bash
[root@master1 ~]# kubectl get deployment -n kube-system
NAME READY UP-TO-DATE AVAILABLE AGE
coredns 2/2 2 2 34d
[root@master1 ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7f89b7bc75-bvwt6 1/1 Running 15 34d
coredns-7f89b7bc75-vdrdn 1/1 Running 15 34d
[root@master1 ~]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.10.0.10 <none> 53/UDP,53/TCP,9153/TCP 34d
服务名的 DNS
解析
通过一个带有nslookup
工具的Pod
来验证DNS
服务能否正常工作
测试 Pod
和 Service
yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30660
selector:
app: webapp
yaml
apiVersion: v1
kind: Pod
metadata:
name: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: tomcat
imagePullPolicy: Never
ports:
- containerPort: 8080
yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
containers:
- name: busybox
image: busybox:1.28.3
command:
- sleep
- "3600"
运行并查看结果
bash
[root@master1 service]# kubectl get pod
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 3m58s
webapp 1/1 Running 1 6d
[root@master1 service]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webapp NodePort 10.10.157.91 <none> 8080:30660/TCP 6d
[root@master1 service]# kubectl exec busybox -- nslookup webapp
Server: 10.10.0.10
Address 1: 10.10.0.10 kube-dns.kube-system.svc.cluster.local
Name: webapp
Address 1: 10.10.157.91 webapp.pod-ns.svc.cluster.local
可以看到,通过DNS
服务器 10.10.0.10
找到 webapp
服务IP地址 10.10.157.91
Pod
级别 DNS
配置说明
除了使用集群范围的 DNS
服务,在 Pod
级别也能设置DNS
的相关策略和配置
DNS
策略
- Default :
Pod
继承其所在Node
节点的DNS
配置。 - ClusterFirst (默认策略):
Pod
首先查询由Kubernetes
集群提供的内部DNS
服务(如CoreDNS
),尝试解析服务名和集群内部的DNS
条目;如果集群DNS
服务不能解析,则请求转发给节点的DNS
配置。 - ClusterFirstWithHostNet :类似
ClusterFirst
,但特别适用于那些使用hostNetwork
模式运行的Pod
,确保它们也能正确使用集群DNS
。 - None :
Kubernetes
不会为Pod
提供任何默认的DNS
配置,此时需要在Pod
的spec.dnsConfig
字段下显式地指定DNS
服务器、搜索域和其他DNS
参数。
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
dnsPolicy: Default
自定义 DNS
配置
- nameservers :一组DNS服务列表,最多设置
3
个。 - searches :用于域名搜索的
DNS
域名后缀,最多设置6
个 - options :设置其他可选
DNS
参数。
yaml
apiVersion: v1
kind: Pod
metadata:
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
运行并查看结果
bash
[root@master1 service]# kubectl get pod
NAME READY STATUS RESTARTS AGE
dns-example 1/1 Running 0 18s
[root@master1 service]# kubectl exec dns-example -- more /etc/resolv.conf
::::::::::::::
/etc/resolv.conf
::::::::::::::
nameserver 1.2.3.4
search ns1.svc.cluster.local my.dns.search.suffix
options ndots:2 edns0
表示该Pod
完全使用自定义的DNS
配置。
结语
K8s
的DNS
服务简化了服务间通信,确保了服务发现的稳定性和可靠性,是支撑云原生应用在Kubernetes
环境下平滑运行的关键基础设施。用户可以根据需要自定义CoreDNS
配置,比如添加上游DNS
服务器以便内外部域名解析等。