
Construyo un clúster de kubernetes básico (nada pesado, solo tres servidores) con kubeadm en Debian 9. Como lo pidió Kubernetes, desactivo el SWAP:
- intercambio -a
- eliminando la línea SWAP en
/etc/fstab
- Añadiendo
vm.swappiness = 0
a/etc/sysctl.conf
Entonces, ya no hay SWAP en mis servidores.
$ free
total used free shared buff/cache available
Mem: 5082668 3679500 117200 59100 1285968 1050376
Swap: 0 0 0
Se utiliza un nodo para ejecutar algunos microservicios. Cuando empiezo a jugar con todos los microservicios, utilizan el 10% de RAM cada uno. Y el proceso kswapd0 comienza a utilizar mucha CPU.
Si hago hincapié un poco en los microservicios, dejan de responder porque kswapd0 usa toda la CPU. Intento esperar si kswapd0 detiene su trabajo, pero nunca sucedió. Incluso después de las 10 h.
Leí muchas cosas pero no encontré ninguna solución.
Puedo aumentar la cantidad de RAM, pero esto no solucionará mi problema.
¿Cómo abordan los Kubernetes Masters este tipo de problemas?
Más detalles:
- Kubernetes versión 1.15
- Calicó versión 3.8
- versión debian 9.6
De antemano, gracias por su valiosa ayuda.
-- Edición 1 --
Según lo solicitado por @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
Respuesta1
Este comportamiento del kswapd0 es por diseño y es explicable.
Aunque deshabilitó y eliminó el archivo de intercambio y configuró el intercambio en cero, kswapd vigila la memoria disponible. Te permite consumir casi toda la memoria sin realizar ninguna acción. Pero tan pronto como la memoria disponible cae a un valor críticamente bajo (páginas bajas para la zona Normal en /proc/zoneinfo
, ~4000 de páginas 4K en mi servidor de prueba), kswapd interviene. Esto provoca una alta utilización de la CPU.
Puede reproducir el problema e investigarlo más profundamente de la siguiente manera. Necesitará una herramienta que le permita consumir memoria de forma controlada, como un script, ofrecido por Roman Evstifeev:ramhog.py
El script llena la memoria con fragmentos de 100 MB del código ASCII de "Z". Para que el experimento sea justo, el script se inicia en el host de Kubernetes, no en el pod, para que los k8 no participen. Este script debe ejecutarse en Python3. Se modifica un poco para:
- ser compatible con versiones de Python anteriores a la 3.6;
- establezca el fragmento de asignación de memoria en menos de 4000 páginas de memoria (páginas bajas para la zona Normal en /proc/zoneinfo; configuré 10 MB) para que la degradación del rendimiento del sistema sea más visible al final.
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)
Puede establecer 3 conexiones de terminales con el sistema de prueba para observar lo que sucede:
- ejecutar el guión;
- ejecute el comando superior;
- buscar el /proc/zoneinfo
Ejecute el script:
$ python3 ramhog.py
Después de escribir bastantes veces la tecla Intro (causada por la pequeña porción de asignación de memoria que hemos configurado (10 MB)), notarás que
El nivel MemAvailable
se está agotando y su sistema responde cada vez menos:salida de ramhog.py
Las páginas gratuitas caerán por debajo de la marca de agua baja:paginas gratis
En consecuencia, kswapd se activará, así como los procesos k8s, y la utilización de la CPU aumentará hasta el 100%:arriba
Tenga en cuenta que el script se ejecuta por separado de los k8 y el SWAP está deshabilitado. Por lo tanto, tanto Kubernetes como kswapd0 estaban inactivos al comienzo de la prueba. Las cápsulas para correr no fueron tocadas. Sin embargo, con el tiempo la falta de memoria disponible provocada por la tercera aplicación provoca un alto uso de la CPU: no sólo por kswapd sino también por k8s. Eso significa que la causa principal es la memoria insuficiente, pero no los propios k8s o kswapd.
Como puede ver en lo /proc/meminfo
que proporcionó, el nivel MemAvailable
se está volviendo bastante bajo, lo que hace que kswapd se active. Por favor, mire /proc/zoneinfo
también el de su servidor.
En realidad, la causa raíz no está en el choque o la incompatibilidad entre k8s y kswap0, sino en la contradicción entre el intercambio deshabilitado y la falta de memoria que a su vez provoca la activación de kswapd. El reinicio del sistema resolverá temporalmente el problema, pero se recomienda agregar más RAM.
Aquí encontrará una buena explicación del comportamiento de kswapd: kswapd está usando muchos ciclos de CPU
Respuesta2
Kubernetes nos permite definir cuánta RAM debemos conservar para el sistema Linux mediante el evictionHard.memory.available
parámetro. Este parámetro se establece en un ConfigMap llamado kubelet-config-1.XX
. Si la RAM excede el nivel permitido por la configuración, Kubernertes comienza a eliminar los Pods para reducir su uso.
En mi caso, el evictionHard.memory.available
parámetro se configuró demasiado bajo (100Mi). Por lo tanto, no hay suficiente espacio de RAM para el sistema Linux, por lo que kswapd0 comienza a fallar cuando el uso de RAM es demasiado alto.
Después de algunas pruebas, para evitar el aumento de kswapd0, configuré el evictionHard.memory.available
valor 800Mi
. El proceso kswapd0 ya no se estropeó.