60·网络进阶

DNS 配置

kubernetesnetworkingdns

DNS 配置

学习目标

  1. 理解 Kubernetes DNS 的作用和工作原理
  2. 掌握 Service 和 Pod 的 DNS 解析规则
  3. 了解 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
ClusterFirstWithHostNetHostNetwork Pod 使用集群 DNSHostNetwork 模式

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...

继续学习

完成本课后,建议继续学习下一课「存储概述」 以巩固所学知识。