第16章 CoreDNS与服务发现
学习目标
- 理解CoreDNS在Kubernetes中的作用和配置
- 掌握DNS服务发现的原理和实现
- 了解CoreDNS插件系统和自定义配置
- 能够排查DNS相关的网络问题
前置知识
16.1 CoreDNS概述
16.1.1 什么是CoreDNS
CoreDNS是Kubernetes集群的默认DNS服务器,提供集群内服务发现和外部域名解析功能。
核心特性:
- 插件化架构,功能模块化
- 高性能DNS服务器
- 支持多种DNS记录类型
- 与Kubernetes深度集成
- 支持自定义DNS解析规则
16.1.2 CoreDNS架构
┌─────────────────────────────────────────────────────────────┐
│ CoreDNS Architecture │
├─────────────────────────────────────────────────────────────┤
│ DNS Query Handler │
├─────────────────────────────────────────────────────────────┤
│ Plugin Chain (kubernetes, forward, cache, etc.) │
├─────────────────────────────────────────────────────────────┤
│ Backend (Kubernetes API, External DNS) │
└─────────────────────────────────────────────────────────────┘
16.1.3 DNS查询流程
- Pod发起DNS查询:应用程序查询服务名称
- CoreDNS接收查询:CoreDNS接收DNS查询请求
- 插件链处理:通过插件链处理查询
- 返回解析结果:返回IP地址或CNAME记录
16.2 CoreDNS配置
16.2.1 基本配置
Corefile配置:
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
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
配置说明:
errors:错误日志插件health:健康检查插件ready:就绪检查插件kubernetes:Kubernetes服务发现插件prometheus:监控指标插件forward:转发插件cache:缓存插件loadbalance:负载均衡插件
16.2.2 高级配置
多区域配置:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health
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
}
example.com:53 {
errors
cache 30
forward . 8.8.8.8 8.8.4.4
}
16.3 Kubernetes服务发现
16.3.1 DNS记录类型
1. A记录(Service)
# 查询Service A记录
nslookup nginx-service.default.svc.cluster.local
# 简化查询
nslookup nginx-service
2. SRV记录(端口信息)
# 查询SRV记录
nslookup -type=SRV _http._tcp.nginx-service.default.svc.cluster.local
3. PTR记录(反向解析)
# 查询PTR记录
nslookup 10.96.0.1
16.3.2 DNS查询规则
完全限定域名(FQDN):
<service-name>.<namespace>.svc.cluster.local
查询优先级:
- 完全限定域名
- 服务名.命名空间
- 服务名(同命名空间)
示例:
# 完全限定域名
nginx-service.default.svc.cluster.local
# 命名空间限定
nginx-service.default
# 同命名空间
nginx-service
16.4 实验:CoreDNS功能验证
16.4.1 实验环境准备
创建测试应用:
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
---
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIP
部署应用:
# 创建Deployment和Service
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
# 验证部署
kubectl get pods,svc
16.4.2 实验1:基本DNS解析
步骤1:创建测试Pod
# 创建测试Pod
kubectl run test-pod --image=busybox -it --rm -- sh
# 在Pod内测试DNS解析
nslookup nginx-service
nslookup nginx-service.default
nslookup nginx-service.default.svc.cluster.local
步骤2:验证不同查询方式
# 测试简化查询
nslookup nginx-service
# 测试命名空间限定查询
nslookup nginx-service.default
# 测试完全限定域名查询
nslookup nginx-service.default.svc.cluster.local
# 测试外部域名解析
nslookup google.com
预期输出:
# nginx-service查询结果
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-service
Address 1: 10.96.0.1 nginx-service.default.svc.cluster.local
16.4.3 实验2:SRV记录查询
步骤1:创建Headless Service
# headless-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
spec:
clusterIP: None
selector:
app: nginx
ports:
- port: 80
targetPort: 80
步骤2:测试SRV记录
# 部署Headless Service
kubectl apply -f headless-service.yaml
# 查询SRV记录
nslookup -type=SRV _http._tcp.nginx-headless.default.svc.cluster.local
# 查询A记录
nslookup nginx-headless.default.svc.cluster.local
16.4.4 实验3:自定义DNS配置
步骤1:创建自定义CoreDNS配置
# custom-coredns.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health
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
}
# 自定义域名解析
internal.company.com:53 {
errors
cache 30
forward . 192.168.1.10
}
# 本地域名解析
local:53 {
errors
cache 30
file /etc/coredns/local.db
}
步骤2:应用自定义配置
# 应用配置
kubectl apply -f custom-coredns.yaml
# 重启CoreDNS
kubectl rollout restart deployment/coredns -n kube-system
# 验证配置
kubectl get configmap coredns -n kube-system -o yaml
16.5 CoreDNS插件详解
16.5.1 Kubernetes插件
功能: 提供Kubernetes服务发现
配置示例:
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
endpoint https://kubernetes.default.svc.cluster.local:443
tls /etc/coredns/cert.pem /etc/coredns/key.pem /etc/coredns/ca.pem
}
参数说明:
pods insecure:允许Pod IP查询fallthrough:查询失败时转发到下一个插件ttl:DNS记录TTL值endpoint:Kubernetes API Server地址tls:TLS证书配置
16.5.2 Forward插件
功能: 转发DNS查询到上游服务器
配置示例:
forward . /etc/resolv.conf {
max_concurrent 1000
except example.com
}
参数说明:
max_concurrent:最大并发查询数except:排除的域名
16.5.3 Cache插件
功能: 缓存DNS查询结果
配置示例:
cache 30 {
success 9984 30
denial 9984 5
}
参数说明:
success:成功查询缓存时间denial:否定查询缓存时间
16.5.4 Rewrite插件
功能: 重写DNS查询
配置示例:
rewrite name regex (.*)\.local\.$ {1}.default.svc.cluster.local
16.6 性能优化
16.6.1 缓存配置
优化缓存设置:
cache 300 {
success 9984 300
denial 9984 30
prefetch 1m 10% 1h
}
参数说明:
success:成功查询缓存5分钟denial:否定查询缓存30秒prefetch:预取热点记录
16.6.2 并发控制
配置并发限制:
forward . /etc/resolv.conf {
max_concurrent 1000
health_check 5s
}
16.6.3 资源限制
配置资源限制:
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health
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
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
spec:
template:
spec:
containers:
- name: coredns
image: coredns/coredns:1.8.6
resources:
limits:
memory: 170Mi
cpu: 100m
requests:
memory: 70Mi
cpu: 100m
16.7 监控和日志
16.7.1 Prometheus监控
启用监控:
prometheus :9153 {
health
}
查看指标:
# 访问监控端点
curl http://coredns-pod-ip:9153/metrics
# 查看关键指标
curl http://coredns-pod-ip:9153/metrics | grep coredns_dns_requests_total
16.7.2 日志配置
启用详细日志:
log . {
class error
class success
}
查看日志:
# 查看CoreDNS日志
kubectl logs -n kube-system -l k8s-app=kube-dns
# 实时查看日志
kubectl logs -n kube-system -l k8s-app=kube-dns -f
16.8 故障排查
16.8.1 常见问题诊断
问题1:DNS解析失败
# 检查CoreDNS状态
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 检查CoreDNS配置
kubectl get configmap coredns -n kube-system -o yaml
# 测试DNS解析
kubectl run test-pod --image=busybox -it --rm -- nslookup nginx-service
问题2:外部域名解析失败
# 检查forward配置
kubectl get configmap coredns -n kube-system -o yaml | grep forward
# 测试外部DNS
kubectl run test-pod --image=busybox -it --rm -- nslookup google.com
# 检查网络连通性
kubectl run test-pod --image=busybox -it --rm -- ping 8.8.8.8
问题3:性能问题
# 查看CoreDNS资源使用
kubectl top pods -n kube-system -l k8s-app=kube-dns
# 查看监控指标
curl http://coredns-pod-ip:9153/metrics | grep coredns_dns_requests_total
# 检查缓存命中率
curl http://coredns-pod-ip:9153/metrics | grep coredns_cache
16.8.2 调试工具
# 使用dig工具
kubectl run test-pod --image=busybox -it --rm -- dig nginx-service.default.svc.cluster.local
# 使用nslookup
kubectl run test-pod --image=busybox -it --rm -- nslookup nginx-service
# 使用host命令
kubectl run test-pod --image=busybox -it --rm -- host nginx-service
16.9 排错清单
16.9.1 DNS配置检查
- [ ] CoreDNS Pod是否正常运行
- [ ] Corefile配置是否正确
- [ ] 插件配置是否合理
- [ ] 缓存设置是否合适
- [ ] 转发配置是否正确
16.9.2 网络连通性检查
- [ ] Pod网络是否正常
- [ ] 外部DNS服务器是否可达
- [ ] 防火墙是否阻止DNS流量
- [ ] 网络策略是否影响DNS
- [ ] 负载均衡是否正常
16.9.3 性能问题检查
- [ ] CPU使用率是否过高
- [ ] 内存使用是否正常
- [ ] 缓存命中率是否合理
- [ ] 并发查询数是否过多
- [ ] 响应时间是否正常
16.10 延伸阅读
返回目录:README