Kubernetes 網路架構完整指南:CNI、Service、Ingress 一次搞懂

Kubernetes 網路架構完整指南:CNI、Service、Ingress 一次搞懂
Kubernetes 網路是最複雜的部分之一。
Pod IP、Service IP、ClusterIP、NodePort、Ingress⋯⋯這些概念容易混淆。但只要理解網路模型,一切就會清晰。
這篇文章會完整解析 Kubernetes 的網路架構。
Kubernetes 的基本介紹,請參考 Kubernetes 完整指南。
Kubernetes 網路模型
Kubernetes 的網路設計遵循幾個基本原則。
基本原則
Kubernetes 網路有四個核心原則:
| 原則 | 說明 |
|---|---|
| Pod 到 Pod | 任何 Pod 可以直接和其他 Pod 通訊,不需要 NAT |
| Node 到 Pod | Node 可以直接和 Pod 通訊,不需要 NAT |
| Pod 看到的 IP | Pod 看到自己的 IP,和其他人看到的一樣 |
| 扁平網路 | 所有 Pod 在同一個扁平網路空間 |
為什麼這樣設計?
簡化網路配置。傳統的容器網路需要處理 port mapping,很複雜。Kubernetes 讓每個 Pod 有自己的 IP,就像獨立的機器一樣。
IP 地址類型
Kubernetes 中有幾種 IP:
| IP 類型 | 說明 | 範例 |
|---|---|---|
| Node IP | 節點的真實 IP | 192.168.1.10 |
| Pod IP | Pod 的 IP,會變動 | 10.244.1.5 |
| Cluster IP | Service 的虛擬 IP | 10.96.0.100 |
| External IP | 對外的 IP | 35.200.x.x |
IP 範圍設定:
Node 網路:192.168.0.0/16(公司網路)
Pod 網路:10.244.0.0/16(Kubernetes 內部)
Service 網路:10.96.0.0/12(虛擬 IP)
網路流量路徑
Pod 到 Pod(同 Node):
Pod A → veth → cbr0 (bridge) → veth → Pod B
Pod 到 Pod(跨 Node):
Pod A → veth → cbr0 → Node A 網路 → Node B 網路 → cbr0 → veth → Pod B
外部到 Pod:
外部流量 → Load Balancer → NodePort → Service → Pod
CNI:容器網路介面
Kubernetes 本身不處理網路,而是透過 CNI 插件。
什麼是 CNI
CNI(Container Network Interface) 是容器網路的標準介面。
Kubernetes 呼叫 CNI 插件來:
- 建立 Pod 網路
- 分配 IP 地址
- 設定路由規則
常見 CNI 插件
| 插件 | 特點 | 適合場景 |
|---|---|---|
| Calico | 功能完整,支援 Network Policy | 生產環境首選 |
| Flannel | 簡單輕量 | 入門學習 |
| Cilium | 基於 eBPF,效能好 | 大規模、高效能需求 |
| Weave | 簡單易用,支援加密 | 小型叢集 |
| AWS VPC CNI | AWS 原生整合 | EKS |
| Azure CNI | Azure 原生整合 | AKS |
| GKE CNI | Google 原生整合 | GKE |
Calico 詳解
Calico 是最受歡迎的 CNI 插件。
特點:
| 特點 | 說明 |
|---|---|
| BGP 路由 | 使用標準路由協定 |
| Network Policy | 完整支援 |
| 效能 | 接近原生網路效能 |
| 可擴展 | 適合大規模叢集 |
安裝 Calico:
# 安裝 Calico operator
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.0/manifests/tigera-operator.yaml
# 安裝 Calico
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.0/manifests/custom-resources.yaml
驗證安裝:
kubectl get pods -n calico-system
Cilium 詳解
Cilium 是新一代的 CNI,基於 eBPF 技術。
特點:
| 特點 | 說明 |
|---|---|
| eBPF | 核心層級處理,效能極佳 |
| 可觀測性 | 內建 Hubble 監控 |
| Service Mesh | 可取代 sidecar |
| 安全 | 七層網路政策 |
適合:
- 大規模叢集(>1000 節點)
- 高效能需求
- 需要進階可觀測性
插圖:四欄式比較表格
場景描述: 四欄式比較表格,分別標示 Calico、Flannel、Cilium、Weave 四種 CNI 的特點,每欄下方用星星圖示標示效能、易用性、功能三個維度的評分。需要顯示的中文字:效能、易用性、功能完整度
視覺重點:
- 主要內容清晰呈現
必須出現的元素:
- 依據描述中的關鍵元素
需要顯示的中文字: 無
顏色調性: 專業、清晰
避免元素: 抽象圖形、齒輪、發光特效
Slug:
kubernetes-cni-comparison
Service:服務發現與負載均衡
Pod IP 會變,Service 提供穩定的存取點。
Service 的作用
問題:Pod IP 不穩定
| 情況 | Pod IP 會變嗎? |
|---|---|
| Pod 重啟 | 會 |
| Pod 被重新調度 | 會 |
| 擴展/縮減 | 新 Pod 新 IP |
Service 的解法:
| 功能 | 說明 |
|---|---|
| 穩定端點 | Service IP 不變 |
| DNS 名稱 | 用名稱存取,如 my-service |
| 負載均衡 | 自動分配到後端 Pod |
| 服務發現 | 自動追蹤 Pod 變化 |
ClusterIP
預設類型,只能從叢集內部存取。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP # 預設值,可省略
selector:
app: my-app
ports:
- port: 80 # Service 的 port
targetPort: 8080 # Pod 的 port
存取方式:
# 從叢集內的 Pod
curl http://my-service:80
curl http://my-service.default.svc.cluster.local:80
DNS 格式:
<service-name>.<namespace>.svc.cluster.local
NodePort
在每個 Node 上開放一個 port。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 範圍:30000-32767
存取方式:
# 從外部
curl http://<node-ip>:30080
特點:
| 優點 | 缺點 |
|---|---|
| 簡單,不需要 LB | port 範圍有限 |
| 任何 Node 都能存取 | 需要知道 Node IP |
| 適合測試 | 不適合生產 |
LoadBalancer
使用雲端負載均衡器。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
雲端會自動:
- 建立負載均衡器
- 分配外部 IP
- 設定健康檢查
存取方式:
# 取得外部 IP
kubectl get svc my-service
# EXTERNAL-IP 欄位
curl http://<external-ip>:80
缺點:
| 缺點 | 說明 |
|---|---|
| 成本 | 每個 Service 一個 LB,費用高 |
| 本地不可用 | 需要雲端環境 |
ExternalName
映射到外部 DNS 名稱。
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: db.example.com
用途:
- 存取外部服務
- 遷移過程中的抽象層
Headless Service
不需要負載均衡,直接取得 Pod IP。
apiVersion: v1
kind: Service
metadata:
name: my-headless
spec:
clusterIP: None # 關鍵設定
selector:
app: my-app
ports:
- port: 80
用途:
- StatefulSet(如資料庫)
- 需要直接連線到特定 Pod
🏗️ Kubernetes 網路架構設計?
正確的網路設計影響效能和安全性。讓專家幫你規劃。
👉 預約架構諮詢
Ingress:HTTP 路由
LoadBalancer 每個 Service 一個,太貴。Ingress 解決這個問題。
Ingress 的作用
Ingress 提供:
| 功能 | 說明 |
|---|---|
| 路徑路由 | /api → Service A,/web → Service B |
| 域名路由 | api.example.com → Service A |
| TLS 終止 | 統一處理 HTTPS |
| 成本節省 | 多個 Service 共用一個 LB |
Ingress Controller
Ingress 本身只是規則定義,需要 Ingress Controller 來實現。
| Controller | 特點 |
|---|---|
| NGINX Ingress | 最常用,功能完整 |
| Traefik | 自動服務發現 |
| HAProxy | 高效能 |
| AWS ALB | AWS 原生 |
| GKE Ingress | GCP 原生 |
安裝 NGINX Ingress:
# 使用 Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx
Ingress 設定範例
基本路徑路由:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
多域名路由:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
TLS 設定
建立 TLS Secret:
kubectl create secret tls my-tls-secret \
--cert=path/to/cert.pem \
--key=path/to/key.pem
在 Ingress 中使用:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: my-tls-secret
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
cert-manager 自動憑證
cert-manager 可以自動從 Let's Encrypt 取得憑證。
安裝:
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager --set installCRDs=true
設定 Issuer:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
自動取得憑證:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auto-tls-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls # cert-manager 會自動建立
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
插圖:Kubernetes Ingress 流量路徑示意圖
場景描述: Kubernetes Ingress 流量路徑示意圖,從左到右依序是使用者、雲端負載均衡器、Ingress Controller Pod、根據路徑分流到不同的 Service 和 Pod,使用箭頭標示流量方向。需要顯示的中文字:使用者、負載均衡、路由規則、服務
視覺重點:
- 主要內容清晰呈現
必須出現的元素:
- 依據描述中的關鍵元素
需要顯示的中文字: 無
顏色調性: 專業、清晰
避免元素: 抽象圖形、齒輪、發光特效
Slug:
kubernetes-ingress-traffic-flow
Network Policy:網路安全
預設情況下,所有 Pod 都可以互相通訊。Network Policy 可以限制這點。
為什麼需要 Network Policy
預設行為: 任何 Pod 可以連到任何 Pod
問題:
- 資料庫不應該被前端直接存取
- 不同 namespace 應該隔離
- 只有特定服務可以對外連線
基本概念
Network Policy 控制:
| 方向 | 說明 |
|---|---|
| Ingress | 進入 Pod 的流量 |
| Egress | 從 Pod 出去的流量 |
選擇器:
| 選擇器 | 說明 |
|---|---|
| podSelector | 選擇套用政策的 Pod |
| namespaceSelector | 選擇來源/目的 namespace |
| ipBlock | 選擇 IP 範圍 |
範例:限制進入流量
只允許特定 Pod 存取資料庫:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
namespace: default
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432
這個政策:
- 套用到
app: database的 Pod - 只允許
app: backend的 Pod 連線 - 只開放 5432 port
範例:限制出去流量
Pod 只能連到特定外部 IP:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-policy
spec:
podSelector:
matchLabels:
app: my-app
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8
ports:
- protocol: TCP
port: 443
預設拒絕所有
安全最佳實踐:預設拒絕,明確允許。
# 預設拒絕所有進入流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {} # 選擇所有 Pod
policyTypes:
- Ingress
# 沒有 ingress 規則 = 全部拒絕
# 預設拒絕所有出去流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
# 沒有 egress 規則 = 全部拒絕
注意事項
| 注意 | 說明 |
|---|---|
| CNI 支援 | 不是所有 CNI 都支援 Network Policy |
| DNS 存取 | 記得開放 DNS(kube-dns) |
| 測試 | 先在測試環境驗證 |
支援 Network Policy 的 CNI:
- Calico ✅
- Cilium ✅
- Weave ✅
- Flannel ❌(需要額外設定)
💡 網路安全規劃?
正確的 Network Policy 可以大幅提升安全性。讓我們幫你設計。
👉 預約免費諮詢
網路除錯
網路問題最難除錯。這裡整理常用的方法。
常見問題
| 問題 | 可能原因 |
|---|---|
| Pod 連不到 Service | Service selector 不對、Endpoint 為空 |
| 外部連不進來 | Ingress 設定錯誤、防火牆 |
| DNS 解析失敗 | CoreDNS 問題、Network Policy 阻擋 |
| 跨 Node 連不通 | CNI 問題、網路設定 |
除錯指令
檢查 Service 和 Endpoint:
# 查看 Service
kubectl get svc my-service -o wide
# 查看 Endpoint(應該要有 Pod IP)
kubectl get endpoints my-service
# 如果 Endpoint 為空,檢查 selector
kubectl describe svc my-service
測試連線:
# 建立除錯 Pod
kubectl run debug --image=nicolaka/netshoot -it --rm -- bash
# 在 Pod 內測試
curl http://my-service:80
nslookup my-service
ping <pod-ip>
檢查 DNS:
# 查看 CoreDNS Pod
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 測試 DNS 解析
kubectl run test --image=busybox -it --rm -- nslookup kubernetes
檢查 Network Policy:
# 查看影響 Pod 的 Network Policy
kubectl get networkpolicy
# 查看詳細內容
kubectl describe networkpolicy <policy-name>
常用除錯工具
| 工具 | 用途 |
|---|---|
| netshoot | 網路除錯瑞士刀 |
| tcpdump | 封包擷取 |
| traceroute | 路由追蹤 |
| curl/wget | HTTP 測試 |
| nslookup/dig | DNS 測試 |
FAQ:常見問題
Q1: Pod IP 會變,怎麼辦?
使用 Service。
Service 提供穩定的 IP 和 DNS 名稱。應用程式應該連到 Service,不是 Pod IP。
Q2: ClusterIP 從外部怎麼存取?
不能直接存取。 ClusterIP 只在叢集內有效。
對外存取的方式:
- NodePort
- LoadBalancer
- Ingress
- kubectl port-forward(除錯用)
Q3: 為什麼 Ingress 不動作?
常見原因:
| 原因 | 檢查方式 |
|---|---|
| 沒裝 Ingress Controller | `kubectl get pods -A |
| ingressClassName 不對 | 檢查 Ingress YAML |
| Service 不存在 | kubectl get svc |
| DNS 沒指向 | 檢查 DNS 設定 |
Q4: 多個 Service 可以共用一個 LoadBalancer 嗎?
用 Ingress。
Ingress 就是讓多個 Service 共用一個入口點。
Q5: Network Policy 會影響效能嗎?
微乎其微。
現代 CNI(如 Calico、Cilium)處理 Network Policy 非常高效。除非規則數量極大,否則不用擔心。
下一步
了解 Kubernetes 網路後,你可以:
| 目標 | 行動 |
|---|---|
| 了解架構 | 閱讀 Kubernetes 架構完整解析 |
| 學習物件 | 閱讀 Kubernetes 核心物件教學 |
| 動手實作 | 閱讀 Kubernetes 入門教學 |
| 選擇雲端 | 閱讀 Kubernetes 雲端服務比較 |
🚀 需要 Kubernetes 網路架構諮詢?
從 CNI 選擇到 Ingress 設計,CloudInsight 提供完整的技術支援。
👉 立即預約諮詢
延伸閱讀
- Kubernetes 完整指南 - K8s 入門總覽
- Kubernetes 架構完整解析 - Control Plane 與 Node
- Kubernetes 核心物件教學 - Pod、Service 詳解
- Kubernetes 工具生態系指南 - 服務網格等工具
- Kubernetes 雲端服務比較 - 各雲端的網路差異
參考資料
相關文章
Kubernetes 核心物件完整教學:Pod、Deployment、Service 一次學會
Kubernetes 核心物件完整教學。從 Pod、Deployment、Service 到 ConfigMap、Secret,包含 YAML 範例和實務操作指南。
KubernetesKubernetes 台灣社群完整指南:CNTUG、KCD Taiwan 與學習資源總整理
深入介紹 Kubernetes 台灣社群生態,包含 CNTUG 雲端原生使用者社群、KCD Taiwan 年度大會、技術 Meetup、線上社群與學習資源,幫助您融入台灣 K8s 技術圈。
KubernetesKubernetes 架構完整解析:Control Plane、Node、元件一次搞懂
深入解析 Kubernetes 架構。從 Control Plane 四大元件到 Worker Node 運作原理,包含 API Server、etcd、Scheduler、kubelet 完整說明。