概述

官网文档: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

K8s集群中的DNS服务(CoreDNS)详解的更多相关文章

  1. 二进制部署1.23.4版本k8s集群-2-安装DNS服务

    2.安装DNS服务 为什么要安装bind9? K8S中,使用Ingress进行7层流量调度,需要使用域名,进行7层调度. 以前使用绑定host的方法,来进行域名和IP地址的解析. 在K8S里,没有好的 ...

  2. 如何使用Istio 1.6管理多集群中的微服务?

    假如你正在一家典型的企业里工作,需要与多个团队一起工作,并为客户提供一个独立的软件,组成一个应用程序.你的团队遵循微服务架构,并拥有由多个Kubernetes集群组成的广泛基础设施. 由于微服务分布在 ...

  3. 在 Nebula K8s 集群中使用 nebula-spark-connector 和 nebula-algorithm

    本文首发于 Nebula Graph Community 公众号 解决思路 解决 K8s 部署 Nebula Graph 集群后连接不上集群问题最方便的方法是将 nebula-algorithm / ...

  4. k8s集群中安装rook-ceph

    容器的持久化存储 容器的持久化存储是保存容器存储状态的重要手段,存储插件会在容器里挂载一个基于网络或者其他机制的远程数据卷,使得在容器里创建的文件,实际上是保存在远程存储服务器上,或者以分布式的方式保 ...

  5. k8s 集群中的etcd故障解决

    一次在k8s集群中创建实例发现etcd集群状态出现连接失败状况,导致创建实例失败.于是排查了一下原因. 问题来源 下面是etcd集群健康状态: [root@docker01 ~]# cd /opt/k ...

  6. 实操教程丨如何在K8S集群中部署Traefik Ingress Controller

    注:本文使用的Traefik为1.x的版本 在生产环境中,我们常常需要控制来自互联网的外部进入集群中,而这恰巧是Ingress的职责. Ingress的主要目的是将HTTP和HTTPS从集群外部暴露给 ...

  7. k8s集群中遇到etcd集群故障的排查思路

    一次在k8s集群中创建实例发现etcd集群状态出现连接失败状况,导致创建实例失败.于是排查了一下原因. 问题来源 下面是etcd集群健康状态: 1 2 3 4 5 6 7 8 9 10 11 [roo ...

  8. Blazor+Dapr+K8s微服务之基于WSL安装K8s集群并部署微服务

         前面文章已经演示过,将我们的示例微服务程序DaprTest1部署到k8s上并运行.当时用的k8s是Docker for desktop 自带的k8s,只要在Docker for deskto ...

  9. k8s集群跨namespace访问服务

    场景:自己有一个java应用部署在test命名空间下,但是一直无法访问到middleware命名空间下的mysql服务 查找资料发现下面所说的问题 我们通常会把mysql,redis,rabbitmq ...

  10. 容灾恢复 | 记一次K8S集群中etcd数据快照的备份恢复实践

    [点击 关注「 全栈工程师修炼指南」公众号 ] 设为「️ 星标」带你从基础入门 到 全栈实践 再到 放弃学习! 涉及 网络安全运维.应用开发.物联网IOT.学习路径 .个人感悟 等知识分享. 希望各位 ...

随机推荐

  1. 【由技及道】螺蛳壳里做道场-git仓库篇-gitlab-Vs-gitea【人工智障AI2077的开发日志001】

    指令接收:「开始构建代码宇宙」 系统检测:需求模糊度99.9% 启动应急协议:构建最小可行性生态圈 核心组件锁定:代码基因库(人类称之为Git仓库) 需求分析:论人类语言的艺术性 人类指令翻译机 表面 ...

  2. Web前端入门第 15 问:学会查阅 HTML 文档

    HELLO,这里是大熊学习前端开发的入门笔记. 本系列笔记基于 windows 系统. HTML的魔法世界,多姿多彩,千变万化. 授人以鱼不如授人以渔,文档阅读是开发者必备的技能,毕竟代码出现 BUG ...

  3. mac更新本地时间

    前言 选取苹果菜单 >"系统偏好设置",然后点按"日期与时间". 点按窗口角落处的锁形图标 ,然后输入您的管理员密码以解锁设置. 在"日期与时 ...

  4. minio迁移工具 mc

    mc mirror 命令属于 MinIO Client (mc) 工具,默认不会随 MinIO 服务器一起安装,需要 单独安装. 安装 MinIO Client (mc) Linux/macOS 执行 ...

  5. docker swarm CA证书到期

    1.现象 在portain平台查看日志,发现一些节点日志无法查看报错为:Error grabbing logs: rpc error: code = Unknown desc = warning: i ...

  6. 继承内存图--java进阶 day01

    主方法进栈,有new进堆 堆内存中先存自己类中有的变量 又因为继承了父类,所以父类中的变量也要存入 即使被私有化,依旧可以继承,只是没有权限使用! 创建对象时,会调用构造方法,所以走构造方法,实参传形 ...

  7. 创建的容器都是没有指定 volume的,为什么docker volume ls命令会看到很多volume列表?

    有那么一天,停止了世界所有的容器(在你电脑上),执行以下命令 docker volume ls docker volume ls | wc -l 哎呦,我去,怎么这么多啥玩意,再执行以下命令看占了我多 ...

  8. git 访问方式浅谈

    小小总结下git的访问方式,留爪. git访问方式简介 https:每次fetch/push/pull都需要输入username & password ssh:通过ssh-keygen生成的公 ...

  9. Java提交到MySQL数据库出现中文乱码

    1)使用文本或者链接地址写到代码中(不推荐)时,实例如下: jdbc:mysql://localhost:3306/tms?useUnicode=true&characterEncoding= ...

  10. 使用CAMEL创建第一个Agent Society

    CAMEL介绍 CAMEL 是一个开源社区,致力于探索代理的扩展规律.相信,在大规模研究这些代理可以提供对其行为.能力和潜在风险的宝贵见解.为了促进这一领域的研究,实现了并支持各种类型的代理.任务.提 ...