Kubernetes 和 kswapd0 是一對邪惡的情侶?

Kubernetes 和 kswapd0 是一對邪惡的情侶?

我在 Debian 9 上使用 kubeadm 建立了一個裸機 kubernetes 叢集(不重,只有三台伺服器)。

  • 交換-a
  • 刪除 SWAP 行/etc/fstab
  • 添加vm.swappiness = 0/etc/sysctl.conf

所以,我的伺服器上不再有交換。

$ free
              total        used        free      shared  buff/cache   available
Mem:        5082668     3679500      117200       59100     1285968     1050376
Swap:             0           0           0

一個節點用於運行一些微服務。當我開始使用所有微服務時,它們每個都使用 10% 的 RAM。且kswapd0進程開始使用大量CPU。

如果我對微服務施加一點壓力,它們就會停止回應,因為 kswapd0 會使用所有 CPU。我嘗試等待 kswapd0 停止他的工作,但它從未發生。即使10小時後。

我讀了很多東西但沒有找到任何解決方案。

我可以增加 RAM 的數量,但這並不能解決我的問題。

Kubernetes大師們是如何處理這類問題的呢?

更多細節:

  • 庫伯內特版本 1.15
  • 印花布版本 3.8
  • Debian 版本 9.6

預先感謝您的寶貴幫助。

-- 編輯1 --

根據@john-mahowald 的要求

$ cat /proc/meminfo
MemTotal:        4050468 kB
MemFree:          108628 kB
MemAvailable:      75156 kB
Buffers:            5824 kB
Cached:           179840 kB
SwapCached:            0 kB
Active:          3576176 kB
Inactive:          81264 kB
Active(anon):    3509020 kB
Inactive(anon):    22688 kB
Active(file):      67156 kB
Inactive(file):    58576 kB
Unevictable:          92 kB
Mlocked:              92 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:       3472080 kB
Mapped:           116180 kB
Shmem:             59720 kB
Slab:             171592 kB
SReclaimable:      48716 kB
SUnreclaim:       122876 kB
KernelStack:       30688 kB
PageTables:        38076 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     2025232 kB
Committed_AS:   11247656 kB
VmallocTotal:   34359738367 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      106352 kB
DirectMap2M:     4087808 kB

答案1

kswapd0 的這種行為是設計使然,並且是可以解釋的。

儘管您已停用並刪除了交換檔案並將 swappiness 設為零,但 kswapd 仍會密切注意可用記憶體。它允許您在不執行任何操作的情況下消耗幾乎所有記憶體。但是,一旦可用記憶體下降到極低的值(/proc/zoneinfo我的測試伺服器上的正常區域的頁面較少,大約 4000 個 4K 頁),kswapd 就會介入。

您可以透過以下方式重現問題並進行更深入的調查。您將需要一個允許您以受控方式消耗記憶體的工具,例如 Roman Evstifeev 提供的腳本:ramhog.py

該腳本以 100MB 的 ASCII 代碼“Z”區塊填充記憶體。為了實驗公平性,腳本在 Kubernetes 主機上啟動,而不是在 pod 中啟動,以使 k8s 不參與其中。該腳本應在 Python3 中運行。對其進行了一些修改,以便:

  • 相容於Python 3.6之前的版本;
  • 將記憶體分配區塊設定為小於 4000 個記憶體頁(/proc/zoneinfo 中的 Normal 區域的低頁;我設定為 10 MB),以便最終系統效能下降更加明顯。
from time import sleep

print('Press ctrl-c to exit; Press Enter to hog 10MB more')

one = b'Z' * 1024 * 1024  # 1MB hog = []

while True:
    hog.append(one * 10)  # allocate 10MB
    free = ';\t'.join(open('/proc/meminfo').read().split('\n')[1:3])
    print("{}\tPress Enter to hog 10MB more".format(free), end='')
    input()
    sleep(0.1)

您可以與測試系統建立 3 個終端連線來觀察正在發生的情況:

  • 運行腳本;
  • 運行top命令;
  • 取得/proc/zoneinfo

運行腳本:

$ python3 ramhog.py

在輸入 Enter 鍵多次後(由我們設定的小型記憶體分配區塊 (10MB) 引起),您會注意到

越來越MemAvailable低,您的系統反應速度越來越慢:ramhog.py 輸出

ramhog.pu 輸出

免費頁面將降至低水位線以下:空閒頁面

區域資訊

因此,kswapd 和 k8s 進程都會被喚醒,CPU 使用率將提高到 100%:頂部

頂部命令輸出

請注意,該腳本與 k8s 分開運行,並且 SWAP 被禁用。因此,Kubernetes 和 kswapd0 在測試開始時都處於空閒狀態。運作中的豆莢沒有受到影響。儘管如此,隨著時間的推移,第三個應用程式導致的可用記憶體不足會導致 CPU 使用率過高:不僅是 kswapd,k8s 也是如此。這意味著根本原因是記憶體不足,而不是 k8s 或 kswapd 本身。

/proc/meminfo正如您從所提供的中看到的,它MemAvailable變得非常低,導致 kswapd 被喚醒。另請查看/proc/zoneinfo您的伺服器。

其實根本原因並不是k8s和kswap0之間的衝突或不相容,而是swap被禁用和記憶體不足之間的矛盾,進而導致kswapd啟動。系統重新啟動將暫時解決該問題,但強烈建議添加更多 RAM。

對 kswapd 行為的一個很好的解釋是: kswapd 正在使用大量 CPU 週期

答案2

Kubernetes 讓我們可以使用參數定義應該為 Linux 系統保留多少 RAM evictionHard.memory.available。此參數在名為 的 ConfigMap 中設定kubelet-config-1.XX。如果 RAM 超過配置允許的水平,Kubernertes 就會開始殺死 Pod 以減少其使用。

就我而言,evictionHard.memory.available參數設定得太低(100Mi)。因此,Linux 系統沒有足夠的 RAM 空間,因此當 RAM 使用率過高時,kswapd0 就會開始出現混亂。

經過一些測試,為了避免 kswapd0 的上升,我將其evictionHard.memory.available設為800Mi. kswapd0 進程不再混亂了。

相關內容