2016-10-08 5 views
5

Существует несколько процессов, выполняющихся в контейнере Docker, их PID изолированы в пространстве имен контейнеров, есть ли способ выяснить, каковы их PID на хосте Docker?Что такое PID в хосте, процесс, выполняющийся внутри контейнера Docker?

Например, есть веб-сервер Apache, запущенный внутри контейнера Docker, (я использую образ Apache + PHP от Docker Hub), и Apache при его запуске создает больше рабочих процессов внутри контейнера. Эти рабочие процессы фактически обрабатывают входящие запросы. Для просмотра этих процессов я бегу pstree внутри контейнера DOCKER:

# pstree -p 1 
apache2(1)-+-apache2(8) 
      |-apache2(9) 
      |-apache2(10) 
      |-apache2(11) 
      |-apache2(12) 
      `-apache2(20) 

Родительский процесс Apache работает на PID 1 внутри пространства имен процесса контейнера. Однако с точки зрения хозяина, можно также получить доступ, но его PID на хосте отличается и может быть определена путем запуска docker compose команды:

$ docker inspect --format '{{.State.Pid}}' container 
17985 

Из этого мы можем видеть, что PID 1 внутри процесса контейнера пространство имен сопоставляется с PID 17985 на хосте. Так что я могу запустить pstree на хосте, чтобы перечислить детей процесса Apache:

$ pstree -p 17985 
apache2(17985)─┬─apache2(18010) 
       ├─apache2(18011) 
       ├─apache2(18012) 
       ├─apache2(18013) 
       ├─apache2(18014) 
       └─apache2(18164) 

Из этого я предполагаю, что точно так же, как PID 1 в контейнере карты для PID 17985 на хосте, он также отображает :

  • ПИД-8 в контейнере с PID 18010 на хосте, и
  • PID 9 PID 18011;
  • PID 10 для PID 18012 и так далее ...

(Это позволяет мне отладить процессы из Докер контейнера, с помощью инструментов, которые доступны только только на хосте, а не в контейнере , как strace)

Проблема в том, что я не знаю, насколько безопасно предположить, что pstree перечисляет процессы в том же порядке как в контейнере, так и в хосте.

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

+0

ИОКи может также означать OS Темы, по крайней мере, линукс. Вы можете проверить с помощью java (или другого языка), создав несколько потоков и считая PIDS, которые вы получаете. – ieugen

ответ

11

Вы можете посмотреть файл /proc/<pid>/status, чтобы определить соответствие между ПИД-идентификатором пространства имен и глобальным PID. Например, если в Докер контейнере я начинаю несколько sleep 900 процессов, например:

# docker run --rm -it alpine sh 
/# sleep 900 & 
/# sleep 900 & 
/# sleep 900 & 

Я могу видеть, что они работают в контейнере:

/ # ps -fe 
PID USER  TIME COMMAND 
    1 root  0:00 sh 
    7 root  0:00 sleep 900 
    8 root  0:00 sleep 900 
    9 root  0:00 sleep 900 
    10 root  0:00 ps -fe 

Я могу смотреть на них на хосте:

# ps -fe | grep sleep 
root  10394 10366 0 09:11 pts/10 00:00:00 sleep 900 
root  10397 10366 0 09:12 pts/10 00:00:00 sleep 900 
root  10398 10366 0 09:12 pts/10 00:00:00 sleep 900 

И для любого из тех, что я могу посмотреть на файл status, чтобы увидеть пространство имен PID:

# grep -i pid /proc/10394/status 
Pid: 10394 
PPid: 10366 
TracerPid: 0 
NSpid: 10394 7 

Посмотрите на строку NSpid, я вижу, что в пространстве имен PID этот процесс имеет pid 7.И в самом деле, если я убью процесс 10394 на хосте:

# kill 10394 

Затем в контейнере я не вижу, что PID 7 больше не работает:

/ # ps -fe 
PID USER  TIME COMMAND 
    1 root  0:00 sh 
    8 root  0:00 sleep 900 
    9 root  0:00 sleep 900 
    11 root  0:00 ps -fe 
+2

Похоже, что он решает мою проблему, следуя этим советам, я могу получить полное отображение PID с помощью этого однострочного интерфейса: 'for i in $ (ps -ef | grep $ (docker inspect --format '{{.State.Pid} } 'php-sandbox) | awk' {print $ 2} '); do grep NSpid:/proc/$ i/status; done' –