
Eu construo um cluster kubernetes bare-metal (nada pesado, apenas três servidores) com kubeadm no Debian 9. Como solicitado pelo Kubernetes, desativo o SWAP:
- troca -a
- removendo a linha SWAP em
/etc/fstab
- Adicionando
vm.swappiness = 0
a/etc/sysctl.conf
Portanto, não há mais SWAP em meus servidores.
$ free
total used free shared buff/cache available
Mem: 5082668 3679500 117200 59100 1285968 1050376
Swap: 0 0 0
Um nó é usado para executar alguns microsserviços. Quando começo a brincar com todos os microsserviços, eles usam 10% de RAM cada. E o processo kswapd0 começa a usar muita CPU.
Se eu enfatizar um pouco os microsserviços eles param de responder porque o kswapd0 usa toda a CPU. Tento esperar que kswapd0 interrompa seu trabalho, mas isso nunca aconteceu. Mesmo depois das 10h.
Li muita coisa mas não encontrei nenhuma solução.
Posso aumentar a quantidade de RAM, mas isso não resolverá meu problema.
Como os Mestres do Kubernetes lidam com esse tipo de problema?
Mais detalhes:
- Kubernetes versão 1.15
- Calico versão 3.8
- Debian versão 9.6
Desde já, obrigado pela sua preciosa ajuda.
- Editar 1 -
Conforme 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
Responder1
Esse comportamento do kswapd0 é intencional e é explicável.
Embora você tenha desabilitado e removido o arquivo de troca e definido a troca como zero, o kswapd está de olho na memória disponível. Ele permite que você consuma quase toda a memória sem realizar nenhuma ação. Mas assim que a memória disponível cai para um valor criticamente baixo (páginas baixas para a zona Normal em /proc/zoneinfo
cerca de 4.000 páginas de 4K em meu servidor de teste), o kswapd entra em ação.
Você pode reproduzir o problema e investigá-lo mais profundamente da seguinte maneira. Você precisará de uma ferramenta que permita consumir memória de forma controlada, como um script, oferecido por Roman Evstifeev:ramhog.py
O script preenche a memória com pedaços de 100 MB do código ASCII de “Z”. Para a justiça do experimento, o script é lançado no host Kubernetes, não no pod, para que os k8s não sejam envolvidos. Este script deve ser executado em Python3. Ele é um pouco modificado para:
- ser compatível com versões do Python anteriores à 3.6;
- defina o bloco de alocação de memória menor que 4.000 páginas de memória (páginas baixas para a zona Normal em /proc/zoneinfo; defino 10 MB) para que a degradação do desempenho do sistema seja mais visível no 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)
Você pode estabelecer três conexões de terminal com o sistema de teste para observar o que está acontecendo:
- execute o script;
- execute o comando superior;
- busque o /proc/zoneinfo
Execute o script:
$ python3 ramhog.py
Depois de algumas digitações na tecla Enter (causadas pelo pequeno pedaço de alocação de memória que definimos (10 MB)), você notará que
o MemAvailable
está ficando baixo e seu sistema está se tornando cada vez menos responsivo:Saída ramhog.py
As páginas gratuitas ficarão abaixo da marca d’água baixa:páginas gratuitas
Consequentemente, o kswapd será ativado, assim como os processos k8s, e a utilização da CPU aumentará em até 100%:principal
Observe que o script está sendo executado separadamente do k8s e o SWAP está desabilitado. Conseqüentemente, tanto o Kubernetes quanto o kswapd0 estavam inativos no início do teste. Os pods em execução não foram tocados. Mesmo assim, com o tempo, a falta de memória disponível causada pelo terceiro aplicativo causa alta utilização da CPU: não apenas pelo kswapd, mas também pelo k8s. Isso significa que a causa raiz é a memória insuficiente, mas não o próprio k8s ou kswapd.
Como você pode ver pelo que /proc/meminfo
você forneceu, MemAvailable
está ficando muito baixo, fazendo com que o kswapd seja ativado. Por favor, verifique /proc/zoneinfo
também o seu servidor.
Na verdade, a causa raiz não está no conflito ou incompatibilidade entre k8s e kswap0, mas na contradição entre a troca desabilitada e a falta de memória que por sua vez causa a ativação do kswapd. A reinicialização do sistema resolverá temporariamente o problema, mas adicionar mais RAM é realmente recomendado.
Uma boa explicação do comportamento do kswapd está aqui: kswapd está usando muitos ciclos de CPU
Responder2
Kubernetes nos permite definir quanta RAM devemos manter para o sistema Linux usando o evictionHard.memory.available
parâmetro. Este parâmetro é definido em um ConfigMap chamado kubelet-config-1.XX
. Se a RAM exceder o nível permitido pela configuração, o Kubernertes começa a eliminar os pods para reduzir seu uso.
No meu caso o evictionHard.memory.available
parâmetro foi definido muito baixo (100Mi). Portanto, não há espaço de RAM suficiente para o sistema Linux, então kswapd0 começa a bagunçar quando o uso de RAM é muito alto.
Após alguns testes, para evitar o aumento do kswapd0, configurei evictionHard.memory.available
para 800Mi
. O processo kswapd0 não atrapalhou mais.