首頁文章關於報價聯絡我們🌐 EN
返回首頁Kubernetes
Kubernetes 網路架構完整指南:CNI、Service、Ingress 一次搞懂

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

📑 目錄

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 插件來:

常見 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
安全七層網路政策

適合:



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

用途:


🏗️ 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


Network Policy:網路安全

預設情況下,所有 Pod 都可以互相通訊。Network Policy 可以限制這點。

為什麼需要 Network Policy

預設行為: 任何 Pod 可以連到任何 Pod

問題:

基本概念

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

這個政策:

範例:限制出去流量

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:


💡 網路安全規劃?

正確的 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 只在叢集內有效。

對外存取的方式:

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

👉 立即預約諮詢



延伸閱讀



參考資料

KubernetesAWSGCPAzureDocker
上一篇
Kubernetes 核心物件完整教學:Pod、Deployment、Service 一次學會
下一篇
Kubernetes 是什麼?K8s 完整指南:架構、教學與實戰入門【2025 更新】