概述
官网文档:https://kubernetes.io/zh-cn/docs/concepts/services-networking/dns-pod-service/
在 Kubernetes(K8s)中,DNS 服务是实现服务发现和 Pod 通信的核心组件之一,用于解决集群内资源通过域名而非 IP 地址进行访问的需求。本文将详细解析 K8s DNS 服务的原理、组件、配置及应用场景。
K8s DNS的作用
服务发现
- 允许 Pod 通过服务名称(Service Name)而非动态变化的 IP 地址访问其他服务,简化网络配置。
- 支持跨命名空间(Namespace)的服务访问,通过域名后缀区分不同作用域。
Pod 通信
- 每个 Pod 自动获取 DNS 配置,可直接通过主机名(Hostname)或服务名进行通信。
解耦服务依赖
- 服务的 IP 地址变更时,DNS 会自动更新解析结果,避免手动维护 IP 列表。
核心组件:CoreDNS(替代传统 kube-dns)
K8s 早期使用kube-dns作为 DNS 服务器,目前默认采用CoreDNS,因其更轻量、灵活且支持插件机制。
CoreDNS的安装
如果使用kubeadm部署集群,CoreDNS 会自动部署在kube-system命名空间下,如果需要进行部署,可以使用下面的文件:- kubectl apply -f https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base
复制代码 部署CoreDNS通常包含
- StatefulSet/Deployment:定义 CoreDNS Pod 副本。
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: coredns
- namespace: kube-system
- spec:
- replicas: 2 # 默认2个副本,确保高可用
- selector:
- matchLabels:
- k8s-app: kube-dns # 历史遗留标签,兼容旧版kube-dns
- template:
- metadata:
- labels:
- k8s-app: kube-dns
- spec:
- containers:
- - name: coredns
- image: coredns/coredns:v1.10.1 # CoreDNS版本
- args: [ "-conf", "/etc/coredns/Corefile" ]
- ports:
- - containerPort: 53
- name: dns
- protocol: UDP
- - containerPort: 53
- name: dns-tcp
- protocol: TCP
- volumeMounts:
- - name: config-volume
- mountPath: /etc/coredns
- volumes:
- - name: config-volume
- configMap:
- name: coredns
- items:
- - key: Corefile
- path: Corefile
复制代码
- Service:暴露 CoreDNS 服务,供集群内 Pod 访问(默认 IP 为10.96.0.10)。
- apiVersion: v1
- kind: Service
- metadata:
- name: kube-dns
- namespace: kube-system
- spec:
- selector:
- k8s-app: kube-dns
- clusterIP: 10.96.0.10 # 默认集群IP,Pod的nameserver配置指向此IP
- ports:
- - name: dns
- port: 53
- protocol: UDP
- - name: dns-tcp
- port: 53
- protocol: TCP
复制代码
- ConfigMap:存储 Corefile 配置。
- .:53 { #表示监听所有接口的 53 端口(DNS 标准端口)。
- errors # 记录错误日志
- health {
- lameduck 5s # 健康检查,延迟5秒标记不健康
- }
- ready # 提供 readiness 探针端点(/ready),指示 CoreDNS 是否准备好处理请求
- kubernetes cluster.local in-addr.arpa ip6.arpa {
- fallthrough in-addr.arpa ip6.arpa # 未匹配到K8s服务时,透传给下一个插件
- ttl 30 # DNS记录的TTL时间
- }
- prometheus :9153 # 暴露Prometheus监控指标
- forward . /etc/resolv.conf # 转发外部域名查询到宿主机的DNS服务器
- cache 30 # 缓存查询结果30秒
- loop # 检测配置循环引用
- reload # 自动重新加载配置变更
- loadbalance # 对A/AAAA记录进行负载均衡
- }
复制代码 CoreDNS的组成
- CoreDNS Pod:运行 CoreDNS 服务,监听 DNS 请求(默认端口 53)。
- [root@master ~]# kubectl get po -o wide -n kube-system
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- coredns-787d4945fb-jb4t9 1/1 Running 1 (2d23h ago) 9d 100.117.144.135 node01 <none> <none>
- coredns-787d4945fb-z47x7 1/1 Running 1 (2d23h ago) 9d 100.117.144.138 node01 <none> <none>
复制代码
- Service 资源:为 CoreDNS Pod 暴露集群内部服务,名称为kube-dns(或coredns,取决于部署方式),IP 通常为10.96.0.10(集群 IP 范围)。
- [root@master ~]# kubectl get svc -n kube-system
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 9d
- [root@master ~]# kubectl describe svc kube-dns -n kube-system
- Name: kube-dns
- Namespace: kube-system
- Labels: k8s-app=kube-dns
- kubernetes.io/cluster-service=true
- kubernetes.io/name=CoreDNS
- Annotations: prometheus.io/port: 9153
- prometheus.io/scrape: true
- Selector: k8s-app=kube-dns
- Type: ClusterIP
- IP Family Policy: SingleStack
- IP Families: IPv4
- IP: 10.96.0.10
- IPs: 10.96.0.10
- Port: dns 53/UDP
- TargetPort: 53/UDP
- Endpoints: 100.117.144.135:53,100.117.144.138:53
- Port: dns-tcp 53/TCP
- TargetPort: 53/TCP
- Endpoints: 100.117.144.135:53,100.117.144.138:53
- Port: metrics 9153/TCP
- TargetPort: 9153/TCP
- Endpoints: 100.117.144.135:9153,100.117.144.138:9153
- Session Affinity: None
- Events: <none>
复制代码
- ConfigMap 配置:通过 ConfigMap 定义 CoreDNS 的解析规则和插件。
- [root@master ~]# kubectl describe cm coredns -n kube-system
- Name: coredns
- Namespace: kube-system
- Labels: <none>
- Annotations: <none>
- Data
- ====
- Corefile:
- ----
- .:53 {
- errors
- health {
- lameduck 5s
- }
- ready
- kubernetes cluster.local in-addr.arpa ip6.arpa {
- pods insecure
- fallthrough in-addr.arpa ip6.arpa
- ttl 30
- }
- prometheus :9153
- forward . /etc/resolv.conf {
- max_concurrent 1000
- }
- cache 30
- loop
- reload
- loadbalance
- }
- BinaryData
- ====
- Events: <none>
复制代码 CoreDNS域名解析规则
K8s集群中Pod之间通过域名互相访问需要遵守特定的规则,规则如下- <service-name>.<namespace>.svc.<cluster-domain>
复制代码
- service-name:表示service的名称
- namespace:service所在的命名空间
- cluster-domain:集群的域名,默认为cluster.local
cluster-domain从哪儿获取?
- [root@master ~]# grep clusterDomain /var/lib/kubelet/config.yaml
- clusterDomain: cluster.local
复制代码 CoreDNS实战案例
验证同一个命名空间下的CoreDNS访问
创建两个Pod和Service- ## 第一个Pod和 Service
- [root@master ~/coredns]# cat test-1.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: dns-target-pod
- labels:
- app: dns-test
- spec:
- containers:
- - name: busybox
- image: busybox
- command: ["sh", "-c", "while true; do sleep 3600; done"]
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: dns-target-service
- spec:
- type: ClusterIP
- selector:
- app: dns-test
- ports:
- - protocol: TCP
- port: 80
- targetPort: 80
- [root@master ~/coredns]# kubectl apply -f test-1.yaml
- pod/dns-target-pod unchanged
- service/dns-target-service created
- # 第二个Pod和Service
- [root@master ~/coredns]# cat test-2.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: dns-source-pod
- labels:
- app: dns-source-test
- spec:
- containers:
- - name: busybox
- image: busybox
- command: ["sh", "-c", "while true; do sleep 3600; done"]
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: dns-source-service
- spec:
- type: ClusterIP
- selector:
- app: dns-source-test
- ports:
- - protocol: TCP
- port: 80
- targetPort: 80
- [root@master ~/coredns]# kubectl apply -f test-2.yaml
- pod/dns-source-pod created
- service/dns-source-service created
- # 检查一下
- [root@master ~/coredns]# kubectl get po,svc
- NAME READY STATUS RESTARTS AGE
- pod/dns-source-pod 1/1 Running 0 111s
- pod/dns-target-pod 1/1 Running 0 8s
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- service/dns-source-service ClusterIP 10.96.0.192 <none> 80/TCP 81s
- service/dns-target-service ClusterIP 10.96.3.51 <none> 80/TCP 3m56s
复制代码 验证DNS- [root@master ~/coredns]# kubectl exec -it pod/dns-source-pod -- sh
- / # nslookup dns-target-service.default.svc.cluster.local
- Server: 10.96.0.10
- Address: 10.96.0.10:53
- Name: dns-target-service.default.svc.cluster.local
- Address: 10.96.3.51
复制代码 验证在不同命名空间下的DNS访问
示例:- # 创建一个新的命名空间
- [root@master ~/coredns]# kubectl create ns coredns
- namespace/coredns created
- [root@master ~/coredns]# kubectl get ns coredns
- NAME STATUS AGE
- coredns Active 15s
复制代码 创建Pod和Service进行验证- [root@master ~/coredns]# cat test-3.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: dns-coredns-pod
- namespace: coredns
- labels:
- app: dns-coredns-test
- spec:
- containers:
- - name: busybox
- image: busybox
- command: ["sh", "-c", "while true; do sleep 3600; done"]
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: dns-coredns-service
- namespace: coredns
- spec:
- type: ClusterIP
- selector:
- app: dns-coredns-test
- ports:
- - protocol: TCP
- port: 80
- targetPort: 80
- [root@master ~/coredns]# kubectl apply -f test3.yaml
- pod/dns-coredns-pod created
- service/dns-coredns-service created
- [root@master ~]# kubectl get all -n coredns
- NAME READY STATUS RESTARTS AGE
- pod/dns-coredns-pod 1/1 Running 0 4m36s
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- service/dns-coredns-service ClusterIP 10.96.0.119 <none> 80/TCP 4m36s
复制代码 进行验证- [root@master ~/coredns]# kubectl exec -it dns-target-pod -- sh
- / # nslookup dns-coredns-service.coredns.svc.cluster.local
- Server: 10.96.0.10
- Address: 10.96.0.10:53
- Name: dns-coredns-service.coredns.svc.cluster.local
- Address: 10.96.0.119
复制代码 来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |