# K8s DNS


# K8s DNS

其實就跟你所認知的 DNS Server 相同,只不過在 k8s 中 k8s DNS 是用來將 Domain Name 解析成 K8s 上的 Resource 作使用的,而且 K8s DNS 非常彈性,可以運用 DNS + DNS Plugin API 組合成最適合自己的解決方案


# K8s DNS 解析過程

假設我想要去 Request 一個 K8s Service

同一個 Namespace

1
curl non-existent-service

不同的 Namespace

1
curl non-existent-service.default

你可以發現到如果一個 Resource 不在自己的 Namespace 就會需要 DNS 來協主解析了

這時候會用到一些 System 的資訊來進行協助

  1. /etc/host.conf
  2. /etc/hosts
  3. /etc/resolv.conf

其中會依序查找

  1. Namespace
  2. Resource Type
  3. Node

# DNS Policy

  • ClusterFirstWithHostNet
    • 如果 Pod 使用 hostnetwork 直接套用 Node 上的 resolv.conf
  • ClusterFirst
    • Pod 內的 DNS 優先使用 CoreDNS
  • Default
    • 讓 kubelet 決定
    • 預設使用 Node 中的 resolv.conf
  • None
    • 不指定
    • 由 dnsconfig 內容進行定義

# KubeDNS VS CoreDNS

# kubeDNS

在 K8s 1.21 後停止支援 (已經被 kubeadm 移除)

優點

  • 有 dnsmesq,有快取效能

缺點

  • 如果 dnsmesq 重啟,行程會被砍掉後重啟,可能造成解析作物

# CoreDNS

優點

  • 可以自訂 Plugin 記憶體效能比較好

缺點

  • 因沒有 dnsmesq 快取效率稍微差一點

# 錯誤處理流程


# 部屬 DNS Utils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
name: dnsutils
namespace: default
spec:
containers:
- name: dnsutils
image: registry.k8s.io/e2e-test-images/jessie-dnsutils:1.3
command:
- sleep
- "infinity"
securityContext:
capabilities:
add:
- NET_RAW
imagePullPolicy: IfNotPresent
restartPolicy: Always
1
2
kubectl create -f dnsutils.yaml -n default
kubectl get podils.yaml -n default

# Ping 測試解析

1
2
3
4
kubectl exec -it dnsutils /bin/sh # 進入 dnsutils
ping kubernetes.default # 測試 K8s API 連線
ping default.svc.cluster.local # 測試服務群組連線
kubectl exec -it dnsutils -n default -- env | grep KUBERNETES #查詢環境變數是否有被註冊

# 路由解析過程測試

1
2
3
nslookup kubernetes.default
nslookup default.svc.cluster.local
# 有出現 Timeout 代表有解析異常

# 確認 CoreDNS pod status

1
kubectl get pods -l k8s-app=kube-dns -n kube-system

# 參考資料

  • CoreDNS 簡單除錯:解決你遇到的一般問題
更新於