Kubernetes 提供了 Ingress 資源和 Ingress Controller 來管理叢集內外的流量路由。本文詳細介紹了 Ingress 的 YAML 設定、Nginx Ingress Controller 的佈署方式,以及 IngressClass 的使用場景。透過 Ingress,可以根據不同的 URL 路徑將流量導向不同的服務,實作外部流量的有效管理。Nginx Ingress Controller 作為常用的 Ingress Controller,提供了豐富的功能和靈活性。文章也涵蓋了在雲端環境和 Minikube 中佈署 Nginx Ingress Controller 的方法,並說明瞭 IngressClass 如何實作更精細的流量控制和多 Ingress Controller 的管理。最後,文章也提到了多叢集策略和 Kubernetes 生態系統的發展趨勢,例如 KubeVirt、Knative 和 OpenFaaS 等。
Kubernetes 高階流量管理、多叢集策略與進階技術
在 Kubernetes 的進階應用中,流量管理、多叢集策略以及其他相關技術是至關重要的。本章將探討 Kubernetes 的進階主題,包括使用 Ingress 資源進行複雜的流量路由、Kubernetes 的故障排除、安全性強化以及最佳實踐。
使用 Ingress 進行高階流量路由
Ingress 是 Kubernetes 中的一個重要資源,用於將外部請求路由到叢集內的服務。它作為反向代理,根據 Ingress 組態中的規則,將請求轉發到相應的服務。
Kubernetes 服務回顧
在深入瞭解 Ingress 之前,我們先回顧一下 Kubernetes 中的不同型別的服務:
- ClusterIP:透過 kube-proxy 在每個節點上管理的虛擬 IP 地址暴露 Pod,只能在叢集記憶體取。
- NodePort:透過任意節點的 IP 地址和指定埠(預設範圍是 30000-32767)存取,kube-proxy 將請求轉發到對應的 ClusterIP 服務。
- LoadBalancer:通常用於雲環境,透過組態外部負載平衡器將流量路由到叢集內的服務。
Ingress 物件概述
Ingress 物件用於實作第 7 層(L7)負載平衡,解決了 LoadBalancer 服務的一些限制,例如無法處理 HTTPS 流量、無法進行根據路徑的路由等。Ingress 物件定義了路由和負載平衡規則,例如將特定路徑的請求路由到特定的 Kubernetes 服務。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /service1
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
- path: /service2
pathType: Prefix
backend:
service:
name: service2
port:
number: 80
Ingress 設定詳解
上述 Ingress 設定定義了一個規則,將 example.com 的請求根據路徑轉發到不同的服務。/service1 路徑的請求被轉發到 service1 服務的 80 埠,而 /service2 路徑的請求被轉發到 service2 服務的 80 埠。
內容解密:
apiVersion和kind定義了資源的 API 版本和型別。metadata部分包含了資源的中繼資料,如名稱。spec部分定義了 Ingress 的具體設定,包括規則(rules)。rules部分定義了根據主機名(host)的路由規則。http.paths部分定義了根據路徑的路由規則,將特定路徑的請求轉發到後端服務。
閘道器 API
閘道器 API 是 Kubernetes 中的一個新興專案,用於簡化服務網格和流量管理的組態。它提供了更靈活和可擴充套件的方式來管理入口流量。
Kubernetes 的現代進展
Kubernetes 生態系統不斷進化,出現了許多新的專案和技術,例如 KubeVirt(用於虛擬化)、Knative 和 OpenFaaS(用於無伺服器計算)。
維護 Kubernetes 叢集:第二天任務
維護 Kubernetes 叢集涉及多個方面,包括監控、升級、日誌記錄和故障排除。
保護 Kubernetes 叢集:最佳實踐
保護 Kubernetes 叢集需要採取多層次的安全措施,包括網路策略、身份驗證和授權、以及定期更新和修補。
Kubernetes 故障排除
故障排除是 Kubernetes 管理中的一個重要方面,涉及日誌分析、監控和除錯工具的使用。
本章涵蓋了 Kubernetes 的多個進階主題,從流量管理和多叢集策略到安全性和故障排除。這些技術對於構建和管理現代化、可擴充套件和高可用性的應用程式至關重要。
Kubernetes 進階流量管理、多叢集策略等
Ingress 設定範例與運作原理
首先,我們來看看一個用於 Ingress 的 YAML 清單檔案範例,ingress/portal-ingress.yaml:
# ingress/portal-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: portal-ingress
namespace: ingress-demo
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: k8sbible.local
http:
paths:
- path: /video
pathType: Prefix
backend:
service:
name: video-service
port:
number: 8080
- path: /shopping
pathType: Prefix
backend:
service:
name: shopping-service
port:
number: 8080
內容解密:
此 YAML 檔案定義了一個名為 portal-ingress 的 Ingress 物件,屬於 ingress-demo 名稱空間。主要功能是根據不同的 URL 路徑,將請求路由到不同的後端服務。
metadata.annotations中的nginx.ingress.kubernetes.io/rewrite-target: /表示將請求的路徑重寫為根路徑/。spec.rules定義了路由規則。在這個例子中,所有到達k8sbible.local的請求將根據路徑進行分流。- 請求路徑以
/video開頭的將被路由到video-service服務的 8080 連線埠。 - 請求路徑以
/shopping開頭的將被路由到shopping-service服務的 8080 連線埠。
- 請求路徑以
以下圖表展示了 Ingress Controller 的運作方式:
@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 Controller 被路由到不同的後端服務。
Ingress HTTP 路由規則解析
Ingress 的路由規則包含以下主要部分:
- 可選的主機名稱(host):如果指定了主機名稱,則該規則僅適用於目標主機的請求。在這個例子中,我們沒有指定主機名稱,因此規則適用於所有進入的流量。
- 路徑路由列表:每個路徑都有一個相關聯的 Ingress 後端服務,透過提供
serviceName和servicePort來定義。例如,所有到達/video路徑的請求將被路由到video-service後端的 Pods。
使用 nginx 作為 Ingress Controller
Ingress Controller 是一個 Kubernetes 控制管理器,通常以 DaemonSet 或 Deployment 物件的形式佈署,用於處理進入叢集的流量負載平衡和智慧路由。nginx 是其中一個常用的 Ingress Controller,被稱為 Nginx Ingress Controller。
Nginx Ingress Controller 的安裝方式在不同環境下有所不同,官方檔案提供了詳細的安裝:https://kubernetes.github.io/ingress-nginx/deploy/。
在雲環境中,安裝通常非常簡單,可以透過應用一個 YAML 清單檔案來完成。例如,在 AKS 或 GKE 中,可以使用一條命令來佈署所需的 Ingress Controller 元件。
使用 Nginx Ingress Controller 的好處
- 能夠組態複雜的路由規則,涉及多個叢集內的服務,但對外卻呈現為單一端點的多路徑可用。
- 支援多種匹配模式,包括字首匹配和精確匹配。
- 能夠與雲供應商的負載平衡器整合,直接與 Pods 進行通訊,無需額外的 Pod 開銷。
在Kubernetes中佈署NGINX Ingress Controller
在Kubernetes環境中,Ingress Controller是用於管理進入叢集的HTTP和HTTPS流量的關鍵元件。NGINX Ingress Controller是一種流行的選擇,它提供了豐富的功能和靈活性。本章節將介紹如何在不同的Kubernetes環境中佈署NGINX Ingress Controller,包括雲端環境和minikube本地叢集。
在雲端Kubernetes叢集中佈署NGINX Ingress Controller
要在雲端Kubernetes叢集中佈署NGINX Ingress Controller,可以使用預先組態的YAML檔案。這些檔案包含了佈署Ingress Controller所需的所有資源,包括Roles、RoleBindings、Namespace、ConfigMap等。
對於AWS環境,可以使用以下命令來佈署:
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml
這將建立一個Network Load Balancer(NLB)並將其與Ingress Controller的Service(型別為LoadBalancer)相關聯。
對於其他雲端提供商,例如GKE,需要根據具體的檔案進行相應的組態。
內容解密:
此步驟涉及使用kubectl apply命令來應用來自GitHub倉函式庫的YAML組態檔案。這些組態檔案定義了Ingress Controller所需的各種Kubernetes資源。NLB的建立是為了將外部流量匯入叢集中的Ingress Controller。
在minikube中佈署NGINX Ingress Controller
要在minikube中啟用Ingress功能,可以使用以下命令:
$ minikube start --cni calico --nodes 3 --kubernetes-version=v1.31.0
$ minikube addons enable ingress
第一條命令啟動了一個包含3個節點的minikube叢集,並指定了Kubernetes版本。第二條命令啟用了Ingress外掛。
內容解密:
minikube start命令用於建立一個本地的Kubernetes叢集。--cni calico選項指定了使用的CNI外掛,而--nodes 3則指定了叢集中的節點數量。minikube addons enable ingress命令則啟用了Ingress功能,使得叢集能夠支援Ingress資源。
佈署Ingress資源
一旦Ingress Controller佈署完成,就可以建立Ingress資源來定義如何路由進入叢集的流量。以下是一個示例YAML檔案(portal-ingress.yaml),它定義了根據路徑路由流量到不同的Service:
spec:
rules:
- host: k8sbible.local
http:
paths:
- path: /video
pathType: Prefix
backend:
service:
name: video-service
port:
number: 8080
- path: /shopping
pathType: Prefix
backend:
service:
name: shopping-service
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: blog-service
port:
number: 8080
這個組態定義了根據存取的路徑(/video、/shopping或根路徑/)將流量路由到不同的Service(video-service、shopping-service或blog-service)。
內容解密:
此YAML檔案定義了一個Ingress資源,它根據HTTP請求的主機名和路徑進行流量路由。對於主機名k8sbible.local,根據不同的路徑,將流量轉發到後端的不同Service。每個Service都執行在埠8080上。
驗證Ingress功能
佈署完成後,可以透過存取組態的網域名稱(例如http://k8sbible.local/video、http://k8sbible.local/shopping或http://k8sbible.local/)來驗證Ingress是否正確地路由了流量。在本地測試時,可能需要修改/etc/hosts檔案來解析網域名稱到minikube叢集的IP。
內容解密:
透過存取不同的路徑,可以驗證Ingress Controller是否按照預期將流量路由到了正確的Service。這種根據路徑的路由使得多個應用可以共用同一個外部IP或網域名稱,提高了靈活性和可管理性。
IngressClass 與多重 Ingress 控制器
在某些情況下,我們可能需要對 Ingress 控制器進行不同的組態。使用單一 Ingress 控制器可能無法實作自定義組態,因為自定義組態可能會影響 Kubernetes 叢集中的其他 Ingress 物件。在這種情況下,您可以透過使用 ingressClass 機制,在單一 Kubernetes 叢集內佈署多個 Ingress 控制器。以下是一些可能的場景:
- 不同類別的 Ingress 對應不同的需求:Kubernetes Ingress 控制器可以使用特定的 Ingress 類別進行註解,例如
nginx-public和nginx-private。這有助於引導不同型別的流量;例如,公共流量可以由效能最佳化的控制器提供,而內部服務則保持在更嚴格的存取控制後面。 - 多協定支援:不同的應用程式需要支援多種協定,包括 HTTP/HTTPS 和 TCP/UDP。這可以透過為每個協定使用不同的 Ingress 控制器來實作。這樣,具有不同協定需求的應用程式將在同一 Kubernetes 叢集中得到支援,而無需依賴單一的 Ingress 控制器。這樣不僅提高了效能,還降低了組態的複雜性。
需要注意的是,您的 ingressClass 資源的 .metadata.name 很重要,因為在指定 Ingress 物件的 ingressClassName 欄位時需要用到這個名稱。這個 ingressClassName 欄位取代了舊的方法,即使用註解將 Ingress 連結到特定的控制器,如 IngressSpec v1 檔案所述。
如果您在建立 Ingress 時未指定 IngressClass,且您的叢集恰好有一個標記為預設的 IngressClass,Kubernetes 將自動將該預設 IngressClass 套用到 Ingress。要將 IngressClass 標記為預設,您應該在該 IngressClass 上設定 ingressclass.kubernetes.io/is-default-class 註解,其值為 true。雖然這是預期的規格,但需要注意的是,不同的 Ingress 控制器可能對這些功能的實作有細微的差異。
apiVersion: v1
items:
- apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
在上述程式碼片段中,可以看到以下內容:
ingressClass名稱為nginx(.metadata.name)- 您可以看到
ingressclass.kubernetes.io/is-default-class: "true"
內容解密:
此 YAML 程式碼是用來描述一個名為 nginx 的 IngressClass 資源。其中,metadata.name 指定了 IngressClass 的名稱,而 ingressclass.kubernetes.io/is-default-class 註解則用於將此 IngressClass 設定為預設。當建立新的 Ingress 物件而未指定 ingressClassName 時,Kubernetes 將自動使用此預設的 IngressClass。此外,spec.controller 指定了處理此類別 Ingress 的控制器。