返回首頁Kubernetes

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

17 min 分鐘閱讀
#Kubernetes#網路#CNI#Service#Ingress#Network Policy#Calico#負載均衡

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 到 PodNode 可以直接和 Pod 通訊,不需要 NAT
Pod 看到的 IPPod 看到自己的 IP,和其他人看到的一樣
扁平網路所有 Pod 在同一個扁平網路空間

為什麼這樣設計?

簡化網路配置。傳統的容器網路需要處理 port mapping,很複雜。Kubernetes 讓每個 Pod 有自己的 IP,就像獨立的機器一樣。

IP 地址類型

Kubernetes 中有幾種 IP:

IP 類型說明範例
Node IP節點的真實 IP192.168.1.10
Pod IPPod 的 IP,會變動10.244.1.5
Cluster IPService 的虛擬 IP10.96.0.100
External IP對外的 IP35.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 CNIAWS 原生整合EKS
Azure CNIAzure 原生整合AKS
GKE CNIGoogle 原生整合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

特點:

優點缺點
簡單,不需要 LBport 範圍有限
任何 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 ALBAWS 原生
GKE IngressGCP 原生

安裝 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 連不到 ServiceService 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/wgetHTTP 測試
nslookup/digDNS 測試

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 提供完整的技術支援。

👉 立即預約諮詢


延伸閱讀


參考資料

需要專業的雲端建議?

無論您正在評估雲平台、優化現有架構,或尋找節費方案,我們都能提供協助

預約免費諮詢

相關文章