Mémoire dédiée au foyer et intervention OOM Killer

Bonjour encore! La traduction de l'article suivant a été préparée spécialement pour les étudiants du cours sur la plate-forme d'infrastructure basée sur Kubernetes , qui commence déjà ce mois-ci.



Ces derniers jours, certains de mes pods se sont constamment écrasés, laissant un enregistrement dans le journal système de l'OS que OOM Killer a détruit le processus de conteneur. J'ai décidé de comprendre pourquoi cela se produit.

Limite de mémoire du foyer et paramètres de mémoire de cgroup


Essayons sur la distribution K3s. Nous créons sous avec une limite de mémoire caractéristique de 123 MiB (123 Mi).

kubectl run --restart=Never --rm -it --image=ubuntu --limits='memory=123Mi' -- sh If you don't see a command prompt, try pressing enter. root@sh:/# 

Dans une autre console, découvrez le uid foyer.

 kubectl get pods sh -o yaml | grep uid uid: bc001ffa-68fc-11e9-92d7-5ef9efd9374c 

Sur le serveur sur lequel il s'exécute, nous découvrons les paramètres de cgroup en spécifiant l' uid pod souhaité.

 cd /sys/fs/cgroup/memory/kubepods/burstable/podbc001ffa-68fc-11e9-92d7-5ef9efd9374c cat memory.limit_in_bytes 128974848 

128974848 est exactement 123 Mio (123 * 1024 * 1024). La situation s'améliore. Il s'avère que dans Kubernetes, la limite de mémoire est définie via cgroup. Dès que la limite de mémoire allouée augmente, cgroup lance la destruction du processus de conteneur.

Test d'effort


Installons des utilitaires pour tester la résistance du foyer via une session de console de commande ouverte.

 root@sh:/# apt update; apt install -y stress 

Dans le même temps, nous dmesg -Tw entrées syslog avec la dmesg -Tw .

Tout d'abord, exécutez l'utilitaire de test de stress en allouant 100 Mo de mémoire. Le processus a démarré avec succès.

 root@sh:/# stress --vm 1 --vm-bytes 100M & [1] 271 root@sh:/# stress: info: [271] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd 

Nous allons maintenant effectuer le deuxième test de résistance.

 root@sh:/# stress --vm 1 --vm-bytes 50M stress: info: [273] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd stress: FAIL: [271] (415) <-- worker 272 got signal 9 stress: WARN: [271] (417) now reaping child worker processes stress: FAIL: [271] (451) failed run completed in 7s 

Le lancement a conduit à la destruction instantanée du processus du premier test de résistance (PID 271) au signal 9.

Pendant ce temps, les entrées suivantes sont apparues dans le journal système:

[Sat Apr 27 22:56:09 2019] stress invoked oom-killer: gfp_mask=0x14000c0(GFP_KERNEL), nodemask=(null), order=0, oom_score_adj=939
[Sat Apr 27 22:56:09 2019] stress cpuset=a2ed67c63e828da3849bf9f506ae2b36b4dac5b402a57f2981c9bdc07b23e672 mems_allowed=0
[Sat Apr 27 22:56:09 2019] CPU: 0 PID: 32332 Comm: stress Not tainted 4.15.0-46-generic #49-Ubuntu
[Sat Apr 27 22:56:09 2019] Hardware name: BHYVE, BIOS 1.00 03/14/2014
[Sat Apr 27 22:56:09 2019] Call Trace:
[Sat Apr 27 22:56:09 2019] dump_stack+0x63/0x8b
[Sat Apr 27 22:56:09 2019] dump_header+0x71/0x285
[Sat Apr 27 22:56:09 2019] oom_kill_process+0x220/0x440
[Sat Apr 27 22:56:09 2019] out_of_memory+0x2d1/0x4f0
[Sat Apr 27 22:56:09 2019] mem_cgroup_out_of_memory+0x4b/0x80
[Sat Apr 27 22:56:09 2019] mem_cgroup_oom_synchronize+0x2e8/0x320
[Sat Apr 27 22:56:09 2019] ? mem_cgroup_css_online+0x40/0x40
[Sat Apr 27 22:56:09 2019] pagefault_out_of_memory+0x36/0x7b
[Sat Apr 27 22:56:09 2019] mm_fault_error+0x90/0x180
[Sat Apr 27 22:56:09 2019] __do_page_fault+0x4a5/0x4d0
[Sat Apr 27 22:56:09 2019] do_page_fault+0x2e/0xe0
[Sat Apr 27 22:56:09 2019] ? page_fault+0x2f/0x50
[Sat Apr 27 22:56:09 2019] page_fault+0x45/0x50
[Sat Apr 27 22:56:09 2019] RIP: 0033:0x558182259cf0
[Sat Apr 27 22:56:09 2019] RSP: 002b:00007fff01a47940 EFLAGS: 00010206
[Sat Apr 27 22:56:09 2019] RAX: 00007fdc18cdf010 RBX: 00007fdc1763a010 RCX: 00007fdc1763a010
[Sat Apr 27 22:56:09 2019] RDX: 00000000016a5000 RSI: 0000000003201000 RDI: 0000000000000000
[Sat Apr 27 22:56:09 2019] RBP: 0000000003200000 R08: 00000000ffffffff R09: 0000000000000000
[Sat Apr 27 22:56:09 2019] R10: 0000000000000022 R11: 0000000000000246 R12: ffffffffffffffff
[Sat Apr 27 22:56:09 2019] R13: 0000000000000002 R14: fffffffffffff000 R15: 0000000000001000
[Sat Apr 27 22:56:09 2019] Task in /kubepods/burstable/podbc001ffa-68fc-11e9-92d7-5ef9efd9374c/a2ed67c63e828da3849bf9f506ae2b36b4dac5b402a57f2981c9bdc07b23e672 killed as a result of limit of /kubepods/burstable/podbc001ffa-68fc-11e9-92d7-5ef9efd9374c
[Sat Apr 27 22:56:09 2019] memory: usage 125952kB, limit 125952kB, failcnt 3632
[Sat Apr 27 22:56:09 2019] memory+swap: usage 0kB, limit 9007199254740988kB, failcnt 0
[Sat Apr 27 22:56:09 2019] kmem: usage 2352kB, limit 9007199254740988kB, failcnt 0
[Sat Apr 27 22:56:09 2019] Memory cgroup stats for /kubepods/burstable/podbc001ffa-68fc-11e9-92d7-5ef9efd9374c: cache:0KB rss:0KB rss_huge:0KB shmem:0KB mapped_file:0KB dirty:0KB writeback:0KB inactive_anon:0KB active_anon:0KB inactive_file:0KB active_file:0KB unevictable:0KB
[Sat Apr 27 22:56:09 2019] Memory cgroup stats for /kubepods/burstable/podbc001ffa-68fc-11e9-92d7-5ef9efd9374c/79fae7c2724ea1b19caa343fed8da3ea84bbe5eb370e5af8a6a94a090d9e4ac2: cache:0KB rss:48KB rss_huge:0KB shmem:0KB mapped_file:0KB dirty:0KB writeback:0KB inactive_anon:0KB active_anon:48KB inactive_file:0KB active_file:0KB unevictable:0KB
[Sat Apr 27 22:56:09 2019] Memory cgroup stats for /kubepods/burstable/podbc001ffa-68fc-11e9-92d7-5ef9efd9374c/a2ed67c63e828da3849bf9f506ae2b36b4dac5b402a57f2981c9bdc07b23e672: cache:0KB rss:123552KB rss_huge:0KB shmem:0KB mapped_file:0KB dirty:0KB writeback:0KB inactive_anon:0KB active_anon:123548KB inactive_file:0KB active_file:0KB unevictable:0KB
[Sat Apr 27 22:56:09 2019] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name
[Sat Apr 27 22:56:09 2019] [25160] 0 25160 256 1 28672 0 -998 pause
[Sat Apr 27 22:56:09 2019] [25218] 0 25218 4627 872 77824 0 939 bash
[Sat Apr 27 22:56:09 2019] [32307] 0 32307 2060 275 57344 0 939 stress
[Sat Apr 27 22:56:09 2019] [32308] 0 32308 27661 24953 253952 0 939 stress
[Sat Apr 27 22:56:09 2019] [32331] 0 32331 2060 304 53248 0 939 stress
[Sat Apr 27 22:56:09 2019] [32332] 0 32332 14861 5829 102400 0 939 stress
[Sat Apr 27 22:56:09 2019] Memory cgroup out of memory: Kill process 32308 (stress) score 1718 or sacrifice child
[Sat Apr 27 22:56:09 2019] Killed process 32308 (stress) total-vm:110644kB, anon-rss:99620kB, file-rss:192kB, shmem-rss:0kB
[Sat Apr 27 22:56:09 2019] oom_reaper: reaped process 32308 (stress), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB


Le processus avec PID 32308 sur l'hôte a été détruit en raison d'une mémoire insuffisante (MOO). Mais la chose la plus intéressante est cachée à la fin des entrées de journal:



Voici les processus de ce foyer qui sont marqués comme candidats à la destruction par le composant OOM Killer. Le processus de pause base, qui stocke les espaces de noms du réseau, a reçu un score oom_score_adj de -998 , ce qui signifie que le processus ne sera pas détruit. Les processus restants dans le conteneur ont reçu un score oom_score_adj de 939 . Vous pouvez vérifier cette valeur en utilisant la formule de la documentation Kubernetes ci-dessous:

 min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999) 

Nous découvrons la quantité de mémoire disponible pour le nœud:

 kubectl describe nodes k3s | grep Allocatable -A 5 Allocatable: cpu: 1 ephemeral-storage: 49255941901 hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 2041888Ki 

Si la taille de mémoire demandée n'est pas spécifiée, elle sera par défaut égale à la limite. En substituant les valeurs, nous obtenons la valeur oom_score_adj suivante: 1000–123*1024/2041888=938.32 , ce qui est très proche de la valeur 939 spécifiée dans le journal système. (Je ne sais pas comment OOM Killer obtient la valeur exacte de 939.)

Ainsi, tous les processus du conteneur ont la même valeur oom_score_adj. Le composant OOM Killer calcule la valeur OOM en fonction de l'utilisation de la mémoire et ajuste le résultat en fonction du score oom_score_adj. Et, finalement, il détruit le processus du premier test de stress, qui a consommé la majeure partie de la mémoire, 100 Mo, ce qui correspond à l'estimation oom_score = 1718.

Conclusion


Kubernetes contrôle la limite de mémoire de l'âtre via les composants cgroup et OOM Killer. Il est nécessaire de convenir soigneusement des conditions du système d'exploitation MOO et des foyers MOO.

Comment aimez-vous le matériel? Tous ceux qui veulent en savoir plus sur le cours sont invités à un webinaire gratuit le 17 juin, où nous étudierons les capacités de Kubernetes pour organiser des pratiques de livraison continue (CI / CD) et des approches pour une petite équipe avec plusieurs applications, ainsi que pour une grande organisation avec un grand nombre de systèmes.

Source: https://habr.com/ru/post/fr456002/


All Articles