Kubernetes 自動擴充套件功能是確保應用程式高用性和資源最佳化的關鍵。透過 VPA,Kubernetes 能夠根據 Pod 的資源使用情況自動調整資源請求和限制,簡化資源管理並提升效率。HPA 則根據負載變化調整 Pod 數量,確保應用程式在高負載下仍能正常運作。而 CA 則負責動態調整叢集節點數量,以滿足整體資源需求,並在負載降低時縮減叢集規模以節省成本。這些機制相互協作,提供完整的自動擴充套件解決方案,提升應用程式彈性和資源利用率。
Kubernetes 自動擴充套件機制:垂直 Pod 自動擴充套件與叢集自動擴充套件
Kubernetes 提供了多種自動擴充套件機制來最佳化資源利用和提高應用程式的彈性,其中包括 垂直 Pod 自動擴充套件(Vertical Pod Autoscaler, VPA) 和 叢集自動擴充套件(Cluster Autoscaler, CA)。這些工具能夠根據實際負載動態調整資源分配,從而提高系統的效率和降低成本。
垂直 Pod 自動擴充套件(VPA)
VPA 能夠根據容器的實際資源使用情況,自動調整 Pod 的資源請求(requests)和限制(limits)。VPA 的主要組成部分包括:
目標參考(Target Reference):指向控制 Pod 的上層資源,如 Deployment 或 StatefulSet。VPA 會從這些資源中取得標籤選擇器,以識別需要管理的 Pod。
更新策略(Update Policy):控制 VPA 如何應用變更。VPA 提供了多種更新模式:
- Off:僅提供資源建議,不應用變更,用於觀察資源使用情況而不幹擾現有 Pod。
- Initial:僅在新建立的 Pod 上應用建議的資源請求,不會重啟現有的 Pod。
- Auto/Recreate:除了在新 Pod 上應用建議外,還會強制重啟現有的 Pod 以應用新的資源組態。
VPA 的運作依賴於其三個主要元件:Recommender、Admission Plugin 和 Updater。Recommender 負責分析 Pod 的資源使用歷史資料,並產生最佳資源組態建議。Admission Plugin 會在新 Pod 建立時修改其資源請求,而 Updater 則負責在需要時重啟 Pod 以應用新的資源組態。
程式碼範例:VPA 組態
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-vpa
spec:
selector:
matchLabels:
app: my-app
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: my-container
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 200m
memory: 256Mi
內容解密:
apiVersion和kind定義了 Kubernetes 資源的版本和型別,這裡使用的是VerticalPodAutoscaler。selector.matchLabels用於指定 VPA 要管理的 Pod,透過標籤app: my-app進行比對。updateMode設定為"Auto",表示 VPA 將自動應用資源建議並重啟 Pod。resourcePolicy.containerPolicies定義了容器資源的最小和最大允許值,確保資源請求不會超出預設範圍。
VPA 的挑戰
雖然 VPA 能夠最佳化資源分配,但它也面臨一些挑戰,例如:
- Pod 重啟:在
Auto或Recreate模式下,VPA 可能會強制重啟 Pod,這可能會導致服務中斷。 - 與 HPA 的協同問題:VPA 和 HPA(水平 Pod 自動擴充套件)可能會同時作用於相同的資源,從而導致不可預期的雙重擴充套件行為。
叢集自動擴充套件(CA)
CA 能夠根據叢集的負載情況,動態地調整節點數量。當叢集需要更多資源時,CA 可以向雲端提供者請求新的節點;當資源使用率降低時,則可以關閉閒置節點以節省成本。
CA 與 HPA 和 VPA 共同工作,提供從 Pod 到節點層級的全面彈性擴充套件能力,從而確保叢集具備足夠的容量來執行工作負載。
Kubernetes 叢集自動擴充套件:Cluster Autoscaler 的原理與實踐
在現代雲端運算環境中,Kubernetes 已成為容器協調的標準工具。然而,要充分利用 Kubernetes 的彈性,叢集自動擴充套件(Cluster Autoscaling)是不可或缺的一環。本文將探討 Cluster Autoscaler(CA)的運作機制、擴充套件策略及其在實際應用中的重要性。
Cluster Autoscaler 簡介
Kubernetes 的 Cluster Autoscaler(CA)是一種自動調整叢集節點數量的機制,旨在根據工作負載的變化動態調整叢集容量。CA 支援多家雲端供應商,包括 AWS、Azure、GCE、IBM Cloud、vSphere 和 OpenStack,使得 Kubernetes 叢集能夠在不同環境中實作自動擴充套件。
CA 的核心是一個在背景執行的機器控制器(machine controller),目前已有多個獨立實作,如 Kubermatic 的 machine-controller 和 Red Hat OpenShift 的 machine-api-operator。這些實作為 CA 提供了強大的節點管理能力,使其能夠根據需求動態調整叢集規模。
Cluster Autoscaler 的運作機制
CA 主要執行兩種操作:新增節點(擴充套件)和移除節點(縮減)。
新增節點(Scale-up)
當應用程式的工作負載增加,需要更多的計算資源時,CA 會檢查是否有 Pod 因資源不足而無法排程。如果 CA 發現新增節點可以滿足這些 Pod 的需求,它將觸發叢集擴充套件,新增節點以容納等待中的 Pod。
在選擇新增節點時,CA 會從現有的節點群組(node group)中選取合適的節點。節點群組中的所有機器應具有相同的容量和標籤,並且執行相同的 Pod,以確保 CA 能夠正確估計新增節點的資源貢獻。
CA 支援多種擴充套件策略(expander),例如:
- least-waste:優先選擇浪費資源最少的節點群組。
- most-pods:選擇能夠容納最多 Pod 的節點群組。
- random:隨機選擇節點群組。
- priority:根據設定的優先順序選擇節點群組。
移除節點(Scale-down)
縮減節點的操作更為複雜,需要進行多項檢查以確保服務不被中斷。CA 會檢查節點是否滿足以下條件:
- 節點的資源利用率低於 50%。
- 節點上的所有可移動 Pod 都可以被重新排程到其他節點。
- 節點上沒有不可移動的 Pod,例如具有本地儲存的 Pod 或由 DaemonSet 管理的 Pod。
- 節點沒有被標記為不可縮減。
如果一個節點在一段時間內(預設為 10 分鐘)持續滿足上述條件,CA 將標記該節點為不可排程,並將其上的 Pod 遷移到其他節點,最終刪除該節點。
Cluster Autoscaler 的優勢
CA 與 Kubernetes 的 Horizontal Pod Autoscaler(HPA)和 Vertical Pod Autoscaler(VPA)相輔相成,共同實作了從 Pod 到叢集層面的自動擴充套件。CA 能夠根據工作負載的變化動態調整叢集容量,確保應用程式的高用性和資源利用率的最佳化。
在面對突發性工作負載(如批次作業、持續整合測試等)時,CA 能夠迅速擴充套件叢集,以滿足臨時性的資源需求,並在負載下降後縮減叢集規模,從而顯著降低雲端基礎設施的成本。
Kubernetes 自動擴充套件技術深度解析
在現代雲原生架構中,Kubernetes 已成為應用程式佈署與管理的首選平台。其強大的自動擴充套件能力,使其能夠根據負載需求動態調整資源,確保應用程式的效能與可靠性。本文將探討 Kubernetes 中的各種自動擴充套件技術,包括應用程式調校、垂直 Pod 自動擴充套件(VPA)、水平 Pod 自動擴充套件(HPA)以及叢集自動擴充套件(CA)。
應用程式調校:最佳化資源利用的基礎
在進行任何自動擴充套件之前,首要步驟是對應用程式進行調校,以確保其能夠有效利用分配的資源。以 Java 應用程式為例,需要調整執行緒池大小以充分利用 CPU 資源,並組態適當的記憶體區域(如堆積、非堆積和執行緒堆積疊大小)。這些調整通常透過組態變更而非程式碼變更來完成。
// Java 應用程式組態範例
public class AppConfig {
public static void main(String[] args) {
// 調整執行緒池大小
int threadPoolSize = Runtime.getRuntime().availableProcessors() * 2;
// 組態記憶體引數
long heapSize = Runtime.getRuntime().maxMemory() * 0.8;
}
}
內容解密:
Runtime.getRuntime().availableProcessors()用於取得可用的 CPU 核心數。- 執行緒池大小設為 CPU 核心數的兩倍,以充分利用 CPU 資源。
Runtime.getRuntime().maxMemory()用於取得容器可用的最大記憶體,並設定堆積大小為其 80%。
此外,容器原生應用程式可以使用啟動指令碼根據分配的容器資源動態計算預設值。Netflix 的 Adaptive Concurrency Limits 函式庫等技術允許應用程式透過自我剖析和調整來動態計算並發限制,實作應用程式內部的自動擴充套件。
垂直 Pod 自動擴充套件(VPA)
VPA 能夠根據實際資源使用情況自動調整 Pod 的資源請求和限制。雖然 VPA 仍處於實驗階段,但它能夠顯著簡化資源組態過程。然而,VPA 需要重新建立 Pod,這可能導致短暫的服務中斷。
# VPA 組態範例
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-vpa
spec:
selector:
matchLabels:
app: my-app
updateMode: Auto
內容解密:
selector.matchLabels用於指定 VPA 所需管理的 Pod。updateMode: Auto表示 VPA 將自動調整 Pod 的資源請求和限制。
水平 Pod 自動擴充套件(HPA)
HPA 透過增加或減少 Pod 的數量來實作水平擴充套件,而不改變 Pod 的規格。HPA 目前支援根據 CPU 和記憶體指標的擴充套件,並可透過自定義指標實作更複雜的擴充套件邏輯。
# HPA 組態範例
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: my-hpa
spec:
selector:
matchLabels:
app: my-app
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
內容解密:
selector.matchLabels指定 HPA 所需管理的 Pod。minReplicas和maxReplicas定義了 Pod 的最小和最大數量。metrics部分定義了擴充套件指標,此處為 CPU 使用率達到 50% 時進行擴充套件。
叢集自動擴充套件(CA)
CA 能夠根據叢集內的資源需求動態調整節點數量。當 HPA 或 VPA 需要更多的資源時,CA 可以擴充套件叢集以提供所需的容量。反之,當資源利用率較低時,CA 可以縮減叢集以節省資源。
# CA 組態範例(部分)
apiVersion: autoscaling/v1
kind: ClusterAutoscaler
metadata:
name: default
spec:
minReplicas: 1
maxReplicas: 10
內容解密:
minReplicas和maxReplicas定義了叢集節點的最小和最大數量。- CA 將根據實際需求在這個範圍內調整節點數量。
容器映像建構器模式
Kubernetes 是一個通用容器協調引擎,不僅適合執行應用程式,也可用於建構容器映像。映像建構器模式解釋了為何在叢集中建構容器映像是有意義的,以及目前有哪些技術可用於在 Kubernetes 中建立映像。
問題描述
到目前為止,本文中的所有模式都與在 Kubernetes 上操作應用程式有關。您已經瞭解如何開發和準備應用程式,使其成為良好的雲原生公民。但是,如何建構應用程式本身呢?傳統方法是將容器映像建構於叢集之外,將其推播到登入檔中,並在 Kubernetes Deployment 描述符中參照它們。然而,在叢集中建構具有多個優勢。
如果公司政策允許,只使用一個叢集進行所有操作是有優勢的。在一個地方建構和執行應用程式可以大大降低維護成本。它還簡化了容量規劃並減少了平台資源開銷。
通常,像 Jenkins 這樣的持續整合(CI)系統用於建構映像。使用 CI 系統建構是一個排程問題,為了有效地找到可用的計算資源來執行建構作業。Kubernetes 的核心是一個高度複雜的排程器,非常適合這類別排程挑戰。
一旦我們轉向持續交付(CD),從建構映像轉向執行容器,如果建構發生在同一個叢集中,兩個階段分享相同的基礎架構,並且可以簡化轉換。例如,假設在用於所有應用程式的基礎映像中發現了一個新的安全漏洞。一旦您的團隊修復了這個問題,您就必須重建依賴於此基礎映像的所有應用程式映像,並使用新的映像更新正在執行的應用程式。
在實作此映像建構器模式時,叢集同時知道映像的建構和佈署,並且可以在基礎映像變更時自動重新佈署。在「OpenShift Build」中,我們將看到 OpenShift 如何實作這種自動化。
解決方案
截至 2023 年,存在一系列用於在叢集中建構容器映像的技術。雖然所有這些技術都旨在建構映像,但每種工具都有其獨特之處,使其適用於特定的情況。
圖 30-1 包含了截至 2023 年在 Kubernetes 叢集中建構容器映像的主要技術。
本章節將簡要概述大多數這些技術。您可以透過「更多資訊」中的連結找到有關這些工具的更多詳細資訊。請注意,雖然這裡描述的許多工具已經成熟並在生產專案中使用,但無法保證當您閱讀這些內容時,這些專案仍然存在。在使用其中一個工具之前,您應該檢查該專案是否仍然活躍並得到支援。
容器映像建構器
這些工具在叢集中建立容器映像。這些工具之間存在一些重疊,它們各有不同,但都可以無需特權存取即可執行。您也可以在叢集外作為 CLI 程式執行這些工具。這些建構器的唯一目的是建立容器映像,但它們不關心應用程式的重新佈署。
建構協調
這些工具在更高的抽象層級上運作,最終觸發容器映像建構器來建立映像。它們還支援與建構相關的任務,例如在映像建立後更新佈署描述符。CI/CD 系統(如前所述)是協調器的典型範例。
無根建構
在 Kubernetes 中進行建構時,叢集對建構過程具有完全控制權。因此,叢集需要更高的安全標準,以防止潛在的漏洞。提高建構過程安全性的其中一種方法是無需 root 許可權即可執行建構,這種做法稱為無根建構。在 Kubernetes 中有多種方法可以實作無根建構,讓您可以在沒有提升許可權的情況下進行建構。
Docker 藉著其無與倫比的使用者經驗,將容器技術帶給了大眾。Docker 根據客戶端-伺服器架構,其背景中有一個 daemon 執行,並透過 REST API 從客戶端接收指令。此 daemon 需要 root 許可權,主要用於網路和磁碟區管理。不幸的是,這帶來了安全風險,因為不受信任的程式可以逃脫其容器,入侵者可以控制整個主機。此問題不僅適用於執行容器,也適用於建構容器映像,因為建構也在容器中進行,當 Docker daemon 執行任意命令時。
本章節中描述的大多數叢集內建構技術都允許在非特權模式下建立容器映像,以減少攻擊面,這對於鎖定的 Kubernetes 叢集非常有用。
根據 Dockerfile 的建構器
以下建構器根據眾所周知的 Dockerfile 格式來定義建構指令。它們在 Dockerfile 級別上相容,並且要麼完全不與背景 daemon 通訊,要麼透過 REST API 與以非特權模式執行的建構程式進行遠端通訊:
- Buildah 和 Podman
Dockerfile-Based builders 程式碼範例
# 使用官方 Python 基礎映像
FROM python:3.9-slim
# 設定工作目錄
WORKDIR /app
# 複製 requirements.txt
COPY requirements.txt .
# 安裝依賴項
RUN pip install --no-cache-dir -r requirements.txt
# 複製應用程式碼
COPY . .
# 暴露埠號
EXPOSE 80
# 執行應用程式
CMD ["python", "app.py"]
內容解密:
FROM python:3.9-slim:使用官方 Python 3.9 的 slim 版本作為基礎映像,slim 版本較小且適合生產環境。WORKDIR /app:設定容器內的工作目錄為/app。COPY requirements.txt .:將主機上的requirements.txt複製到容器內的工作目錄,用於安裝 Python 依賴項。RUN pip install --no-cache-dir -r requirements.txt:安裝requirements.txt中指定的 Python 套件,--no-cache-dir用於避免快取套件。COPY . .:將主機上的當前目錄(即應用程式碼)複製到容器內的工作目錄。EXPOSE 80:宣告容器將監聽的埠號為 80,通常用於 Web 服務。CMD ["python", "app.py"]:指定容器啟動時執行的預設命令,即使用 Python 執行app.py指令碼。
此 Dockerfile 定義了一個簡單的 Python 應用程式容器化流程,從依賴安裝到應用程式執行皆有涵蓋。