新聞中心
Pod 水平自動擴縮
在 Kubernetes 中,HorizontalPodAutoscaler 自動更新工作負載資源 (例如 Deployment 或者 StatefulSet), 目的是自動擴縮工作負載以滿足需求。

成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設、高性價比克州網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式克州網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設找我們,業(yè)務覆蓋克州地區(qū)。費用合理售后完善,10多年實體公司更值得信賴。
水平擴縮意味著對增加的負載的響應是部署更多的 Pods。 這與 “垂直(Vertical)” 擴縮不同,對于 Kubernetes, 垂直擴縮意味著將更多資源(例如:內(nèi)存或 CPU)分配給已經(jīng)為工作負載運行的 Pod。
如果負載減少,并且 Pod 的數(shù)量高于配置的最小值, HorizontalPodAutoscaler 會指示工作負載資源( Deployment、StatefulSet 或其他類似資源)縮減。
水平 Pod 自動擴縮不適用于無法擴縮的對象(例如:DaemonSet。)
HorizontalPodAutoscaler 被實現(xiàn)為 Kubernetes API 資源和控制器。
資源決定了控制器的行為。在 Kubernetes 控制平面內(nèi)運行的水平 Pod 自動擴縮控制器會定期調(diào)整其目標(例如:Deployment)的所需規(guī)模,以匹配觀察到的指標, 例如,平均 CPU 利用率、平均內(nèi)存利用率或你指定的任何其他自定義指標。
使用水平 Pod 自動擴縮演練示例。
HorizontalPodAutoscaler 是如何工作的?
HorizontalPodAutoscaler 控制 Deployment 及其 ReplicaSet 的規(guī)模
Kubernetes 將水平 Pod 自動擴縮實現(xiàn)為一個間歇運行的控制回路(它不是一個連續(xù)的過程)。間隔由 ?kube-controller-manager? 的 ?--horizontal-pod-autoscaler-sync-period? 參數(shù)設置(默認間隔為 15 秒)。
在每個時間段內(nèi),控制器管理器都會根據(jù)每個 HorizontalPodAutoscaler 定義中指定的指標查詢資源利用率。 控制器管理器找到由 ?scaleTargetRef ?定義的目標資源,然后根據(jù)目標資源的 ?.spec.selector? 標簽選擇 Pod, 并從資源指標 API(針對每個 Pod 的資源指標)或自定義指標獲取指標 API(適用于所有其他指標)。
- 對于按 Pod 統(tǒng)計的資源指標(如 CPU),控制器從資源指標 API 中獲取每一個 HorizontalPodAutoscaler 指定的 Pod 的度量值,如果設置了目標使用率, 控制器獲取每個 Pod 中的容器資源使用 情況, 并計算資源使用率。如果設置了 target 值,將直接使用原始數(shù)據(jù)(不再計算百分比)。 接下來,控制器根據(jù)平均的資源使用率或原始值計算出擴縮的比例,進而計算出目標副本數(shù)。
- 如果 Pod 使用自定義指示,控制器機制與資源指標類似,區(qū)別在于自定義指標只使用 原始值,而不是使用率。
- 如果 Pod 使用對象指標和外部指標(每個指標描述一個對象信息)。 這個指標將直接根據(jù)目標設定值相比較,并生成一個上面提到的擴縮比例。 在 ?
autoscaling/v2beta2? 版本 API 中,這個指標也可以根據(jù) Pod 數(shù)量平分后再計算。
需要注意的是,如果 Pod 某些容器不支持資源采集,那么控制器將不會使用該 Pod 的 CPU 使用率。 下面的算法細節(jié)章節(jié)將會介紹詳細的算法。
HorizontalPodAutoscaler 的常見用途是將其配置為從聚合 API (?metrics.K8S.io?、?custom.metrics.k8s.io? 或 ?external.metrics.k8s.io?)獲取指標。 ?metrics.k8s.io? API 通常由名為 Metrics Server 的插件提供,需要單獨啟動。
HorizontalPodAutoscaler 控制器訪問支持擴縮的相應工作負載資源(例如:Deployments 和 StatefulSet)。 這些資源每個都有一個名為 ?scale ?的子資源,該接口允許你動態(tài)設置副本的數(shù)量并檢查它們的每個當前狀態(tài)。
算法細節(jié)
從最基本的角度來看,Pod 水平自動擴縮控制器根據(jù)當前指標和期望指標來計算擴縮比例。
期望副本數(shù) = ceil[當前副本數(shù) * (當前指標 / 期望指標)]
例如,如果當前指標值為 200m,而期望值為 100m,則副本數(shù)將加倍, 因為 200.0 / 100.0 == 2.0 如果當前值為 50m,則副本數(shù)將減半, 因為 50.0 / 100.0 == 0.5。如果比率足夠接近 1.0(在全局可配置的容差范圍內(nèi),默認為 0.1), 則控制平面會跳過擴縮操作。
如果 HorizontalPodAutoscaler 指定的是 ?targetAverageValue ?或 ?targetAverageUtilization?, 那么將會把指定 Pod 度量值的平均值做為 ?currentMetricValue?。
在檢查容差并決定最終值之前,控制平面還會考慮是否缺少任何指標, 以及有多少 Pod 已就緒。
所有設置了刪除時間戳的 Pod(帶有刪除時間戳的對象正在關閉/移除的過程中)都會被忽略, 所有失敗的 Pod 都會被丟棄。
如果某個 Pod 缺失度量值,它將會被擱置,只在最終確定擴縮數(shù)量時再考慮。
當使用 CPU 指標來擴縮時,任何還未就緒(還在初始化,或者可能是不健康的)狀態(tài)的 Pod 或 最近的指標度量值采集于就緒狀態(tài)前的 Pod,該 Pod 也會被擱置。
由于技術限制,HorizontalPodAutoscaler 控制器在確定是否保留某些 CPU 指標時無法準確確定 Pod 首次就緒的時間。 相反,如果 Pod 未準備好并在其啟動后的一個可配置的短時間窗口內(nèi)轉(zhuǎn)換為未準備好,它會認為 Pod “尚未準備好”。 該值使用 ?--horizontal-pod-autoscaler-initial-readiness-delay? 標志配置,默認值為 30 秒。 一旦 Pod 準備就緒,如果它發(fā)生在自啟動后較長的、可配置的時間內(nèi),它就會認為任何向準備就緒的轉(zhuǎn)換都是第一個。 該值由 ?-horizontal-pod-autoscaler-cpu-initialization-period? 標志配置,默認為 5 分鐘。
在排除掉被擱置的 Pod 后,擴縮比例就會根據(jù) ?currentMetricValue/desiredMetricValue? 計算出來。
如果缺失某些度量值,控制平面會更保守地重新計算平均值,在需要縮小時假設這些 Pod 消耗了目標值的 100%, 在需要放大時假設這些 Pod 消耗了 0% 目標值。這可以在一定程度上抑制擴縮的幅度。
此外,如果存在任何尚未就緒的 Pod,工作負載會在不考慮遺漏指標或尚未就緒的 Pod 的情況下進行擴縮, 控制器保守地假設尚未就緒的 Pod 消耗了期望指標的 0%,從而進一步降低了擴縮的幅度。
考慮到尚未準備好的 Pod 和缺失的指標后,控制器會重新計算使用率。 如果新的比率與擴縮方向相反,或者在容差范圍內(nèi),則控制器不會執(zhí)行任何擴縮操作。 在其他情況下,新比率用于決定對 Pod 數(shù)量的任何更改。
注意,平均利用率的 原始 值是通過 HorizontalPodAutoscaler 狀態(tài)體現(xiàn)的, 而不考慮尚未準備好的 Pod 或缺少的指標,即使使用新的使用率也是如此。
如果創(chuàng)建 HorizontalPodAutoscaler 時指定了多個指標, 那么會按照每個指標分別計算擴縮副本數(shù),取最大值進行擴縮。 如果任何一個指標無法順利地計算出擴縮副本數(shù)(比如,通過 API 獲取指標時出錯), 并且可獲取的指標建議縮容,那么本次擴縮會被跳過。 這表示,如果一個或多個指標給出的 ?desiredReplicas ?值大于當前值,HPA 仍然能實現(xiàn)擴容。
最后,在 HPA 控制器執(zhí)行擴縮操作之前,會記錄擴縮建議信息。 控制器會在操作時間窗口中考慮所有的建議信息,并從中選擇得分最高的建議。 這個值可通過 ?kube-controller-manager? 服務的啟動參數(shù) ?--horizontal-pod-autoscaler-downscale-stabilization? 進行配置, 默認值為 5 分鐘。 這個配置可以讓系統(tǒng)更為平滑地進行縮容操作,從而消除短時間內(nèi)指標值快速波動產(chǎn)生的影響。
API 對象
HorizontalPodAutoscaler 是 Kubernetes ?autoscaling ?API 組中的 API 資源。 當前的穩(wěn)定版本可以在 ?autoscaling/v2? API 版本中找到,其中包括對基于內(nèi)存和自定義指標執(zhí)行擴縮的支持。 在使用 ?autoscaling/v1? 時,?autoscaling/v2? 中引入的新字段作為注釋保留。
創(chuàng)建 HorizontalPodAutoscaler 對象時,需要確保所給的名稱是一個合法的 DNS 子域名。 有關 API 對象的更多信息,請查閱 HorizontalPodAutoscaler 對象設計文檔。
工作量規(guī)模的穩(wěn)定性
在使用 HorizontalPodAutoscaler 管理一組副本的規(guī)模時,由于評估的指標的動態(tài)特性, 副本的數(shù)量可能會經(jīng)常波動。這有時被稱為 抖動(thrashing) 或 波動(flapping)。它類似于控制論中的 滯后(hysteresis) 概念。
滾動升級時擴縮
Kubernetes 允許你在 Deployment 上執(zhí)行滾動更新。在這種情況下,Deployment 為你管理下層的 ReplicaSet。 當你為一個 Deployment 配置自動擴縮時,你要為每個 Deployment 綁定一個 HorizontalPodAutoscaler。 HorizontalPodAutoscaler 管理 Deployment 的 ?replicas ?字段。 Deployment Controller 負責設置下層 ReplicaSet 的 ?replicas ?字段, 以便確保在上線及后續(xù)過程副本個數(shù)合適。
如果你對一個副本個數(shù)被自動擴縮的 StatefulSet 執(zhí)行滾動更新, 該 StatefulSet 會直接管理它的 Pod 集合 (不存在類似 ReplicaSet 這樣的中間資源)。
對資源指標的支持
HPA 的任何目標資源都可以基于其中的 Pods 的資源用量來實現(xiàn)擴縮。 在定義 Pod 規(guī)約時,類似 ?cpu ?和 ?memory ?這類資源請求必須被設定。 這些設定值被用來確定資源利用量并被 HPA 控制器用來對目標資源完成擴縮操作。 要使用基于資源利用率的擴縮,可以像下面這樣指定一個指標源:
type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60基于這一指標設定,HPA 控制器會維持擴縮目標中的 Pods 的平均資源利用率在 60%。 利用率是 Pod 的當前資源用量與其請求值之間的比值。
說明:
由于所有的容器的資源用量都會被累加起來,Pod 的總體資源用量值可能不會精確體現(xiàn) 各個容器的資源用量。這一現(xiàn)象也會導致一些問題,例如某個容器運行時的資源用量非常 高,但因為 Pod 層面的資源用量總值讓人在可接受的約束范圍內(nèi),HPA 不會執(zhí)行擴大 目標對象規(guī)模的操作。
容器資源指標
特性狀態(tài): Kubernetes v1.20 [alpha]
HorizontalPodAutoscaler API 也支持容器指標源,這時 HPA 可以跟蹤記錄一組 Pods 中各個容器的 資源用量,進而觸發(fā)擴縮目標對象的操作。 容器資源指標的支持使得你可以為特定 Pod 中最重要的容器配置規(guī)模擴縮閾值。 例如,如果你有一個 Web 應用和一個執(zhí)行日志操作的邊車容器,你可以基于 Web 應用的 資源用量來執(zhí)行擴縮,忽略邊車容器的存在及其資源用量。
如果你更改擴縮目標對象,令其使用新的、包含一組不同的容器的 Pod 規(guī)約,你就需要 修改 HPA 的規(guī)約才能基于新添加的容器來執(zhí)行規(guī)模擴縮操作。 如果指標源中指定的容器不存在或者僅存在于部分 Pods 中,那么這些 Pods 會被忽略, HPA 會重新計算資源用量值。要使用容器資源用量來完成自動擴縮,可以像下面這樣定義指標源:
type: ContainerResource
containerResource:
name: cpu
container: application
target:
type: Utilization
averageUtilization: 60在上面的例子中,HPA 控制器會對目標對象執(zhí)行擴縮操作以確保所有 Pods 中 ?application ?容器的平均 CPU 用量為 60%。
說明:
如果你要更改 HorizontalPodAutoscaler 所跟蹤記錄的容器的名稱,你可以按一定順序 來執(zhí)行這一更改,確保在應用更改的過程中用來判定擴縮行為的容器可用。 在更新定義容器的資源(如 Deployment)之前,你需要更新相關的 HPA,使之能夠同時 跟蹤記錄新的和老的容器名稱。這樣,HPA 就能夠在整個更新過程中繼續(xù)計算并提供擴縮操作建議。
一旦你已經(jīng)將容器名稱變更這一操作應用到整個負載對象至上,就可以從 HPA 的規(guī)約中去掉老的容器名稱,完成清理操作。
擴展自定義指標
特性狀態(tài): Kubernetes v1.23 [stable]
(之前的 ?autoscaling/v2beta2? API 版本將此功能作為 beta 功能提供)
如果你使用 ?autoscaling/v2? API 版本,則可以將 HorizontalPodAutoscaler 配置為基于自定義指標(未內(nèi)置于 Kubernetes 或任何 Kubernetes 組件)進行擴縮。 HorizontalPodAutoscaler 控制器能夠從 Kubernetes API 查詢這些自定義指標。
基于多個指標來執(zhí)行擴縮
特性狀態(tài): Kubernetes v1.23 [stable]
(之前的 ?autoscaling/v2beta2? API 版本將此功能作為 beta 功能提供)
如果你使用 ?autoscaling/v2? API 版本,你可以為 HorizontalPodAutoscaler 指定多個指標以進行擴縮。 HorizontalPodAutoscaler 控制器評估每個指標,并根據(jù)該指標提出一個新的比例。 HorizontalPodAutoscaler 采用為每個指標推薦的最大比例, 并將工作負載設置為該大?。ㄇ疤崾沁@不大于你配置的總體最大值)。
對 Metrics API 的支持
默認情況下,HorizontalPodAutoscaler 控制器會從一系列的 API 中檢索度量值。 集群管理員需要確保下述條件,以保證 HPA 控制器能夠訪問這些 API:
- 啟用了 API 聚合層
- 相應的 API 已注冊:
- 對于資源指標,將使用 ?
metrics.k8s.io? API,一般由 metrics-server 提供。 它可以作為集群插件啟動。 - 對于自定義指標,將使用 ?
custom.metrics.k8s.io? API。 它由其他度量指標方案廠商的“適配器(Adapter)” API 服務器提供。 檢查你的指標管道以查看是否有可用的 Kubernetes 指標適配器。 - 對于外部指標,將使用 ?
external.metrics.k8s.io? API??赡苡缮厦娴淖远x指標適配器提供。
關于指標來源以及其區(qū)別的更多信息,請參閱相關的設計文檔, HPA V2, custom.metrics.k8s.io 和 external.metrics.k8s.io。
可配置的擴縮行為
特性狀態(tài): Kubernetes v1.23 [stable]
(之前的 ?autoscaling/v2beta2? API 版本將此功能作為 beta 功能提供)
如果你使用 ?v2? HorizontalPodAutoscaler API,你可以使用 ?behavior ?字段來配置單獨的放大和縮小行為。你可以通過在行為字段下設置 ?scaleUp ?或 ?scaleDown ?來指定這些行為。
你可以指定一個 “穩(wěn)定窗口” ,以防止擴縮目標的副本計數(shù)發(fā)生波動。 擴縮策略還允許你在擴縮時控制副本的變化率。
擴縮策略
可以在規(guī)約的 ?behavior ?部分中指定一個或多個擴縮策略。當指定多個策略時, 允許最大更改量的策略是默認選擇的策略。以下示例顯示了縮小時的這種行為:
behavior:
scaleDown:
policies:
- type: Pods
value: 4
periodSeconds: 60
- type: Percent
value: 10
periodSeconds: 60?periodSeconds ?表示在過去的多長時間內(nèi)要求策略值為真。 第一個策略(Pods)允許在一分鐘內(nèi)最多縮容 4 個副本。第二個策略(Percent) 允許在一分鐘內(nèi)最多縮容當前副本個數(shù)的百分之十。
由于默認情況下會選擇容許更大程度作出變更的策略,只有 Pod 副本數(shù)大于 40 時, 第二個策略才會被采用。如果副本數(shù)為 40 或者更少,則應用第一個策略。 例如,如果有 80 個副本,并且目標必須縮小到 10 個副本,那么在第一步中將減少 8 個副本。 在下一輪迭代中,當副本的數(shù)量為 72 時,10% 的 Pod 數(shù)為 7.2,但是這個數(shù)字向上取整為 8。 在 autoscaler 控制器的每個循環(huán)中,將根據(jù)當前副本的數(shù)量重新計算要更改的 Pod 數(shù)量。 當副本數(shù)量低于 40 時,應用第一個策略(Pods),一次減少 4 個副本。
可以指定擴縮方向的 ?selectPolicy ?字段來更改策略選擇。 通過設置 ?Min ?的值,它將選擇副本數(shù)變化最小的策略。 將該值設置為 ?Disabled ?將完全禁用該方向的擴縮。
穩(wěn)定窗口
當用于擴縮的指標不斷波動時,穩(wěn)定窗口用于限制副本計數(shù)的波動。 自動擴縮算法使用此窗口來推斷先前的期望狀態(tài)并避免對工作負載規(guī)模進行不必要的更改。
例如,在以下示例代碼段中,為 ?scaleDown ?指定了穩(wěn)定窗口。
behavior:
scaleDown:
stabilizationWindowSeconds: 300當指標顯示目標應該縮容時,自動擴縮算法查看之前計算的期望狀態(tài),并使用指定時間間隔內(nèi)的最大值。 在上面的例子中,過去 5 分鐘的所有期望狀態(tài)都會被考慮。
這近似于滾動最大值,并避免了擴縮算法頻繁刪除 Pod 而又觸發(fā)重新創(chuàng)建等效 Pod。
默認行為
要使用自定義擴縮,不必指定所有字段。 只有需要自定義的字段才需要指定。 這些自定義值與默認值合并。 默認值與 HPA 算法中的現(xiàn)有行為匹配。
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max用于縮小穩(wěn)定窗口的時間為 300 秒(或是 ?--horizontal-pod-autoscaler-downscale-stabilization? 參數(shù)設定值)。 只有一種縮容的策略,允許 100% 刪除當前運行的副本,這意味著擴縮目標可以縮小到允許的最小副本數(shù)。 對于擴容,沒有穩(wěn)定窗口。當指標顯示目標應該擴容時,目標會立即擴容。 這里有兩種策略,每 15 秒添加 4 個 Pod 或 100% 當前運行的副本數(shù),直到 HPA 達到穩(wěn)定狀態(tài)。
示例:更改縮容穩(wěn)定窗口
將下面的 behavior 配置添加到 HPA 中,可提供一個 1 分鐘的自定義縮容穩(wěn)定窗口:
behavior:
scaleDown:
stabilizationWindowSeconds: 60
示例:限制縮容速率
將下面的 behavior 配置添加到 HPA 中,可限制 Pod 被 HPA 刪除速率為每分鐘 10%:
behavior:
scaleDown:
policies:
- type: Percent
value: 10
periodSeconds: 60為了確保每分鐘刪除的 Pod 數(shù)不超過 5 個,可以添加第二個縮容策略,大小固定為 5,并將 ?selectPolicy ?設置為最小值。 將 ?selectPolicy ?設置為 ?Min ?意味著 autoscaler 會選擇影響 Pod 數(shù)量最小的策略:
behavior:
scaleDown:
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 5
periodSeconds: 60
selectPolicy: Min
示例:禁用縮容
?selectPolicy ?的值 ?Disabled ?會關閉對給定方向的縮容。 因此使用以下策略,將會阻止縮容:
behavior:
scaleDown:
selectPolicy: Disabled
kubectl 對 HorizontalPodAutoscaler 的支持
與每個 API 資源一樣,HorizontalPodAutoscaler 都被 ?kubectl ?以標準方式支持。 你可以使用 ?kubectl create? 命令創(chuàng)建一個新的自動擴縮器。 你可以通過 ?kubectl get hpa? 列出自動擴縮器或通過 ?kubectl describe hpa? 獲取詳細描述。 最后,你可以使用 ?kubectl delete hpa? 刪除自動擴縮器。
此外,還有一個特殊的 ?kubectl autoscale? 命令用于創(chuàng)建 HorizontalPodAutoscaler 對象。 例如,執(zhí)行 ?kubectl autoscale rs foo --min=2 --max=5 --cpu-percent=80? 將為 ReplicaSet foo 創(chuàng)建一個自動擴縮器,目標 CPU 利用率設置為 ?80%?,副本數(shù)在 2 到 5 之間。
隱式維護狀態(tài)禁用
你可以在不必更改 HPA 配置的情況下隱式地為某個目標禁用 HPA。 如果此目標的期望副本個數(shù)被設置為 0,而 HPA 的最小副本個數(shù)大于 0, 則 HPA 會停止調(diào)整目標(并將其自身的 ?ScalingActive ?狀況設置為 ?false?), 直到你通過手動調(diào)整目標的期望副本個數(shù)或 HPA 的最小副本個數(shù)來重新激活。
將 Deployment 和 StatefulSet 遷移到水平自動擴縮
當啟用 HPA 時,建議從它們的清單中 刪除 Deployment 和/或 StatefulSet 的 ?spec.replicas? 的值。 如果不這樣做,則只要應用對該對象的更改,例如通過 ?kubectl apply -f deployment.yaml?, 這將指示 Kubernetes 將當前 Pod 數(shù)量擴縮到 ?spec.replicas? 鍵的值。這可能不是所希望的, 并且當 HPA 處于活動狀態(tài)時可能會很麻煩。
請記住,刪除 ?spec.replicas? 可能會導致 Pod 計數(shù)一次性降級,因為此鍵的默認值為 1。 更新后,除 1 之外的所有 Pod 都將開始其終止程序。之后的任何部署應用程序都將正常運行, 并根據(jù)需要遵守滾動更新配置。你可以根據(jù)修改部署的方式選擇以下兩種方法之一來避免這種降級:
- 客戶端 apply 操作(默認行為)
- ?
kubectl apply edit-last-applied deployment/? - 在編輯器中,刪除 ?
spec.replicas?。當你保存并退出編輯器時,?kubectl?會應用更新。 在此步驟中不會更改 Pod 計數(shù)。 - 你現(xiàn)在可以從清單中刪除 ?
spec.replicas?。如果你使用源代碼管理, 還應提交你的更改或采取任何其他步驟來修改源代碼,以適應你如何跟蹤更新。 - 從這里開始,你可以運行 ?
kubectl apply -f deployment.yaml? - 服務器端 apply 操作
使用服務器端 Apply 機制, 你可以遵循交出所有權 說明, 該指南涵蓋了這個確切的用例。
分享文章:創(chuàng)新互聯(lián)kubernetes教程:KubernetesPod水平自動擴縮
文章URL:http://m.5511xx.com/article/dhgojpd.html


咨詢
建站咨詢
