Поделиться через


Сбор диагностики в контейнерах Linux

Те же средства диагностики, которые полезны для диагностики проблем .NET в других сценариях, также работают в контейнерах. Средства можно запускать в том же контейнере, что и целевой процесс, из хоста или из контейнера-поддержки.

Использование средств .NET CLI в контейнере

Эти средства применяются: ✔️ пакет SDK .NET Core 3.1 и более поздние версии

Все средства диагностики dotnet-* CLI могут работать при выполнении в одном контейнере с приложением, которое они проверяют, однако следует остерегаться следующих потенциально проблемных моментов:

  • Инструменты, работающие внутри контейнера, будут подчиняться ограничениям ресурсов контейнера. Средства могут выполняться медленно или завершать сбой, если ограничения ресурсов слишком низки. Большинство средств имеют скромные требования, но dotnet-dumpdotnet-gcdump могут использовать значительные объемы памяти и дискового пространства при выборе процесса с большим объемом памяти. dotnet-trace и dotnet-counters могут также создавать большие файлы, если они настроены на запись большого количества событий трассировки или данных временных рядов метрик.
  • dotnet-dump приведет к выполнению вспомогательного процесса, требующего разрешений ptrace. Linux имеет множество параметров конфигурации безопасности, которые могут повлиять на то, успешно ли это происходит в некоторых случаях, может потребоваться настроить конфигурацию безопасности контейнера. Подробные рекомендации по диагностике привилегий безопасности см. в разделе "Часто задаваемые вопросы о дампах".
  • При запуске средств внутри контейнера можно заранее установить их при создании контейнера или скачать их по запросу. Установка их заранее упрощает последующее использование, когда они нужны, однако увеличивает размер контейнера и создает большую поверхность атаки, которую злоумышленники могут попытаться использовать.

Использование инструментов командной строки .NET в контейнере-сайдкаре или на узле хоста.

Средства диагностики dotnet-* CLI также поддерживают запуск с хоста или в контейнере в виде боковины. Это в основном позволяет избежать ограничений по размеру, безопасности и ресурсам, связанных с одновременной работой в одном контейнере, однако есть дополнительные требования для успешной работы с инструментами.

Определение целевого процесса для проверки с помощью средств --process-id или --name с использованием аргументов командной строки требует:

  1. Контейнеры должны совместно использовать пространство имен процесса , чтобы средства в контейнере бокового контейнера могли получать доступ к процессам в целевом контейнере.
  2. Средства нуждаются в доступе к диагностическому сокету Unix Domain, который среда выполнения .NET записывает в каталог /tmp. Поэтому каталог /tmp должен быть общим между целевым и вспомогательным контейнером через подключение тома. Например, для этого контейнеры должны совместно использовать общий том или том Kubernetes emptyDir. Если вы пытаетесь использовать средства диагностики из побочного контейнера без общего доступа к каталогу /tmp, вы получите ошибку о том, что "среда выполнения .NET не совместима".

Если вы не хотите предоставлять общий доступ к пространству имен процесса и каталогу /tmp , многие из средств также поддерживают более расширенный --diagnostic-port параметр командной строки. Это позволяет напрямую указать путь к порту диагностики целевого процесса в файловой системе узла или сайдкара. Каталог /tmp целевого контейнера должен быть сопоставлен в каком-либо месте, чтобы этот путь существовал, но его не обязательно делить с хостом или сайдкаром /tmp.

Примечание.

Даже при запуске средств диагностики из узла или бокового контейнера целевой процесс может по-прежнему запрашиваться для выполнения работы, что увеличивает его использование ресурсов внутри целевого контейнера. Мы заметили, что dotnet-dump может привести к значительному использованию виртуальной памяти целевым процессом при сборе дампа. Другие инструменты могут вызвать менее значительное воздействие, хотя на практике мы не наблюдали, чтобы они вызывали проблемы. Например, dotnet-trace запрашивает целевой процесс выделения буфера событий и dotnet-counters запрашивает небольшую область памяти, в которой агрегируются данные метрик. Мы рекомендуем провести тестирование, чтобы ограничения памяти не были столь строгими, чтобы выполнение инструментов приводило к прекращению работы операционной системы.

Примечание.

Во время dotnet-dump записи файла дампа на диск выходной путь интерпретируется в контексте представления файловой системы целевым процессом. Это может отличаться от контейнера хоста или контейнера-помощника.

Используйте PerfCollect в контейнере

Область применения: ✔️ .NET Core 2.1 и более поздних версий

Скрипт PerfCollect полезен для сбора трассировок производительности, содержащих события ядра, такие как сэмплы ЦП или переключения контекста. При использовании PerfCollect в контейнере учитывайте следующие требования:

  • PerfCollect требует дополнительных возможностей perf для запуска средства. Минимальный набор необходимых возможностей — PERFMON и SYS_PTRACE. Для некоторых сред требуется SYS_ADMIN. Обязательно запустите контейнер с необходимыми возможностями. Если минимальный набор не работает, попробуйте использовать полный набор.

  • PerfCollect требует, чтобы некоторые переменные среды были заданы до начала профилирования приложения. Их можно задать в Dockerfile или при запуске контейнера. Так как эти переменные не должны задаваться в обычных рабочих средах, как правило, они добавляются при запуске контейнера для профилирования. Для PerfCollect необходимы следующие две переменные.

    • DOTNET_PerfMapEnabled=1
    • DOTNET_EnableEventLog=1

Примечание.

При выполнении приложения с помощью .NET 7 необходимо также задать DOTNET_EnableWriteXorExecute=0 в дополнение к предыдущим переменным среды.

Примечание.

.NET 6 стандартизует префикс DOTNET_ вместо COMPlus_ для переменных среды, которые настраивают поведение .NET во время выполнения. Но префикс COMPlus_ будет и дальше работать. Если вы используете предыдущую версию среды выполнения .NET, следует и дальше использовать префикс COMPlus_ для переменных среды.

Используйте PerfCollect в контейнере-сайдкаре

Если вы хотите запустить PerfCollect в одном контейнере для профилирования процесса .NET в другом контейнере, интерфейс почти такой же. Различия описаны ниже.

  • Переменные среды, упомянутые ранее (DOTNET_PerfMapEnabled и DOTNET_EnableEventLog), нужно установить для целевого контейнера (а не для того, в котором выполняется PerfCollect).
  • Контейнер, в котором выполняется PerfCollect, должен обладать возможностью SYS_ADMIN (не целевой контейнер).
  • Два контейнера должны совместно использовать пространство имен процесса.