Несоответствие использования памяти: cgroup memory.usage_in_bytes против RSS внутри контейнера докеров

«Kubernetes» (v1.10.2) говорит, что мой модуль (содержащий один контейнер) использует около 5 ГБ памяти. Внутри контейнера RSS говорит больше как 681MiB. Может ли anypony объяснить, как получить от 681 МБ до 5 ГБ со следующими данными (или описать, как восполнить разницу с помощью другой команды, которую я пропустил, либо из контейнера, либо из хоста докеров, на котором этот контейнер запущен в кубернетах)?

kubectl top pods говорит 5 ГБ:

% kubectl top pods -l app=myapp
NAME                             CPU(cores)   MEMORY(bytes)
myapp-56b947bf6d-2lcr7           39m          5039Mi

Cadvisor сообщает о том же числе (возможно, несколько в другое время, поэтому не обращайте внимания на небольшие различия):

container_memory_usage_bytes{pod_name=~".*myapp.*"}      5309456384

5309456384 / 1024.0 / 1024 ~= 5063 ~= 5039

Внутри контейнера этот файл, по-видимому, является тем местом, где cadvisor получает свои данные:

% kubectl exec -it myapp-56b947bf6d-2lcr7 bash
meme@myapp-56b947bf6d-2lcr7:/app# cat /sys/fs/cgroup/memory/memory.usage_in_bytes
5309456384

Размер резидентного набора (RSS) внутри контейнера НЕ совпадает (менее 1 ГБ):

meme@myapp-56b947bf6d-2lcr7:/app# kb=$(ps aux | grep -v grep | grep -v 'ps aux' | grep -v bash | grep -v awk | grep -v RSS | awk '{print $6}' | awk '{s+=$1} END {printf "%.0f", s}'); mb=$(expr $kb / 1024); printf "Kb: $kb\nMb: $mb\n"
Kb: 698076
Mb: 681

Полный ps aux на случай, если это будет полезно:

meme@myapp-56b947bf6d-2lcr7:/app# ps aux | grep -v grep | grep -v 'ps aux' | grep -v bash | grep -v awk
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
meme         1  0.0  0.0 151840 10984 ?        Ss   Jun04   0:29 /usr/sbin/apache2 -D FOREGROUND
www-data    10  0.0  0.0 147340  4652 ?        S    Jun04   0:00 /usr/sbin/apache2 -D FOREGROUND
www-data    11  0.0  0.0 148556  4392 ?        S    Jun04   0:16 /usr/sbin/apache2 -D FOREGROUND
www-data    12  0.2  0.0 2080632 11348 ?       Sl   Jun04  31:58 /usr/sbin/apache2 -D FOREGROUND
www-data    13  0.1  0.0 2080384 10980 ?       Sl   Jun04  18:12 /usr/sbin/apache2 -D FOREGROUND
www-data    68  0.3  0.0 349048 94272 ?        Sl   Jun04  47:09 hotapp
www-data   176  0.2  0.0 349624 92888 ?        Sl   Jun04  43:11 hotapp
www-data   179  0.2  0.0 349196 94456 ?        Sl   Jun04  42:20 hotapp
www-data   180  0.3  0.0 349828 95112 ?        Sl   Jun04  44:14 hotapp
www-data   185  0.3  0.0 346644 91948 ?        Sl   Jun04  43:49 hotapp
www-data   186  0.3  0.0 346208 91568 ?        Sl   Jun04  44:27 hotapp
www-data   189  0.2  0.0 350208 95476 ?        Sl   Jun04  41:47 hotapp

Раздел памяти из API статистики контейнера докеров:

curl --unix-socket /var/run/docker.sock 'http:/v1.24/containers/a45fc651e7b12f527b677e6a46e2902786bee6620484922016a135e317a42b4e/stats?stream=false' | jq . # yields:

"memory_stats": {
  "usage": 5327712256,
  "max_usage": 5368344576,
  "stats": {
    "active_anon": 609095680,
    "active_file": 74457088,
    "cache": 109944832,
    "dirty": 28672,
    "hierarchical_memory_limit": 5368709120,
    "inactive_anon": 1687552,
    "inactive_file": 29974528,
    "mapped_file": 1675264,
    "pgfault": 295316278,
    "pgmajfault": 77,
    "pgpgin": 85138921,
    "pgpgout": 84964308,
    "rss": 605270016,
    "rss_huge": 0,
    "shmem": 5513216,
    "total_active_anon": 609095680,
    "total_active_file": 74457088,
    "total_cache": 109944832,
    "total_dirty": 28672,
    "total_inactive_anon": 1687552,
    "total_inactive_file": 29974528,
    "total_mapped_file": 1675264,
    "total_pgfault": 295316278,
    "total_pgmajfault": 77,
    "total_pgpgin": 85138921,
    "total_pgpgout": 84964308,
    "total_rss": 605270016,
    "total_rss_huge": 0,
    "total_shmem": 5513216,
    "total_unevictable": 0,
    "total_writeback": 0,
    "unevictable": 0,
    "writeback": 0
  },
  "limit": 5368709120
},

Комментарий к утверждениям https://github.com/google/cadvisor/issues/638 :

Итого (memory.usage_in_bytes) = rss + кеш

https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt говорит:

usage_in_bytes: для эффективности, как и другие компоненты ядра, cgroup памяти использует некоторую оптимизацию, чтобы избежать ненужного ложного совместного использования строки кэша. Использование_in_bytes зависит от метода и не показывает «точное» значение использования памяти (и подкачки), это нечеткое значение для эффективного доступа. (Конечно, при необходимости он синхронизируется.) Если вы хотите узнать более точное использование памяти, вы должны использовать значение RSS + CACHE (+ SWAP) в memory.stat (см. 5.2).

https://docs.docker.com/engine/reference/commandline/stats/#parent-command говорит:

Примечание. В Linux интерфейс командной строки Docker сообщает об использовании памяти, вычитая использование кэша страницы из общего использования памяти. API не выполняет такие вычисления, а предоставляет общее использование памяти и объем кеша страниц, чтобы клиенты могли использовать данные по мере необходимости.

И действительно, большая часть материала в /sys/fs/cgroup/memory/memory.stat в контейнере отображается в приведенном выше ответе api docker stats (небольшие отличия связаны с взятием образцов в другое время, извините):

meme@myapp-56b947bf6d-2lcr7:/app# cat /sys/fs/cgroup/memory/memory.stat
cache 119492608
rss 607436800
rss_huge 0
shmem 5525504
mapped_file 1675264
dirty 69632
writeback 0
pgpgin 85573974
pgpgout 85396501
pgfault 296366011
pgmajfault 80
inactive_anon 1687552
active_anon 611213312
inactive_file 32800768
active_file 81166336
unevictable 0
hierarchical_memory_limit 5368709120
total_cache 119492608
total_rss 607436800
total_rss_huge 0
total_shmem 5525504
total_mapped_file 1675264
total_dirty 69632
total_writeback 0
total_pgpgin 85573974
total_pgpgout 85396501
total_pgfault 296366011
total_pgmajfault 80
total_inactive_anon 1687552
total_active_anon 611213312
total_inactive_file 32800768
total_active_file 81166336
total_unevictable 0

Информация о памяти от kubectl describe pod <pod>:

Limits:
  memory:  5Gi
Requests:
  memory:   4Gi

Вот что pmap говорит внутри контейнера. В этом однострочном файле я получаю все идентификаторы процессов, запускаю для них pmap -x и извлекаю столбец Kbytes из результатов pmap. Общий результат составляет 256 мегабайт (намного меньше, чем у RSS ps, я думаю, частично, потому что многие процессы не возвращают выходных данных pmap -x):

ps aux | awk '{print $2}' | grep -v PID | xargs sudo pmap -x | grep total | grep -v grep | awk '{print $3}' | awk '{s+=$1} END {printf "%.0f", s}'; echo
256820

ps_mem.py упоминается по адресу https://stackoverflow.com/a/133444/6090676. Он проверяет /proc/$pid/statm и /proc/$pid/smaps. Здесь нет подсветки (опять же, вроде игнорируются некоторые процессы):

# python ps_mem.py
Private  +   Shared  =  RAM used    Program

  1.7 MiB +   1.0 MiB =   2.7 MiB   apache2
  2.0 MiB +   1.0 MiB =   3.0 MiB   bash (3)
---------------------------------
                          5.7 MiB
=================================

Есть еще один вопрос, похожий на этот (но с меньшим количеством информации) на странице Неверный отчет об использовании памяти контейнера cadvisor. Спасибо!


person burnettk    schedule 14.06.2018    source источник
comment
$ bytes = $ (ps aux | grep -v grep | grep -v 'ps aux' | grep -v bash | grep -v awk | grep -v RSS | awk '{s + = $ 1} END {printf% .0f, s} '); мегабайты = $ (выражение $ байтов / 1024); printf bytes: $ bytes \ nmibibytes: $ megabytes \ n - Опубликованная вами команда должна вычислить сумму первого столбца, который является именем пользователя, но RSS стоит 6 долларов. Вы уверены, что рассчитали правильные значения?   -  person VASャ    schedule 15.06.2018
comment
ты прав, спасибо, поправили! Я опечатал команду при публикации в вопросе. числа в выводе команды были основаны на столбце 6 и верны.   -  person burnettk    schedule 15.06.2018
comment
Вы можете показать нам kubectl describe pod <pod>? Особенно любые настройки памяти, которые могут появиться.   -  person Robert    schedule 18.06.2018
comment
добавлено в конце вопроса!   -  person burnettk    schedule 18.06.2018
comment
возможно, это поможет: stackoverflow.com/questions/131303/   -  person gesellix    schedule 19.06.2018
comment
Какую версию Kubernetes вы используете? Я просто попытался воспроизвести это, но у меня это работает, как и ожидалось, с 1.10.   -  person Michael Hausenblas    schedule 21.06.2018
comment
Я использую Kubernetes v1.10.2. это происходит не со всеми нашими приложениями, но неясно, почему одни приложения демонстрируют этот симптом, а другие нет.   -  person burnettk    schedule 22.06.2018
comment
столкнувшись с той же проблемой, вы догадались   -  person shimron    schedule 22.03.2019
comment
нет. дайте мне знать. : D   -  person burnettk    schedule 22.03.2019


Ответы (3)


Одна вещь, которую я не видел, чтобы вы здесь проверяли, - это память ядра. Это также учитывается на рисунке memory.usage_in_bytes, но не отображается в memory.stat. Вы можете найти это, посмотрев на /sys/fs/cgroup/memory/memory.kmem.usage_in_bytes.

Однажды я видел похожую вещь, происходящую с одним из наших приложений ядра .NET, и я не мог понять, что именно происходит (возможно, утечка памяти в ядре .NET, поскольку это неуправляемая память, которую наше приложение не контролирует).

Возможно, для вас это очередная хлебная крошка. Это будет зависеть от вашего приложения, было ли это использование нормальным или нет, но с точки зрения контрольных групп я считаю, что использование памяти ядра по умолчанию не ограничено.

person Chris Gilbert    schedule 18.10.2018

Похоже, он использует VSZ, размер виртуальной памяти, а не RSS. Kubernetes видит это:

% kubectl top pods -l app=myapp
NAME                             CPU(cores)   MEMORY(bytes)
myapp-7b4b4f84f8-fxbns           39m          7136Mi

ps внутри контейнера при суммировании 5-го столбца (VSZ) говорит:

meme@myapp-7b4b4f84f8-fxbns:/app# kb=$(ps aux | grep -v grep | grep -v 'ps aux' | grep -v bash | grep -v awk | grep -v RSS | awk '{print $5}' | awk '{s+=$1} END {printf "%.0f", s}'); mb=$(expr $kb / 1024); printf "Kb: $kb\nMb: $mb\n"
Kb: 7032172
Mb: 6867

VSZ находится в районе 7 ГБ (не совсем совпадает, но близко), тогда как RSS сообщает 665 МБ, так что это заставляет меня поверить, что Kubernetes и /sys/fs/cgroup/memory/memory.usage_in_bytes используют что-то вроде VSZ, по крайней мере, в этом случае.

person burnettk    schedule 25.06.2018

Я не знаю, нашли ли вы свой ответ или нет, но позвольте мне дать вам некоторую информацию, которая может помочь.

  • cAdvisor извлекает множество показателей, связанных с памятью. Мы сосредоточимся на:

    1. container_memory_usage_bytes - ›получает использование памяти. Из файла memory.usage_in_bytes.

    2. container_memory_working_set_bytes - ›рассчитывается в cAdvisor. Это ‹= usage. Другими словами, usage = working_set_bytes + total_inactive_file

    3. container_memory_rss - ›равно total_rss из файла memory.state.

  • Теперь вы знаете, как собираются эти метрики, вам нужно знать, что когда вы используете команду kubectl top pods, вы получаете значение container_memory_working_set_bytes, а не usage метрики.

    так что из ваших ценностей:

    Рабочий набор 5039Mi для команды kubectl ~ = 5064 из файла memory.usage - 28 total_inactive_file из раздела Memory из API статистики контейнера Docker

  • Также стоит упомянуть, что когда значение container_memory_usage_bytes достигает пределов, ваш под НЕ будет убит. НО, если container_memory_working_set_bytes или container_memory_rss достигнут пределов, модуль будет убит.

person MohamedSaeed    schedule 24.07.2020
comment
учитывая working_set_bytes = memory_usage_in_bytes - total_inactive_file, то total_rss в любом случае должен быть частью memory_usage_in_bytes, насколько я понимаю. Значит, working_set_bytes должен быть единственной метрикой, о которой нужно заботиться в отношении убийств OOM? Также здесь описано: faun. pub / - person Daniel Föhr; 10.06.2021
comment
что произойдет, когда container_memory_usage_bytes достигнет предела? Влияние на производительность? или ничего? - person Salmaan P; 28.06.2021