1. Services & Endpoints
建立 Service 時,Kubernetes 會自動建立包含符合 selector 的 Pod IP 清單的 Endpoints 物件。
# Service → Endpoints → Pods
kubectl get service my-app # 虛擬 IP (ClusterIP)
kubectl get endpoints my-app # 清單: 10.244.1.2:80, 10.244.1.3:80
kubectl describe endpoints my-app # 詳細
# Endpoints 為空 → selector 與 Pod 標籤不匹配
# 除錯: 比較 selector 和 Pod 標籤
kubectl get svc my-app -o jsonpath='{.spec.selector}'
kubectl get pods --show-labels | grep app=my-app
2. CoreDNS 設定
# CoreDNS 在 kube-system 以 Deployment 運行
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl get configmap coredns -n kube-system -o yaml
# 預設 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
}
考試重點:CoreDNS 故障排除步驟:1) 確認 CoreDNS Pod 運行中、2) 檢查 kube-system 中的 kube-dns Service、3) 在 Pod 內用
kubectl exec -it pod -- nslookup kubernetes測試 DNS、4) 確認 Pod 的/etc/resolv.conf指向 kube-dns ClusterIP。
3. kube-proxy 模式
| 模式 | 機制 | 效能 |
|---|---|---|
| iptables(預設) | Linux iptables 規則,隨機選擇 Pod | 良好,O(n) 規則 |
| IPVS | Linux IPVS(核心層,基於雜湊) | 大規模叢集最佳 |
| userspace(已棄用) | 使用者空間代理 | 較慢,舊版 |
4. Headless Service
# Headless: clusterIP: None
# DNS 直接回傳 Pod IP(無虛擬 IP)
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
spec:
clusterIP: None
selector:
app: mysql
ports:
- port: 3306
# DNS 行為:
# mysql-headless → 多筆 A 記錄(每個 Pod IP 一筆)
# mysql-0.mysql-headless → 特定 Pod IP(StatefulSet)
5. DNS 故障排除指令
# 從 Pod 內測試 DNS
kubectl run dns-test --image=busybox --rm -it -- nslookup kubernetes
kubectl run dns-test --image=busybox --rm -it -- nslookup my-service.namespace
# 確認 Pod 的 resolv.conf
kubectl exec -it my-pod -- cat /etc/resolv.conf
# 應顯示: nameserver 10.96.0.10 (kube-dns service IP)
# 檢查 CoreDNS 日誌
kubectl logs -n kube-system -l k8s-app=kube-dns
# 確認 kube-dns Service
kubectl get svc -n kube-system kube-dns
6. 速查表
| 問題 | 檢查方式 |
|---|---|
| Service 無法到達 Pod | kubectl get endpoints NAME |
| Endpoints 為空 | Service selector 與 Pod 標籤不匹配 |
| Pod 無法解析 DNS | /etc/resolv.conf + CoreDNS Pod 狀態 |
| StatefulSet Pod DNS | 需要與 serviceName 同名的 Headless Service |
7. 練習題
Q1:建立了 Service 但流量無法到達 Pod。Service 的 Endpoints 物件顯示 "no endpoints"。最可能的原因是?
- A) Service 連接埠與容器連接埠不匹配
- B) Service selector 的標籤與 Pod 標籤不匹配 ✓
- C) NetworkPolicy 封鎖了流量
- D) Pod 在另一個叢集
解析:Endpoints 為空表示 Service 找不到匹配的 Pod。原因是標籤 selector 不匹配。檢查方式:比較 kubectl get svc myapp -o jsonpath='{.spec.selector}' 和 kubectl get pods --show-labels。
Q2:在 "frontend" Namespace 運行的 Pod 需要存取 "backend" Namespace 的 "payments" Service。正確的 DNS 名稱是?
- A) payments
- B) payments.backend
- C) payments.backend.svc.cluster.local ✓
- D) backend.payments.cluster.local
解析:跨 Namespace 的 DNS 需要指定完整的 Namespace:{service}.{namespace}.svc.cluster.local。短名稱只在同一 Namespace 內有效。B 和 C 都可以運作,但 C 是最明確且可靠的格式。
Q3:CoreDNS 沒有回應。適當的診斷步驟是?
- A) 重新啟動整個叢集
- B) 確認 CoreDNS Pod 運行中、檢查 kube-dns Service 的 ClusterIP、從 Pod 內用 nslookup 測試 ✓
- C) 重新安裝 kube-proxy
- D) 重建 kube-system Namespace
解析:系統化 DNS 除錯:(1) kubectl get pods -n kube-system -l k8s-app=kube-dns、(2) 確認 kube-dns Service 有 ClusterIP、(3) 確認 Pod 的 /etc/resolv.conf 指向該 IP、(4) 從測試 Pod 執行 nslookup。