Kubernetes 網路環境的建置,仰賴 CNI 外掛程式與網路位址空間的妥善規劃。選擇 CNI 時,除了考量功能特性外,更需注意與雲端供應商 SDN、網路安全及監控工具的相容性。服務 API 則提供 Pod 穩定的存取方式,透過 kube-proxy 管理 Pod 端點對映,確保服務穩定運作。本文將探討 ClusterIP、NodePort 等服務型別,並解析 Ingress 和 Gateway API 的應用,最後探討網路安全策略及服務網格的最佳實務,協助讀者建構高效率且安全的 Kubernetes 網路環境。

Kubernetes 網路最佳實踐與服務型別解析

Kubernetes 環境中的網路設計對於應用程式的可靠運作至關重要。正確組態虛擬元件與實體網路環境之間的互動,能夠確保應用程式之間的通訊穩定且高效。

網路設計關鍵考量

  1. 評估所需功能特性:選擇適合的 CNI 外掛程式,以滿足整體網路目標。某些 CNI 外掛程式提供原生高用性、多雲端連線、Kubernetes 網路策略支援等功能。
  2. 驗證 CNI 外掛程式的相容性:在公有雲環境中,確認所選的 CNI 外掛程式是否與雲端服務供應商的軟體定義網路(SDN)相容。
  3. 確保網路安全與監控工具的相容性:選擇與所選 CNI 外掛程式相容的網路安全、監控和管理工具。若不相容,需研究替代方案,以保持可觀察性和安全性。例如,可使用 Weaveworks Weave Scope、Dynatrace 和 Sysdig 等工具。在公有雲的託管服務中,可利用原生工具,如 Azure Container Insights 和 Network Watcher、Google Logging and Monitoring,以及 AWS CloudWatch。這些工具應提供網路堆積疊的洞察力,以及 Google SRE 團隊提出的四大黃金訊號:延遲、流量、錯誤和飽和度。
  4. 規劃網路位址空間:若使用的 CNI 不提供與 SDN 空間分離的覆寫網路,需確保有足夠的網路位址空間,以處理節點 IP、Pod IP、內部負載平衡器,以及叢集升級和擴充套件所需的額外位址。

Kubernetes 中的服務

在 Kubernetes 中,Pod 預設只能與同一叢集內的其他 Pod 直接通訊。雖然某些 CNI 外掛程式允許 Pod 獲得與節點相同的網路空間 IP,但由於 Pod 的短暫性,直接存取 Pod IP 並非高效的服務存取方式。因此,需要服務 API 來提供穩定的 IP 和埠對映到後端 Pod。

服務 API 的運作機制

服務 API 為 Kubernetes 叢集內的 Pod 提供一個持久的 IP 和埠,並自動對映到正確的 Pod 端點。這一對映由執行在每個節點上的 kube-proxy 服務管理,透過 iptables 或 IPVS 實作服務 IP 和埠到端點 IP 的對映。

服務型別

  1. ClusterIP:預設的服務型別,為服務分配一個來自指定服務 CIDR 範圍的 IP。該 IP 與服務物件一樣持久,並提供 IP 和埠以及協定對映到後端 Pod。服務還具有 DNS 名稱,方便叢集內的服務發現。

    apiVersion: v1
    kind: Service
    metadata:
      name: web1-svc
    spec:
      selector:
        app: web1
      ports:
      - port: 80
        targetPort: 8081
    

    若客戶端位於同一名稱空間,可使用 http://web1-svc 存取服務;若位於其他名稱空間,則使用 <service_name>.<namespace_name>.svc.cluster.local 的 DNS 模式。

  2. NodePort:在叢集的每個節點上為服務分配一個高埠(30000-32767 範圍內)。可透過 NodeIP:NodePort 從叢集外部直接存取服務。此型別通常用於本地叢集或自定義解決方案。

重點整理

  • 正確選擇和組態 CNI 外掛程式對於 Kubernetes 網路設計至關重要。
  • 服務 API 提供穩定的 IP 和埠對映,方便叢集內部和外部對 Pod 的存取。
  • ClusterIP 和 NodePort 是兩種常見的服務型別,分別適用於叢集內部通訊和外部存取需求。

網路架構視覺化

圖表翻譯: 此圖示展示了客戶端如何透過 NodePort 存取 Kubernetes 叢集內的服務,並最終路由到後端的 Pod。請求首先到達節點的 NodePort,然後透過 iptables 或 IPVS 規則轉發到 ClusterIP,最終根據選擇器路由到具體的 Pod。回應則沿著相反的路徑傳回客戶端。

Kubernetes 中的服務型別與網路管理

Kubernetes 提供多種服務型別以滿足不同的網路需求,其中包括 ExternalNameLoadBalancer 以及重要的 Ingress 與新興的 Gateway API。這些服務型別在 Kubernetes 網路架構中扮演著關鍵角色,確保應用程式能夠穩定且安全地對外提供服務。

ExternalName 服務型別

ExternalName 服務型別較少被使用,但它在將叢集內的 DNS 名稱對映到外部服務時非常有用。例如,當使用雲端供應商提供的外部資料函式庫服務時,可以透過 ExternalName 建立一個更通用的名稱(如 prod-mongodb),這樣便於在需要時更改實際的資料函式庫服務而無需重新啟動 Pod。

kind: Service
apiVersion: v1
metadata:
  name: prod-mongodb
  namespace: prod
spec:
  type: ExternalName
  externalName: mymongodb.documents.azure.com

內容解密:

  • type: ExternalName 指定了服務的型別為 ExternalName
  • externalName 欄位定義了外部服務的 DNS 名稱,在此例中為 mymongodb.documents.azure.com
  • 這種方式使得叢集內的應用程式可以透過 prod-mongodb 存取外部的 MongoDB 服務,提高了組態的靈活性。

LoadBalancer 服務型別

LoadBalancer 是一種特殊的服務型別,能夠與雲端供應商或其他可程式化的雲端基礎設施服務進行自動化整合。它提供了一種統一的方式來佈署由基礎設施供應商提供的負載平衡機制。這意味著在大多數情況下,LoadBalancer 在 AWS、Azure、GCE、OpenStack 等平台上的運作方式大致相同。

kind: Service
apiVersion: v1
metadata:
  name: web-svc
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8081
  loadBalancerIP: 13.12.21.31
  loadBalancerSourceRanges:
  - "142.43.0.0/16"

內容解密:

  • type: LoadBalancer 定義了服務型別為負載平衡器。
  • selectorports 定義瞭如何選擇後端 Pod 及轉發規則。
  • loadBalancerIP 指定了負載平衡器的 IP 位址。
  • loadBalancerSourceRanges 設定允許存取的來源 IP 範圍,增強了安全性。

Ingress 與 Ingress 控制器

雖然 Ingress 在技術上並不是一種服務型別,但它是 Kubernetes 中一個重要的網路概念,用於管理進入叢集的工作負載的流量。Ingress API 提供了一個 HTTP 等級的路由器,能夠根據主機名和路徑將流量導向後端的特定服務。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: labs-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
  - hosts:
    - www.evillgenius.com
    secretName: secret-tls
  rules:
  - host: www.evillgenius.com
    http:
      paths:
      - path: /registration
        pathType: ImplementationSpecific
        backend:
          service:
            name: reg-svc
            port:
              number: 8088
      - path: /labaccess
        pathType: ImplementationSpecific
        backend:
          service:
            name: labaccess-svc
            port:
              number: 8089

內容解密:

  • Ingress 資源定義了根據主機名和路徑的路由規則,將流量導向後端服務。
  • tls 部分組態了 TLS 終止,使用指定的 Secret (secret-tls) 對流量進行加密。
  • rules 部分定義了具體的路由規則,將不同路徑的請求轉發到對應的後端服務。

Gateway API

Gateway API 是 Kubernetes 為瞭解決 Ingress API 的一些限制而引入的新 API。它提供了更為靈活和可擴充套件的網路管理能力,支援多種協定,並且更貼近基礎設施元件的管理模式。

圖表翻譯:

此圖表展示了 Gateway API 的角色分工模式,不同角色負責不同的任務,從而實作了更靈活和可擴充套件的網路管理。

網路安全策略與服務網路最佳實踐

隨著Kubernetes叢集規模的擴大和複雜度的增加,網路安全和管理變得越來越重要。Kubernetes提供了一系列工具和API來幫助管理網路流量和安全,例如Ingress API、NetworkPolicy API等。本文將探討Kubernetes中的網路安全策略和服務網路最佳實踐。

網路安全策略

Kubernetes中的NetworkPolicy API允許使用者定義網路層級的入口和出口存取控制。網路策略允許使用者控制不同Pod之間的通訊以及與其他端點的通訊。

網路策略的基本結構

網路策略具有簡單的YAML結構,主要包括podSelectoringressegresspolicyTypes欄位。其中,podSelector是必填欄位,用於選擇要套用網路策略的Pod。

  • podSelector:根據標籤選擇要套用網路策略的Pod。
  • ingress:定義允許進入Pod的流量規則。
  • egress:定義允許從Pod出去的流量規則。
  • policyTypes:指定網路策略的型別,包括Ingress和Egress。

網路策略的範例

假設有一個三層應用程式,分別是Web層、API層和資料函式庫層,分別標記為tier: "web"tier: "api"tier: "db"。可以建立以下網路策略來限制各層之間的流量:

預設拒絕所有流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress

內容解密:

此網路策略會拒絕所有進入叢集的流量,因為它沒有定義任何允許的規則。透過設定空的podSelector,它會選中名稱空間中的所有Pod。

Web層網路策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: webaccess
spec:
  podSelector:
    matchLabels:
      tier: "web"
  policyTypes:
  - Ingress
  ingress:
  - {}

內容解密:

此網路策略允許所有流量進入標記為tier: "web"的Pod。由於ingress欄位為空物件{},表示允許所有來源的流量。

API層網路策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-access
spec:
  podSelector:
    matchLabels:
      tier: "api"
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          tier: "web"

內容解密:

此網路策略允許來自標記為tier: "web"的Pod的流量進入標記為tier: "api"的Pod。這樣可以確保只有Web層可以存取API層。

資料函式庫層網路策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-db-access
spec:
  podSelector:
    matchLabels:
      tier: "db"
  ingress:
  - from:
    - podSelector:
        matchLabels:
          tier: "api"

內容解密:

此網路策略允許來自標記為tier: "api"的Pod的流量進入標記為tier: "db"的Pod。這樣可以確保只有API層可以存取資料函式庫層。

服務網路最佳實踐

在建立複雜的虛擬網路環境時,需要謹慎規劃和管理不同服務之間的通訊。以下是一些最佳實踐:

  • 限制需要從叢集外部存取的服務數量:盡可能使用ClusterIP,只將外部面對的服務暴露給叢集外部。
  • 使用Ingress API和Ingress控制器:對於HTTP/HTTPS為基礎的服務,使用Ingress API和Ingress控制器來路由流量到後端服務,並提供TLS終止、速率限制、標頭重寫、OAuth驗證等功能。
  • 選擇具有所需功能的Ingress控制器:選擇適合企業需求的Ingress控制器,並在企業內部進行標準化,以確保佈署程式碼的可移植性。
  • 評估雲端服務提供商特定的Ingress控制器選項:考慮使用雲端服務提供商提供的Ingress控制器,以將基礎設施管理和負載從叢集中移除。
  • 使用API特定的Ingress控制器:對於主要提供API的服務,考慮使用Kong或Ambassador等API特定的Ingress控制器,以獲得更精細的API調優。

網路政策最佳實踐與服務網格

網路政策最佳實踐

在企業系統中,網路流量的安全管理曾經是複雜的硬體裝置和網路規則的領域。如今,Kubernetes 網路政策提供了一種更以應用程式為中心的方法,用於分割和控制 Kubernetes 中託管的應用程式流量。無論使用哪種政策外掛程式,以下是一些常見的最佳實踐:

  • 從簡單開始,專注於 Pod 的入口流量。過早地複雜化入口和出口規則可能會使網路追蹤變得困難。當流量按照預期流動時,可以開始查看出口規則,以進一步控制對敏感工作負載的流量。規範也傾向於入口規則,因為即使沒有輸入任何入口規則,許多選項也是預設的。

網路政策範例

若要拒絕所有流量,可以建立以下網路政策:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress

內容解密:

此網路政策預設拒絕所有入口流量。其中:

  • podSelector: {} 表示選擇所有 Pod。
  • policyTypes: [Ingress] 表示此政策適用於入口流量。

若要允許來自特定 Pod 的流量,可以使用以下網路政策:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-api-tier
spec:
  podSelector:
    matchLabels:
      tier: "web"
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          tier: "api"

內容解密:

此網路政策允許來自具有 tier: "api" 標籤的 Pod 的入口流量。其中:

  • podSelector 指定了目標 Pod 的標籤。
  • ingress 部分定義了允許的入口流量來源。

服務網格

服務網格是一種用於管理和保護服務之間通訊的技術。它提供了一種統一的方式來控制服務之間的流量、安全性和可觀察性。服務網格通常包括以下功能:

  • 負載平衡和流量控制
  • 服務發現
  • 可觀察性和追蹤
  • 安全性和身份驗證

服務網格範例

以 Istio 為例,它使用 Envoy 作為其資料平面代理,並提供了豐富的服務網格功能。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: example-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - '*'

內容解密:

此範例定義了一個 Istio Gateway,用於接收外部流量。其中:

  • selector 指定了目標 ingressgateway 的標籤。
  • servers 部分定義了接收流量的組態。

圖表示例

以下是一個簡單的 Plantuml 圖表,用於展示服務網格中的流量流動:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Kubernetes 網路最佳實踐與服務型別解析

package "Kubernetes Cluster" {
    package "Control Plane" {
        component [API Server] as api
        component [Controller Manager] as cm
        component [Scheduler] as sched
        database [etcd] as etcd
    }

    package "Worker Nodes" {
        component [Kubelet] as kubelet
        component [Kube-proxy] as proxy
        package "Pods" {
            component [Container 1] as c1
            component [Container 2] as c2
        }
    }
}

api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2

note right of api
  核心 API 入口
  所有操作經由此處
end note

@enduml

圖表翻譯: 此圖表展示了客戶端如何透過 Ingress Gateway 存取不同的服務。Ingress Gateway 將流量路由到不同的服務,服務之間也可以進行通訊。