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

하나의 노드는 일부 마이크로서비스를 실행하는 데 사용됩니다. 모든 마이크로서비스를 사용하기 시작하면 각각 10%의 RAM을 사용합니다. 그리고 kswapd0 프로세스는 많은 CPU를 사용하기 시작합니다.

마이크로서비스에 약간의 스트레스를 가하면 kswapd0이 모든 CPU를 사용하기 때문에 마이크로서비스가 응답을 중지합니다. kswapd0이 작업을 중단하면 기다리려고 했지만 그런 일은 결코 일어나지 않았습니다. 10시간이 지나도.

많은 내용을 읽었지만 해결책을 찾지 못했습니다.

RAM의 양을 늘릴 수 있지만 이렇게 해도 문제가 해결되지는 않습니다.

Kubernetes Masters는 이런 종류의 문제를 어떻게 처리합니까?

자세한 내용은:

  • 쿠버네티스 버전 1.15
  • 옥양목 버전 3.8
  • 데비안 버전 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의 이러한 동작은 의도적으로 설계된 것이며 설명이 가능합니다.

스왑 파일을 비활성화 및 제거하고 스왑성을 0으로 설정했지만 kswapd는 사용 가능한 메모리를 계속 감시합니다. 아무런 조치도 취하지 않고 거의 모든 메모리를 사용할 수 있습니다. 그러나 사용 가능한 메모리가 매우 낮은 값(테스트 서버의 4K 페이지 중 4,000개에 달하는 Normal 영역의 낮은 페이지)으로 떨어지자마자 /proc/zoneinfokswapd가 개입합니다. 이로 인해 CPU 사용률이 높아집니다.

다음 방법으로 문제를 재현하고 더 자세히 조사할 수 있습니다. Roman Evstifeev가 제공하는 스크립트와 같이 제어된 방식으로 메모리를 소비할 수 있는 도구가 필요합니다.ramhog.py

스크립트는 ASCII 코드 "Z"의 100MB 청크로 메모리를 채웁니다. 실험의 공정성을 위해 스크립트는 k8s가 관련되지 않도록 Pod가 아닌 Kubernetes 호스트에서 실행됩니다. 이 스크립트는 Python3에서 실행되어야 합니다. 다음과 같이 약간 수정되었습니다.

  • 3.6 이전 Python 버전과 호환됩니다.
  • 시스템 성능 저하가 결국 더 눈에 띄도록 메모리 할당 청크를 4000 메모리 페이지(/proc/zoneinfo의 Normal 영역에 대한 낮은 페이지, 10MB로 설정)보다 작게 설정하십시오.
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개의 터미널 연결을 설정할 수 있습니다.

  • 스크립트를 실행하십시오.
  • 최상위 명령을 실행하십시오.
  • /proc/zoneinfo 가져오기

스크립트를 실행합니다:

$ python3 ramhog.py

Enter 키를 여러 번 입력한 후에(우리가 설정한 작은 메모리 할당 청크(10MB)로 인해 발생) 다음을 알 수 있습니다.

속도 MemAvailable가 점점 낮아지고 시스템의 응답성이 점점 낮아지고 있습니다.ramhog.py 출력

ramhog.pu 출력

무료 페이지는 낮은 워터마크 아래로 떨어집니다.무료 페이지

구역 정보

결과적으로 kswapd와 k8s 프로세스가 깨어나고 CPU 사용률이 최대 100%까지 증가합니다.맨 위

최고 명령 출력

스크립트는 k8s와 별도로 실행되며 SWAP이 비활성화되어 있습니다. 따라서 Kubernetes와 kswapd0은 모두 테스트 시작 시 유휴 상태였습니다. 실행 중인 포드는 건드리지 않았습니다. 하지만 시간이 지남에 따라 세 번째 응용 프로그램으로 인해 사용 가능한 메모리가 부족해지면 kswapd뿐만 아니라 k8s에서도 CPU 사용률이 높아집니다. 이는 근본 원인이 메모리 부족 때문이지 k8s나 kswapd 자체가 아니라는 뜻입니다.

/proc/meminfo귀하가 제공한 것에서 볼 수 있듯이 , MemAvailablekswapd가 깨어나도록 하는 원인이 상당히 낮아지고 있습니다. /proc/zoneinfo서버에서도 살펴보십시오 .

실제로 근본 원인은 k8s와 kswap0 사이의 충돌이나 비호환성에 있는 것이 아니라 비활성화된 스왑과 메모리 부족 사이의 모순으로 인해 kswapd 활성화가 발생하는 데 있습니다. 시스템을 재부팅하면 문제가 일시적으로 해결되지만 RAM을 추가하는 것이 좋습니다.

kswapd 동작에 대한 좋은 설명은 다음과 같습니다. kswapd는 CPU 사이클을 많이 사용하고 있습니다.

답변2

Kubernetes를 사용하면 매개변수를 사용하여 Linux 시스템에 유지해야 하는 RAM의 양을 정의할 수 있습니다 evictionHard.memory.available. 이 매개변수는 이라는 ConfigMap에 설정됩니다 kubelet-config-1.XX. RAM이 구성에서 허용하는 수준을 초과하면 Kubernertes는 Pod 사용을 줄이기 위해 Pod를 종료하기 시작합니다.

내 경우에는 evictionHard.memory.available매개변수가 너무 낮게 설정되었습니다(100Mi). 따라서 Linux 시스템에는 RAM 공간이 충분하지 않으므로 RAM 사용량이 너무 높은 곳에서 kswapd0이 문제를 일으키기 시작합니다.

몇 가지 테스트 후에 kswapd0의 상승을 피하기 evictionHard.memory.available위해 800Mi. kswapd0 프로세스는 더 이상 엉망이 되지 않았습니다.

관련 정보