Как стать автором
Обновить
858.82
OTUS
Цифровые навыки от ведущих экспертов

Выделенная память подов и вмешательство OOM Killer

Время на прочтение5 мин
Количество просмотров6.8K
Автор оригинала: Чжиминь Вэнь (Zhimin Wen)
И снова здравствуйте! Перевод следующей статьи подготовлен специально для студентов курса «Инфраструктурная платформа на основе Kubernetes», который запускается уже в этом месяце Начнем.



В последние дни некоторые из моих подов постоянно аварийно завершали работу, оставляя в системном журнале ОС запись о том, что OOM Killer уничтожил процесс контейнера. Я решил разобраться, почему это происходит.

Лимит памяти подов и параметры памяти cgroup


Проведем тест на дистрибутиве K3s. Создаем под с характерным лимитом памяти — 123 МиБ (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:/# 

В другой консоли выясняем uid пода.

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

На сервере, где выполняется под, узнаем параметры cgroup, указав uid нужного пода.

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

128974848 — это ровно 123 МиБ (123*1024*1024). Ситуация проясняется. Выходит, в Kubernetes лимит памяти задается через cgroup. Как только под разрастется больше отведенного лимита памяти, cgroup инициирует уничтожение процесса контейнера.

Стресс-тест


Давайте установим утилиты для стресс-тестирования пода через открытый сеанс командной консоли.

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

В то же время будем отслеживать записи системного журнала командой dmesg -Tw.

Сначала запустим утилиту стресс-тестирования, выделив ей в памяти 100 МБ. Процесс запустился успешно.

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

Теперь проведем второй стресс-тест.

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

Запуск привел к мгновенному уничтожению процесса первого стресс-теста (PID 271) по сигналу 9.

Тем временем в системном журнале появились такие записи:

[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


Процесс с PID 32308 на хосте уничтожен в связи с нехваткой памяти (OOM). Но самое интересное скрывается в конце журнальных записей:



Здесь указаны процессы этого пода, которые отмечены как кандидаты на уничтожение компонентом OOM Killer. Базовый процесс pause, в котором хранится пространство сетевых имен (network namespaces), получил оценку oom_score_adj в -998, то есть процесс гарантированно не будет уничтожен. Остальные процессы в контейнере получили оценку oom_score_adj в 939. Можно проверить это значение, воспользовавшись формулой из документации Kubernetes, приведенной ниже:

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

Выясняем объем памяти, доступной узлу:

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

Если объем запрашиваемой памяти не указан, по умолчанию он будет равен лимиту. Подставив значения, мы получаем следующее значение oom_score_adj: 1000–123*1024/2041888=938.32, что очень близко к значению 939, указанному в системном журнале. (Не знаю, каким образом OOM Killer получает точное значение 939.)

Итак, все процессы в контейнере обладают одинаковым значением oom_score_adj. Компонент OOM Killer рассчитывает значение OOM, исходя из использования памяти, и корректирует результат с учетом оценки oom_score_adj. И, в конечном счете, он уничтожает процесс первого стресс-теста, который отъел большую часть памяти, 100 МБ, что соответствует оценке oom_score = 1718.

Заключение


Kubernetes контролирует лимит памяти подов через параметры cgroup и компонент OOM Killer. Необходимо внимательно согласовывать условия OOM операционной системы и OOM подов.

Как вам материал? Всех, кто желает подробнее узнать о курсе, приглашаем 17 июня на бесплатный вебинар, где изучим возможности Kubernetes для организации практики непрерывной поставки (CI/CD) и подходы как для небольшой команды с несколькими приложениями, так и для большой организации с большим количеством систем.
Теги:
Хабы:
+8
Комментарии3

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS