
我在 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 輸出
免費頁面將降至低水位線以下:空閒頁面
因此,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 進程不再混亂了。