2015-06-23 2 views
2

Моя цель - следить за тем, какие порты открыты и закрыты многопроцессорным приложением. Мой план заключается в том, чтобы запустить приложение в контейнере Docker, чтобы его изолировать, а затем использовать strace, чтобы сообщить о активности приложения.strace для мониторинга активности приложения доксеризованного приложения

Я попытался с сервером Apache dockerized:

strace -f -o /tmp/docker.out docker run -D -P apache 

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

Может ли strace сообщать о деятельности процессов внутри контейнера?

ответ

0

попытайтесь запустить Apache docker run -D -P apache и подключите внутри docker exec -it container_id bash, а затем strace ваш процесс Apache.

+1

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

4

Проблема с командой + комбинации Трассирование является то, что Докер имеет модель клиент/сервер, и ваш docker run представляет клиентскую сторону сделки REST API, чтобы задать Docker демон запустить контейнер Apache от вашего имени. В зависимости от того, как настроен ваш клиент, этот контейнер может даже не работать в той же системе, на которой вы вводите команду docker run.

Однако, чтобы взять простейший случай, когда клиент и демон Docker находятся в одной и той же системе, вы можете использовать ps найти PID работающего сервера Apache и использовать strace для соединения и отслеживания уже начатого процесса поскольку этого достаточно для ваших потребностей отслеживания.

Учитывая, что мне пришлось отлаживать некоторые проблемы с ранним запуском с помощью «runc», исполнителя для контейнеров в докерной версии 1.11 и выше, я также создал небольшую обертку для docker-runc, которая с самого начала запускает контейнерный процесс strace (извне системы, поэтому в файловой системе контейнера не требуется strace). Вы можете найти его here on GitHub, хотя справедливое предупреждение о том, что он несколько глючит для регулярного использования, так как я полагаю, что вызов shell + strace мешает некоторой сигнализации между containerd и реальным docker-runc и связанными с ним процессами. Более элегантным решением может быть создание варианта runc, который знает, как добавить фактическое начало содержащегося процесса с помощью оболочки strace, а не перехватывать весь вызов runc в strace.

1

Я только успел Трассирование грузчика контейнера, выполнив следующие действия:

  1. Разработайте какой дистрибутив изображение контейнера, основанное на, то получит strace бинарных из этого дистрибутива, например, путем установки соответствующего дистрибутивного пакета из контейнера, созданного для этой цели.

  2. Скопируйте двоичный файл strace в том, который вы можете установить в контейнер.

  3. Также создайте небольшой скрипт оболочки оболочки, который называется entry.sh, который содержит ваш вызов strace. В моем случае я написал это так:

    #!/bin/sh 
    exec /path/to/strace -ff -o /path/to/dumps /bin/bash /original/entrypoint 
    

    Это предполагает, что исходная точка входа, которую вы читали из Dockerfile изображения вы хотите отлаживать, начал с #!/bin/bash. Убедитесь, что вы установили бит выполнения этого скрипта и поместите его там, где вы также разместили двоичный файл strace.

  4. Launch докер, используя команду:

    docker run -v $PWD/shared:/path/to \ 
          --entrypoint="/path/to/entry.sh" \ 
          --cap-add SYS_PTRACE \ 
          image-name 
    

Смонтированный объем составит доступный strace и entry.sh внутри грузчиком. Точка входа вызовет вызов strace, прежде чем вызывать фактическую точку входа. Это может вызвать некоторые проблемы с самим strace, становящимися pid 1 в контейнере и неспособными пожинать детей. Если это проблема, другой подход, подобный предложенному Филом, будет лучше. Наконец, добавленная возможность сообщает докере, что начать процессы трассировки можно. В противном случае вы получите сообщения об ошибках, такие как

strace: …: PTRACE_TRACEME doesn't work: Operation not permitted 

Фактически указывая на эту возможность настройки, я пишу свой ответ. Я уже делал шаги, кроме этого флага, и при поиске решения там я нашел здесь и этот вопрос и a blog post by John Goulah, содержащий этот бит информации. Ради полноты я думаю, что здесь должен упоминаться и флаг. Еще не пробовал подход Фила, поэтому я определенно не утверждаю, что мой подход превосходит то, что он предложил. Я думаю, это может сработать легче в системах, где вы не хотите возиться с демоном докеров.

0

Посмотрите на решение, описанное в https://medium.com/@rothgar/how-to-debug-a-running-docker-container-from-a-separate-container-983f11740dc6, в котором описано, как запустить контейнер с установленным strace, который находится в том же пространстве имен pid и network, что и контейнер/процесс, с которым вы хотите работать.

Это хорошо, поскольку это означает, что вам не нужно устанавливать strace в контейнер, который вы хотите отлаживать.

кишках него является то, что при отладке контейнера (caddy в примере ниже) вы запускаете Docker контейнер под названием Трассирование и с соответствующими инструментами установлены:

докер запуска -t --pid = контейнер: кэдди \ --net = контейнер: кэдди \ --cap добавьте sys_admin \ --cap добавьте sys_ptrace \ трассированием

Предполагая, что вы делаете это так при создании вашего Strace контейнера, вы теперь имеют оболочку с соответствующие инструменты, из которых вы можете запустить ps и посмотреть процесс в caddy контейнер, и вы можете запустить strace против него.

Вы будете находиться в другом контейнере с другой файловой системой, но вы можете увидеть файловое пространство целевого контейнера по адресу /prof/$PID/root.