在 AKS 環境中,有效管理流量和確保叢集穩定性至關重要。本文將探討如何使用 AGIC 簡化負載平衡,並透過直接與 Pod 通訊提升效能。同時,我們也將介紹 Kubernetes Gateway API,它提供更具表達力和擴充性的流量路由管理方式。此外,EndpointSlices 的應用將改善叢集的可擴充套件性。最後,我們將探討 etcd 的備份與還原策略,以保障叢集資料安全和業務連續性,並討論如何在雲端環境中有效運用這些策略。

Azure Application Gateway Ingress Controller for AKS

正如前一節所詳細討論的,使用 nginx Ingress Controller 是 Kubernetes 叢集中流量路由的一種相當靈活的方法。雖然這種方法通常運作良好,但當轉向使用雲端提供商(如 Azure Kubernetes Service (AKS))時,由於多層負載平衡,可能會變得有些複雜。這些層可能會引入不必要的複雜性並增加故障點。

為瞭解決這些問題,AKS 提供了一個名為 Azure Application Gateway Ingress Controller (AGIC) 的原生 L7 負載平衡服務。AGIC 與 Azure 的網路服務協同工作,以支援更有效率和可靠的流量路由,實作透過私有 IP 位址與 Pod 直接通訊。這種功能是透過一些 Azure SDN 功能(如 VNet Peering)實作的。

為什麼選擇 AGIC for AKS?

選擇 AGIC for AKS 的原因如下:

  • 簡化的負載平衡:AGIC 消除了使用單獨的 Azure Load Balancer 的需要,該負載平衡器會將請求代理到 nginx Ingress Controller Pod,使用 NodePorts。相反,它直接將流量轉發到 Pod。這減少了負載平衡所涉及的層數,並最小化了故障點的可能性。
  • 直接與 Pod 通訊:AGIC 利用 Azure SDN 功能,實作與 Pod 的直接通訊,而無需 kube-proxy 管理服務的路由。
az aks create --resource-group myResourceGroup --name myAKSCluster --node-count 2 --network-plugin azure --enable-managed-identity -a ingress-appgw --appgw-name MyAppGateway --appgw-subnet-cidr "10.2.0.0/16" --generate-ssh-keys

內容解密:

此命令用於在 Azure 上建立一個新的 AKS 叢集,並啟用 Azure Application Gateway Ingress Controller (AGIC)。其中,--resource-group 指定了資源群組名稱,--name 指定了 AKS 叢集名稱,--node-count 指定了叢集中的節點數量。--enable-managed-identity 啟用了受控身分識別,而 -a ingress-appgw 則啟用了 AGIC。--appgw-name 指定了 Application Gateway 的名稱,--appgw-subnet-cidr 指定了 Application Gateway 所使用的子網路 CIDR。

AGIC 的高階設計

AGIC 的高階設計如下圖所示:

圖示說明:

此圖示展示了 AGIC 在 AKS 中的工作流程。外部流量首先進入 Application Gateway,然後由 AGIC 路由到後端的 Pod。這種設計簡化了流量管理和負載平衡,提高了系統的可靠性和效率。

Kubernetes 進階流量管理與多叢集策略

設定 Azure Kubernetes Service (AKS) 與 Application Gateway Ingress Controller (AGIC)

在完成叢集佈署後,我們需要產生 kubeconfig 以便與 kubectl 搭配使用。執行以下命令(它會切換到新的上下文,因此稍後仍可使用舊的上下文):

$ az aks get-credentials --resource-group k8sforbeginners-rg --name k8sforbeginners-aks-agic
Merged "k8sforbeginners-aks-agic" as current context in .kube/config

現在,我們可以使用與 ingress 目錄中相同的 YAML 資源清單來佈署 Deployments 和 Services(在 Book 儲存函式庫中,與前一節相同)。但我們需要在 YAML 中對 AGIC 進行一些更改;為了更清楚起見,我們將 ingress 目錄的內容複製到 aks_agic 目錄並在那裡進行修改。修改 Ingress 資源定義如下:

# aks-agic/portal-ingress.yaml
...
spec:
  ingressClassName: azure-application-gateway
...

內容解密:

  • ingressClassName 指定了用於此 Ingress 資源的 Ingress Controller。在此例中,我們使用的是 azure-application-gateway,它對應到 AGIC。

我們還將名稱空間重新命名為 agic-demo 以隔離測試。按照以下方式從 aks_agic 目錄套用 YAML 定義:

$ kubectl apply -f aks_agic/

等待幾分鐘,讓 Application Gateway 更新其組態。若要檢索 Ingress 的外部 IP 地址,請執行以下命令:

$ kubectl get ingress
NAME              CLASS    HOSTS   ADDRESS         PORTS   AGE
example-ingress   <none>   *       52.191.222.39   80      36m

內容解密:

  • kubectl get ingress 用於取得叢集中 Ingress 資源的資訊。
  • 在此例中,外部 IP 地址是 52.191.222.39

透過導航到使用檢索到的 IP 地址的 /video/shopping 路徑來測試組態:

  • 服務 1:http://<external-IP>/video 將由 video-service Pods 提供服務。
  • 服務 2:http://<external-IP>/shopping 將由 shopping-service Pods 提供服務。
  • 預設服務:http://<external-IP>/ 將由 blog-service Pods 提供服務。

Gateway API 簡介

Kubernetes Gateway API 是一組不斷演進的資源,提供了一種更具表達性和擴充套件性的方式來定義叢集中的網路流量路由。

Gateway API 的主要資源

  1. GatewayClass:代表一組分享通用組態並由同一控制器操作的 Gateways。
  2. Gateway:代表一個環境例項,其中流量透過控制器進行控制,例如雲端負載平衡器。
  3. HTTPRoute:定義從 Gateway 監聽器到後端網路端點(通常表示為 Services)的 HTTP 特定路由規則。

以下圖表顯示了 Gateway API 資源的高階流程: 此圖示展示了 Gateway API 的資源模型。

相較於 Ingress API,Gateway API 的主要優勢包括對複雜路由場景(如多層次、跨名稱空間路由)的靈活性。此外,其設計強調可擴充套件性,第三方開發者可以編寫自己的 Gateway 控制器,與 Kubernetes 無縫互動。此外,Gateway API 允許對路由規則、流量策略和負載平衡管理任務進行更細粒度的控制。

範例組態

一個典型的 GatewayClass 定義如下:

# gateway_api/gatewayclass.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: dev-cluster-gateway
spec:
  controllerName: "example.net/gateway-controller"

內容解密:

  • GatewayClass 定義了一個 Gateways 的類別,由特定的控制器管理。

一個典型的 Gateway 資源指向 dev-cluster-gateway 作為 gatewayClassName

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: dev-gateway
  namespace: gateway-api-demo
spec:
  gatewayClassName: dev-cluster-gateway
  listeners:
  - name: http
    protocol: HTTP
    port: 80

內容解密:

  • Gateway 定義了一個具體的流量控制例項,指定了使用的 GatewayClass 和監聽器組態。

最後,我們有 HTTPRoute(類別似於 Ingress),其規則指向不同的服務:

# gateway-api/httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: dev-httproute
  namespace: gateway-api-demo
spec:
  parentRefs:
  - name: dev-cluster-gateway
    kind: Gateway
    namespace: gateway-api-demo
  hostnames:
  - "k8sbible.local"
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /video
    backendRefs:
    - name: video-service
      port: 80

內容解密:

  • HTTPRoute 定義了從 Gateway 到後端服務的 HTTP 路由規則。
  • 此例中,任何到 /video 路徑的請求都將被路由到 video-service 的 80 埠。

Kubernetes 高階技術:流量管理、多叢集策略等

深入理解 Endpoints 與 EndpointSlices

傳統上,Kubernetes 透過 Pod 來管理應用的佈署,而 Service 物件則作為可靠的網路中介。Service 物件扮演著進入 Pod 的門戶角色,並維護一個對應的 Endpoints 物件,該物件列出了與 Service 選擇器條件相匹配的活躍且健康的 Pod。然而,當規模擴大時,這種做法就無法滿足需求。

假設一個 Service 代表多個 Pod,對應的 Endpoints 物件會攜帶每個 Pod 的 IP 和埠,這些資訊會在叢集中傳播並用於網路組態。每次更新這個物件都會影響整個叢集的所有節點,即使是微小的變更也會導致大量的網路流量和節點處理負擔。

為瞭解決這個挑戰,EndpointSlices 將龐大的 Endpoints 物件切割成較小的片段。預設情況下,每個 EndpointSlice 可容納 100 個端點,代表 Pod 的網路細節。透過 EndpointSlices,更新操作變得更加精確。不是重新下載整個 Endpoints 物件,而只會更新包含特定 Pod 的那個片段。這樣減少了網路流量和節點工作負載,最重要的是,它提高了可擴充套件性和效能,這在 Kubernetes 的發展中被視為一個令人振奮的前景。

更多關於 EndpointSlices 的資訊,請參考官方檔案(https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/)。

Kubernetes 的現代進展

Kubernetes 站在整合和支援一系列先進技術的前沿,這些技術正在重塑 IT 環境。因此,Kubernetes 提供了一個靈活且可擴充套件的平台,可以輕鬆整合現代和前沿的解決方案,例如用於無伺服器運算的 Knative、用於函式即服務的 OpenFaas、用於虛擬機器管理的 KubeVirt,以及用於機器學習工作流程的 Kubeflow。這些解決方案擴充套件了 Kubernetes 的功能,進而幫助組織以更高的效率和速度創新並採用新的正規化。

在本章中,我們將探討兩個最強大的框架:Knative 和 OpenFaaS,以及它們的主要使用案例。

使用 Knative 和 OpenFaaS 實作無伺服器架構

無伺服器運算正在改變應用程式的構建和佈署方式,使開發者能夠專注於編寫程式碼,而基礎設施管理則交由自動化平台負責。在 Kubernetes 環境中使用 Knative 和 OpenFaaS,可以實作嚴謹的無伺服器功能佈署、擴充套件和管理。

Knative:無伺服器運算的強大工具

Knative 是一個根據 Kubernetes 的平台,它抽象出了管理容器化應用程式的大部分底層複雜性。它提供了諸如自動擴充套件、流量管理和事件驅動函式執行等任務的自動化。此外,這使得 Knative 在需要處理可變工作負載或事件驅動任務的應用程式中非常有效。你可以使用 Knative 在峰值時期擴充套件微服務,處理像使用者上傳處理這樣的後台作業,或者構建超回應的事件驅動系統。

OpenFaaS:佈署函式的靈活框架

另一個靈活的框架是 OpenFaaS,它在 Kubernetes 上佈署函式時提供了很大的便利。OpenFaaS 允許在容器中佈署輕量級、無伺服器的函式,以確保易於擴充套件和管理。在微服務架構中,這將非常有用,因為你可以根據需求單獨擴充套件每個函式。OpenFaaS 非常適合涉及實時資料處理、由事件觸發的函式,或者構建 API 以調整影像大小或轉換資料,而無需整個應用程式堆積疊的開銷。在 OpenFaaS 上使用 Knative,可以讓組織更好地利用 Kubernetes,以減少複雜性並擴展出更高效的應用程式。

Kubeflow:在 Kubernetes 上實作機器學習

Kubeflow(https://www.kubeflow.org)是一個開源平台,能夠在 Kubernetes 上輕鬆、平滑地佈署、擴充套件和管理機器學習工作流程。它將各種工具和框架整合到一個系統中,使資料科學家和開發者能夠專注於建立和實驗機器學習模型,而無需擔心管理基礎設施。

Kubeflow 可以自動化整個機器學習週期,從資料準備到模型訓練,再到佈署和監控。它與大多數流行的機器學習框架(如 TensorFlow、PyTorch 和 XGBoost)相容,因此這些工具應該能夠無縫地整合到你的當前工作流程中。在 Kubernetes 上執行,Kubeflow 從 Kubernetes 層獲得了其可擴充套件性和彈性,這意味著你的機器學習工作負載在需要時能夠擴充套件,並自動從故障中還原。

特別是,Kubeflow 是管理大型機器學習專案的有效解決方案,在這些專案中,需要在分散式資料集上進行模型訓練,將模型佈署到生產環境,或者使用新資料重複訓練模型。這反過來意味著實作了一個真正強大和靈活的平台,加速了在 Kubernetes 上開發和佈署機器學習應用程式。

KubeVirt:在 Kubernetes 上管理虛擬機器

KubeVirt(https://kubevirt.io)是一個開源專案,它透過管理虛擬機器(VM)來擴充套件 Kubernetes,除了容器化工作負載之外。這種整合讓組織能夠在 Kubernetes 叢集中執行虛擬機器,使得傳統的使用虛擬機器的應用程式能夠與現代化的容器化應用程式平行佈署在同一個受管理的平台上。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title AKS 高階流量管理與叢集維護策略

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

此圖示說明瞭 Kubernetes 與各種先進技術之間的整合關係,包括 Knative、OpenFaaS、Kubeflow 和 KubeVirt,以及它們各自的功能領域。

Kubernetes叢集維護:備份與還原策略

在Kubernetes的實際應用中,維護叢集的穩定性和資料完整性是至關重要的。隨著Kubernetes在生產環境中的廣泛使用,諸如備份、升級和多叢集管理等日常維護任務(Day 2 Tasks)變得越來越重要。本篇文章將探討Kubernetes叢集的備份與還原機制,特別是針對etcd這個儲存叢集狀態的關鍵元件。

為什麼etcd備份至關重要

etcd是Kubernetes的核心元件之一,它儲存了叢集的所有組態和狀態資訊。因此,定期備份etcd是確保叢集資料完整性和業務連續性的關鍵。在發生災難或控制平面節點故障時,etcd備份可以幫助還原叢集到正常狀態。

使用etcdctl進行備份

etcdctl是官方提供的工具,可以用於對etcd進行快照備份。以下命令展示瞭如何使用etcdctl建立一個快照:

$ ETCDCTL_API=3 etcdctl \
--endpoints=[https://127.0.0.1:2379] \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /tmp/snapshot-pre-patch.db

內容解密:

  1. ETCDCTL_API=3:指定使用etcd的v3 API進行操作。
  2. --endpoints:指定etcd服務的連線端點。
  3. --cacert, --cert, --key:提供用於TLS連線的CA憑證、客戶端憑證和私鑰。
  4. snapshot save:將etcd的當前狀態儲存到指設定檔案。

備份完成後,可以使用etcdutl工具驗證快照的完整性:

$ etcdutl --write-out=table snapshot status snapshot.db

內容解密:

  1. --write-out=table:以表格形式輸出快照狀態資訊。
  2. snapshot status:檢查指定快照檔案的狀態,包括雜湊值、修訂版本、鍵值數量和快照大小。

在雲端環境中進行備份

對於使用雲端Kubernetes服務(如GKE、EKS、AKS)的使用者,這些平台通常提供自動備份和還原工具。例如,可以使用AWS Backup或Azure Backup來定期備份叢集狀態,而無需手動干預。

etcd快照還原

從快照還原etcd是一個複雜且關鍵的操作,尤其是在多節點叢集中,需要確保所有節點的一致性。在還原之前,必須停止所有API伺服器例項,以防止資料不一致。還原完成後,需要重新啟動API伺服器和其他關鍵元件。

使用etcdutl進行還原的命令如下:

$ etcdutl --data-dir <data-dir-location> snapshot restore snapshot.db

內容解密:

  1. --data-dir:指定還原後資料存放的目錄。
  2. snapshot restore:從指定的快照檔案還原etcd資料。