DNS 配置
学习目标
- 理解 Kubernetes DNS 的作用和工作原理
- 掌握 Service 和 Pod 的 DNS 解析规则
- 了解 CoreDNS 的配置和自定义
核心概念
一句话解释
Kubernetes DNS 为 Service 和 Pod 提供自动 DNS 解析,使得服务之间可以通过域名而不是 IP 地址进行通信。
为什么需要 DNS
问题:使用 IP 地址访问服务
Service A (10.96.0.100) → Service B (10.96.0.101)
↓
Pod B1 (10.1.1.2)
Pod B2 (10.1.1.3)
Pod B3 (10.1.1.4)
问题:
- IP 地址难以记忆
- IP 地址可能变化
- 不便于服务发现
解决方案:DNS
Service A → http://service-b → Service B (10.96.0.101)
↓
自动负载均衡到 Pod
Kubernetes DNS 解析规则
Service DNS 格式:
┌─────────────────────────────────────────────────────┐
│ <service-name>.<namespace>.svc.cluster.local │
│ │
│ 示例: │
│ my-service.default.svc.cluster.local │
│ │
│ 同 namespace 简化: │
│ my-service(省略后缀) │
└─────────────────────────────────────────────────────┘
Pod DNS 格式:
┌─────────────────────────────────────────────────────┐
│ <pod-ip>.<namespace>.pod.cluster.local │
│ │
│ 示例: │
│ 10-1-1-2.default.pod.cluster.local │
│ (IP 中的 . 替换为 -) │
└─────────────────────────────────────────────────────┘
DNS 解析流程
Pod 内的 DNS 解析流程:
1. 应用代码发起 DNS 查询
http://my-service
↓
2. Pod 的 /etc/resolv.conf
nameserver 10.96.0.10 (CoreDNS)
search default.svc.cluster.local svc.cluster.local cluster.local
↓
3. 查询 CoreDNS
my-service.default.svc.cluster.local
↓
4. CoreDNS 返回 Service ClusterIP
10.96.0.100
↓
5. 应用连接到 Service
http://10.96.0.100
Service DNS 记录
# 查看 Service 的 DNS 记录
kubectl get svc my-service
# DNS 解析示例
# Service: my-service
# Namespace: default
# ClusterIP: 10.96.0.100
# 完整 DNS 名称:
# my-service.default.svc.cluster.local
# 同 namespace 可以简化:
# my-service
# 跨 namespace:
# my-service.other-namespace
Pod DNS 记录
# 查看 Pod 的 DNS 记录
kubectl get pod my-pod -o wide
# Pod IP: 10.1.1.2
# Namespace: default
# DNS 名称:
# 10-1-1-2.default.pod.cluster.local
# 注意:IP 中的 . 替换为 -
CoreDNS
CoreDNS 是 Kubernetes 的默认 DNS 服务器
CoreDNS 功能:
- 为 Service 提供 DNS 记录
- 为 Pod 提供 DNS 记录
- 转发外部 DNS 查询
- 支持自定义配置
CoreDNS 部署:
┌─────────────────────────────────────────────────────┐
│ kube-system namespace │
│ ┌─────────────────────────────────────────────────┐│
│ │ CoreDNS Deployment ││
│ │ - 2 个 Pod(默认) ││
│ │ - 监听 53 端口 ││
│ │ - 处理集群内 DNS 查询 ││
│ └─────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────┘
CoreDNS 配置
# CoreDNS 配置(ConfigMap)
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
}
自定义 DNS 配置
# Pod 自定义 DNS 配置
apiVersion: v1
kind: Pod
metadata:
name: custom-dns
spec:
dnsPolicy: "None" # 使用自定义 DNS
dnsConfig:
nameservers:
- 8.8.8.8
- 8.8.4.4
searches:
- my-namespace.svc.cluster.local
- svc.cluster.local
- cluster.local
options:
- name: ndots
value: "5"
containers:
- name: app
image: nginx
DNS 策略
# DNS 策略选项
apiVersion: v1
kind: Pod
metadata:
name: dns-policy
spec:
dnsPolicy: "ClusterFirst" # 默认策略
containers:
- name: app
image: nginx
| 策略 | 说明 | 使用场景 |
|---|---|---|
| ClusterFirst | 集群内查询走 CoreDNS,外部走上游 DNS | 默认策略 |
| Default | 使用节点的 DNS 配置 | 需要访问外部 DNS |
| None | 使用自定义 dnsConfig | 完全自定义 DNS |
| ClusterFirstWithHostNet | HostNetwork Pod 使用集群 DNS | HostNetwork 模式 |
DNS 调试
# 查看 CoreDNS Pod
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 查看 CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns
# 测试 DNS 解析
kubectl run dns-test --image=busybox --rm -it -- nslookup kubernetes.default
# 详细 DNS 查询
kubectl run dns-test --image=busybox --rm -it -- nslookup -type=A my-service.default.svc.cluster.local
# 查看 Pod 的 DNS 配置
kubectl exec my-pod -- cat /etc/resolv.conf
外部 DNS 集成
# 使用 ExternalName Service 访问外部服务
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
type: ExternalName
externalName: api.external.com
# 使用 External DNS 自动管理 DNS 记录
# 安装 External DNS
# kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/external-dns/master/docs/contributing/external-dns.yaml
# Ingress 自动生成 DNS 记录
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
external-dns.alpha.kubernetes.io/hostname: app.example.com
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
实践练习
练习 1:查看 CoreDNS 配置
# 查看 CoreDNS Pod
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 查看 CoreDNS ConfigMap
kubectl get configmap coredns -n kube-system -o yaml
# 查看 CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns
练习 2:测试 Service DNS 解析
# 创建测试 Service
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80
# 测试 DNS 解析
kubectl run dns-test --image=busybox --rm -it -- nslookup nginx
# 测试完整域名
kubectl run dns-test --image=busybox --rm -it -- nslookup nginx.default.svc.cluster.local
# 测试跨 namespace
kubectl create namespace test-ns
kubectl run test-pod -n test-ns --image=busybox --command -- sleep 3600
kubectl exec -n test-ns test-pod -- nslookup nginx.default
练习 3:查看 Pod DNS 配置
# 创建 Pod
kubectl run test-pod --image=busybox --command -- sleep 3600
# 查看 DNS 配置
kubectl exec test-pod -- cat /etc/resolv.conf
# 测试 DNS 解析
kubectl exec test-pod -- nslookup kubernetes.default
kubectl exec test-pod -- nslookup nginx.default.svc.cluster.local
练习 4:自定义 DNS 配置
# 创建自定义 DNS 的 Pod
apiVersion: v1
kind: Pod
metadata:
name: custom-dns-pod
spec:
dnsPolicy: "None"
dnsConfig:
nameservers:
- 8.8.8.8
options:
- name: ndots
value: "2"
containers:
- name: busybox
image: busybox
command: ["sleep", "3600"]
# 应用配置
kubectl apply -f custom-dns-pod.yaml
# 查看自定义 DNS 配置
kubectl exec custom-dns-pod -- cat /etc/resolv.conf
# 测试 DNS 解析
kubectl exec custom-dns-pod -- nslookup nginx.default.svc.cluster.local
kubectl exec custom-dns-pod -- nslookup google.com
练习 5:调试 DNS 问题
# 创建测试 Pod
kubectl run dns-debug --image=busybox --command -- sleep 3600
# 测试 DNS 解析
kubectl exec dns-debug -- nslookup kubernetes.default
# 如果失败,检查 CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
# 检查 Service
kubectl get svc
kubectl get endpoints
# 检查网络连通性
kubectl exec dns-debug -- wget -qO- http://nginx.default
常见误解
1. DNS 是 Kubernetes 内置的
错误理解:Kubernetes 自带 DNS
正确理解:需要安装 CoreDNS(通常在集群初始化时自动安装)
CoreDNS 是独立的组件
以 Deployment 形式运行在 kube-system namespace
2. 所有域名都需要完整格式
错误理解:必须使用完整域名 service.namespace.svc.cluster.local
正确理解:同 namespace 可以简化
完整格式:my-service.default.svc.cluster.local
同 namespace:my-service
跨 namespace:my-service.other-namespace
3. DNS 解析是即时的
错误理解:DNS 解析立即生效
正确理解:有 TTL 缓存
CoreDNS 默认 TTL: 30 秒
应用可能缓存 DNS 结果
Service 变化后可能需要等待缓存过期
小结
| 要点 | 说明 |
|---|---|
| Kubernetes DNS | 为 Service 和 Pod 提供自动 DNS 解析 |
| CoreDNS | 默认 DNS 服务器,运行在 kube-system |
| Service DNS | <service>.<namespace>.svc.cluster.local |
| Pod DNS | <pod-ip>.<namespace>.pod.cluster.local |
| DNS 策略 | ClusterFirst、Default、None、ClusterFirstWithHostNet |
| 调试方法 | nslookup、查看 CoreDNS 日志、检查配置 |
练习编辑器
bash
Loading...