Kubernetes と kswapd0 は悪のカップル?

Kubernetes と kswapd0 は悪のカップル?

Debian 9 で kubeadm を使用してベアメタル Kubernetes クラスター (重いものではなく、サーバーが 3 つだけ) を構築します。Kubernetes の質問に従って、SWAP を無効にします。

  • スワップオフ -a
  • SWAP行を削除する/etc/fstab
  • 追加vm.swappiness = 0する/etc/sysctl.conf

つまり、私のサーバーにはもう SWAP はありません。

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

1 つのノードは、いくつかのマイクロサービスを実行するために使用されます。すべてのマイクロサービスで操作を開始すると、それぞれが RAM の 10% を使用します。また、kswapd0 プロセスが CPU を大量に使用し始めます。

マイクロサービスに少し負荷をかけると、kswapd0 が CPU をすべて使用するため、応答が停止します。kswapd0 が作業を停止するかどうかを待とうとしましたが、10 時間経過しても停止しませんでした。

いろいろ読みましたが、解決策は見つかりませんでした。

RAM の量を増やすことはできますが、問題は解決しません。

Kubernetes マスターはこのような問題にどのように対処するのでしょうか?

詳細:

  • 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 を 0 に設定しても、kswapd は使用可能なメモリを監視しています。これにより、何もせずにほぼすべてのメモリを消費できます。ただし、使用可能なメモリが極めて低い値 (の Normal ゾーンのページ数が少ない/proc/zoneinfo、テスト サーバーでは 4K ページのうち約 4000 ページ) に低下するとすぐに、kswapd が介入します。これにより、CPU 使用率が高くなります。

次の方法で問題を再現し、さらに詳しく調査することができます。Roman Evstifeev が提供しているスクリプトのように、メモリを制御された方法で消費できるツールが必要になります。ラムホッグ

このスクリプトは、メモリを ASCII コード「Z」の 100 MB のチャンクで埋めます。実験の公平性を保つために、スクリプトはポッドではなく Kubernetes ホストで起動され、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% まで上昇します。

topコマンドの出力

スクリプトは k8s とは別に実行されており、SWAP は無効になっていることに注意してください。そのため、テストの開始時には Kubernetes と kswapd0 の両方がアイドル状態でした。実行中のポッドには影響しませんでした。しかし、時間の経過とともに、3 番目のアプリケーションによって使用可能なメモリが不足し、kswapd だけでなく k8s でも CPU 使用率が高くなります。つまり、根本的な原因はメモリ不足であり、k8s や kswapd 自体ではないということです。

/proc/meminfo提供されたからわかるように、 がMemAvailable非常に少なくなり、kswapd が起動する原因になっています。/proc/zoneinfoサーバーの も確認してください。

実際のところ、根本的な原因は k8s と kswap0 の衝突や非互換性ではなく、無効化されたスワップとメモリ不足の矛盾にあり、それが 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 プロセスはもう混乱しなくなりました。

関連情報