1. 为什么K8S需要CoreDNS?
在Kubernetes集群中,服务发现是基础设施的核心能力之一。想象一下,当你的Pod需要访问另一个Service时,难道每次都要记住那串变化的ClusterIP吗?这就是CoreDNS的用武之地。
CoreDNS作为K8S默认的DNS服务,本质上是一个模块化、可扩展的DNS服务器。它取代了早期的kube-dns方案,通过插件机制实现了更灵活的DNS功能。在典型的K8S集群中,每当你创建一个Service,CoreDNS就会自动生成对应的DNS记录。
注意:从Kubernetes 1.13版本开始,CoreDNS正式成为默认DNS服务,替代了原来的kube-dns。如果你还在使用旧版本,升级集群时需要考虑迁移方案。
CoreDNS的配置文件以Corefile形式存在,通常包含如下关键插件:
- kubernetes:核心插件,用于发现K8S集群中的Service和Pod
- prometheus:提供监控指标暴露
- cache:DNS缓存加速
- loop:检测DNS查询循环
- reload:支持配置文件热加载
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 部署CoreDNS的完整流程
2.1 前置条件检查
在开始部署前,需要确认你的K8S环境已经满足:
- 正常运行的Kubernetes集群(v1.12+)
- 集群网络插件(如Calico、Flannel等)已正确配置
- kubectl命令行工具已配置好集群访问权限
可以通过以下命令验证网络插件状态:
bash复制kubectl get pods -n kube-system | grep -E 'flannel|calico|coredns'
2.2 官方部署方案
Kubernetes官方提供了CoreDNS的部署清单模板,我们可以基于此进行定制化部署:
- 获取官方部署文件:
bash复制wget https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed
- 根据集群配置修改关键参数:
bash复制sed -e 's/CLUSTER_DNS_IP/10.96.0.10/g' \
-e 's/CLUSTER_DOMAIN/cluster.local/g' \
coredns.yaml.sed > coredns.yaml
其中需要特别关注的配置项:
CLUSTER_DNS_IP:必须与kubelet的--cluster-dns参数一致CLUSTER_DOMAIN:默认使用cluster.local,也可自定义
- 应用配置:
bash复制kubectl apply -f coredns.yaml
2.3 验证部署状态
部署完成后,需要检查CoreDNS是否正常运行:
bash复制kubectl get pods -n kube-system -l k8s-app=kube-dns
预期应该看到类似输出:
code复制NAME READY STATUS RESTARTS AGE
coredns-7f6cbbb7b8-2xgxq 1/1 Running 0 3m
coredns-7f6cbbb7b8-hlq9v 1/1 Running 0 3m
3. CoreDNS的域名解析机制深度解析
3.1 K8S中的DNS记录生成规则
CoreDNS会为以下K8S资源自动生成DNS记录:
Service记录:
my-svc.my-namespace.svc.cluster.local→ ClusterIP- 如果Service有命名端口,还会生成SRV记录
Pod记录(需要显式启用):
pod-ip-address.my-namespace.pod.cluster.local- 对于hostNetwork Pod,会生成
pod-ip-address.my-namespace.pod.cluster.local
3.2 域名解析流程示例
假设集群中有以下资源:
- Namespace:
dev - Service:
frontend(ClusterIP: 10.96.1.10) - Pod:
backend-xyz(IP: 172.16.1.5)
对应的DNS解析行为:
- 完全限定域名查询:
bash复制nslookup frontend.dev.svc.cluster.local
返回:10.96.1.10
- 相对域名查询(在dev命名空间的Pod中):
bash复制nslookup frontend
返回:10.96.1.10
- Pod直接解析:
bash复制nslookup 172-16-1-5.dev.pod.cluster.local
返回:172.16.1.5
3.3 自定义DNS配置
通过修改CoreDNS的ConfigMap可以实现高级配置:
yaml复制apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
4. 常见问题排查指南
4.1 DNS解析超时问题
现象:应用Pod内域名解析经常超时
排查步骤:
- 检查CoreDNS Pod资源限制:
bash复制kubectl describe deployment coredns -n kube-system | grep -A 5 Resources
建议至少分配100m CPU和70Mi内存
- 检查节点DNS配置:
bash复制cat /etc/resolv.conf
确保nameserver设置正确
- 测试CoreDNS服务可达性:
bash复制kubectl run -it --rm --image=busybox:1.28 test-dns -- nslookup kubernetes.default
4.2 自定义域名无法解析
现象:配置了外部域名但无法解析
解决方案:
在CoreDNS配置中添加hosts插件:
yaml复制hosts {
192.168.1.10 my.internal.domain
fallthrough
}
4.3 DNS查询性能优化
对于大规模集群,建议:
- 启用CoreDNS缓存:
yaml复制cache {
success 9984 30
denial 9984 5
}
- 调整DNS自动伸缩策略:
yaml复制apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: coredns
namespace: kube-system
spec:
maxReplicas: 20
minReplicas: 2
metrics:
- resource:
name: cpu
target:
averageUtilization: 70
type: Utilization
type: Resource
5. 高级应用场景
5.1 多集群DNS联邦
通过配置federation插件可以实现跨集群服务发现:
yaml复制kubernetes cluster.local in-addr.arpa ip6.arpa {
federation {
prod prod-cluster.local
dev dev-cluster.local
}
}
5.2 基于DNS的服务分流
结合template插件实现智能路由:
yaml复制template IN A my-service {
match "^my-service\.dev\.svc\.cluster\.local$"
answer "{{ .Name }} 60 IN A 10.96.1.10"
fallthrough
}
5.3 安全加固配置
- 禁用递归查询:
yaml复制forward . /etc/resolv.conf {
policy sequential
max_concurrent 1000
}
- 启用DNS-over-TLS:
yaml复制forward . tls://9.9.9.9 tls://1.1.1.1 {
tls_servername dns.quad9.net
health_check 5s
}
在实际生产环境中,CoreDNS的性能表现与集群规模、查询模式密切相关。根据我们的经验,一个4核8G的CoreDNS实例可以轻松处理每秒5000+的DNS查询请求。关键在于合理配置缓存策略和副本数量。
