久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

使用 Prometheus 來避免 K8s CPU Limits 造成的事故

 bin仔學習園地 2023-04-18 發(fā)布于上海

本文將介紹 Kubernetes 的 resource limits 是如何工作的,、使用哪些 metrics 來設置正確的 limits 值,、以及使用哪些指標來定位 CPU 抑制的問題。


將 limits 中的 CPU 解釋為時間概念,,可以方便地理解容器中的多線程是如何使用 CPU 時間的,。


理解 Limits

在配置 limits 時,,我們會告訴 Linux 節(jié)點在一個特定的周期內(nèi)一個容器應用的運行時長。這樣做是為了保護節(jié)點上的其余負載不受任意一組進程占用過多 CPU 周期的影響,。

limits 的核并不是主板上的物理核,,而是配置了單個容器內(nèi)的一組進程或線程在容器短暫暫停 (避免影響到其他應用) 前的運行時長。這句話有點違反直覺,,特別是在 Kubernetes 調(diào)度器級別上很容易出錯,,Kubernetes 調(diào)度器使用了物理核的概念。

kubernetes 調(diào)度器在執(zhí)行調(diào)度的時候用的是節(jié)點上物理核的概念,,但容器運行的時候,,應該將 limits 配置的 CPU 轉換為 CPU 時間的概念。


Limits 其實是時間

下面使用一個虛構的例子來解釋這個概念,。假設有一個單線程應用,,該應用需要 1 秒 CPU 運行時間來完成一個事務,此時將 limits 配置為 1 core 或 1000 millicores:

Resources:
  limits:
    cpu: 1000m 

如果該應用需要完整的 1 秒 CPU 運行時間來服務一個 API 調(diào)用,,中間不能被停止或抑制,,即在容器被抑制前需要允許該應用運行 1000 毫秒 (ms) 或 1 CPU 秒。

圖片

由于 1000 毫秒等同于 1 秒 CPU 運行時間,,這就可以讓該應用每秒不受限地運行一個完整的 CPU 秒,,實際的工作方式更加微妙。我們將一個 CPU 秒稱為一個周期 (period),,用來衡量時間塊,。


Linux Accounting system

Limits 是一個記賬系統(tǒng) (Accounting system),用于跟蹤和限制一個容器在固定時間周期內(nèi)使用的總 vCPU 數(shù),,該值作為可用運行時的全局池進行跟蹤,,一個容器可以在該周期內(nèi)使用該池。上面陳述中有很多內(nèi)容,,下面對此進行分析,。

回到周期或記賬系統(tǒng)翻頁頻率的概念。我們需要跨多個 vCPU 申請運行時間,,這意味著需要將賬簿的每頁分為多個段,,稱為切片。Linux 內(nèi)核默認會將一個周期分為 20 個切片,。

圖片

假設我們需要運行半個周期,,此時只需要將配額配置為一半數(shù)目的切片即可,在一個周期之后,,記賬系統(tǒng)會重置切片,,并重啟進程。

圖片

類似于 requests 或 shares 可以轉換為表示 CPU 分配百分比的比率,也可以將 limits 轉換為一個百分比,。例如,,容器的配額設置為半個周期,則配置為:

resources:
 limits:
   cpu: 500m

開始時,,使用 1000 milliCPU 作為一個完整的 share,。當配置 500 milliCPU 時,使用了半個周期,,或 500m/1000m =  50%,。如果設置了 200m/1000m,則表示使用的 CPU 比率為 20%,,以此類推,。我們需要這些轉換數(shù)字來理解一些 prometheus 的指標輸出。

上面提到的記賬系統(tǒng)是按容器計算的,,下面看下指標 container_spec_cpu_period,,與我們假設的實驗不同,實際與容器相關的周期為 100ms,。

圖片

Linux 有一個配置,,稱為 cpu.cfs_period_us,設置了賬簿翻到下一頁前的時間,,該值表示下一個周期創(chuàng)建前的微秒時間,。這些 Linux 指標會通過 cAdvisor 轉換為 prometheus 指標。

撇開一些特殊場景不談,,在賬簿翻頁之前經(jīng)過的時間并不像被限制的 CPU 時間切片那樣重要,。

下面看下使用 cpu.cfs_quota_us 指標設置的容器配額,這里配置為 50 毫秒,,即 100ms 的一半:

圖片


多線程容器

容器通常具有多個處理線程,,根據(jù)語言的不同,可能有數(shù)百個線程,。

圖片

當這些線程 / 進程運行時,它們會調(diào)度不同的 (可用)vCPU,,Linux 的記賬系統(tǒng)需要全局跟蹤誰在使用這些 vCPU,,以及需要將哪些內(nèi)容添加到賬簿中。

先不談周期的概念,,下面我們使用 container_cpu_usage_seconds_total 來跟蹤一個應用的線程在 1 秒內(nèi)使用的 vCPU 數(shù),。假設線程在 4 個 vCPU 上均運行了整整一秒鐘,則說明其使用了 4 個 vCPU 秒,。

如果總的 vCPU 時間小于 1 個 vCPU 秒會發(fā)生什么呢,?此時會在該時間幀內(nèi)抑制節(jié)點上該應用的其他線程的運行。


Global accounting

上面討論了如何將一個 vCPU 秒切分為多個片,,然后就可以全局地在多個 vCPU 上申請時間片,。讓我們回到上述例子 (4 個線程運行在 4 個 vCPU 上),,進一步理解它們?nèi)绾芜\行的。

當一個 CPU 需要運行其隊列中的一個線程或進程時,,它首先會確認容器的全局配額中是否有 5ms 的時間片,,如果全局配額中有足夠的時間片,則會啟動線程,,否則,,該線程會被抑制并等待下一個周期。

圖片


真實場景

下面假設一個實驗,,假如有 4 個線程,,每個線程需要 100ms 的 CPU 時間來完成一個任務,將所有所需的 vCPU 時間加起來,,總計需要 400ms 或 4000m,,因此可以以此為進程配置 limit 來避免被抑制。

圖片

不幸的是,,實際的負載并不是這樣的,。這些函數(shù)的線程可能運行重的或輕的 API 調(diào)用。應用所需的 CPU 時間是變化的,,因此不能將其認為是一個固定的值,。再進一步,4 個線程可能并不會同時各需要一個 vCPU,,有可能某些線程需要等待數(shù)據(jù)庫鎖或其他條件就緒,。

正因為如此,負載往往會突然爆發(fā),,因此延遲并不總是能夠成為設置 limits 的候選因素,。最新的一個特性--cpu.cfs_burst_us[1]允許將部分未使用的配額由一個周期轉至下一個周期。

有趣的是,,這并不是讓大多數(shù)客戶陷入麻煩的地方,。假設我們只是猜測了應用程序和測試需求,并且 1 個 CPU 秒聽起來差不多是正確的,。該容器的應用程序線程將分布到 4 個 vCPU 上,。這樣做的結果是將每個線程的全局配額分為 100ms/4 或 25ms 的運行時。

圖片

而實際的總配額為 (100ms 的配額) * (4 個線程) 或 400ms 的配額,。在 100 毫秒的現(xiàn)實時間里,,所有線程有 300 毫秒處于空閑狀態(tài)。因此,,這些線程總共被抑制了 300 毫秒,。

Latency

下面從應用的角度看下這些影響。單線程應用需要 100ms 來完成一個任務,當設置的配額為 100ms 或 1000 m/1000 m = 100%,,此時設置了一個合理的 limits,,且沒有抑制。

圖片

在第二個例子中,,我們猜測錯誤,,并將 limits 設置為 400m 或 400 m/1000 m = 40%,此時的配額為 100ms 周期中的 40ms,。下圖展示該配置了對該應用的延遲:

圖片

此時處理相同請求的時間翻倍 (220ms),。該應用在三個統(tǒng)計周期中的兩個周期內(nèi)受到了抑制。在這兩個周期中,,應用被抑制了 60ms,。更重要的是,如果沒有其他需要處理的線程,,vCPU 將會被浪費,,這不僅僅會降低應用的處理速度,也會降低 CPU 的利用率,。

與 limits 相關的最常見的指標 container_cpu_cfs_throttled_periods_total 展示了被抑制的周期,,container_cpu_cfs_periods_total 則給出了總的可用周期。上例中,,三分之二 (66%) 的周期被抑制了,。

那么,如何知道 limits 應該增加多少呢,?


Throttled seconds

幸運的是,,cAdvisor 提供了一個指標 container_cpu_cfs_throttled_seconds_total,它會累加所有被抑制的 5ms 時間片,,并讓我們知道該進程超出配額的數(shù)量,。指標的單位是秒,因此可以通過將該值除以 10 來獲得 100ms(即我們設置的周期),。

通過如下表達式可以找出 CPU 使用超過 100ms 的前三個 pods,。

topk(3, max by (pod, container)(rate(container_cpu_usage_seconds_total{image!='', instance='$instance'}[$__rate_interval]))) / 10

下面做一個實驗:使用 sysbench 啟動一個現(xiàn)實時間 100ms 中需要 400ms CPU 時間的的 4 線程應用。

          command:
            - sysbench
            - cpu
            - --threads=4
            - --time=0
            - run

可以觀測到使用了 400ms 的 vCPU:

圖片

下面對該容器添加 limits 限制:

          resources:
            limits:
              cpu: 2000m
              memory: 128Mi

可以看到總的 CPU 使用在 100ms 的現(xiàn)實時間中減少了一半,,這正是我們所期望的,。

圖片

PromQL 給出了每秒的抑制情況,每秒有 10 個周期 (每個周期默認 100ms),。為了得到每個周期的抑制情況,需要除以 10,。如果需要知道應該增加多少 limits,,則可以乘以 10(如 200ms * 10 = 2000m)。

topk(3, max by (pod, container)(rate(container_cpu_cfs_throttled_seconds_total{image!='', instance='$instance'}[$__rate_interval]))) / 10



告警設置

可以基于 CPU 抑制時間或抑制比率來編寫告警表達式,其表達的也是 CPU 的飽和度信息:

# CPU抑制時間超過1s時產(chǎn)生告警
rate(container_cpu_cfs_throttled_seconds_total{namespace=~'wordpress-.*'}[1m]) > 1
# CPU抑制周期占可用周期的一半時產(chǎn)生告警
sum(increase(container_cpu_cfs_throttled_periods_total{container!=''}[5m])) by (container, pod, namespace)/sum(increase(container_cpu_cfs_periods_total{}[5m])) by (container, pod, namespace) *100 > 50



總結

本文介紹了 limits 是如何工作的,,以及可以使用哪些指標來設置正確的值,,使用哪些指標來進行抑制類型的問題定位。本文的實驗提出了一個觀點,,即過多地配置 limits 的 vCPU 數(shù)也可能會導致 vCPU 處于 idle 狀態(tài)而造成應用響應延遲,,但在現(xiàn)實的服務中,一般會包含語言自身 runtime 的線程 (如 go 和 java) 以及開發(fā)者自己啟動的線程,,一般設置較多的 vCPU 不會對應用的響應造成影響,,但會造成資源浪費。



參考

  • Demystifying Kubernetes CPU Limits (and Throttling)[2]

引用鏈接

[1]

cpu.cfs_burst_us: https:///Articles/844976/

[2]

Demystifying Kubernetes CPU Limits (and Throttling): https:///understanding-kubernetes-cpu-limits/


來源: charlieroro 的博客,,原文:https://www.cnblogs.com/charlieroro/p/17074808.html

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多