Что такое PID в хосте, процесс, выполняющийся внутри контейнера Docker?
Есть несколько процессов, выполняемых в контейнере Docker, их PID изолированы в пространстве имен контейнеров, есть ли способ выяснить, каковы их PID на хосте Docker?
Например, веб-сервер Apache работает внутри контейнера Docker (я использую Apache + PHP-образ из Docker Hub), а Apache при его запуске создает больше рабочих процессов внутри контейнера. Эти рабочие процессы фактически обрабатывают входящие запросы. Чтобы просмотреть эти процессы, я запускаю pstree
внутри контейнера pstree
:
# 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
на хосте, чтобы pstree
процесса Apache:
$ pstree -p 17985
apache2(17985)─┬─apache2(18010)
├─apache2(18011)
├─apache2(18012)
├─apache2(18013)
├─apache2(18014)
└─apache2(18164)
Из этого я предполагаю, что так же, как PID 1 в контейнере сопоставляется с PID 17985 на хосте, он также отображает:
- PID 8 в контейнере до PID 18010 на хосте и
- PID 9 - PID 18011;
- PID 10 до PID 18012 и так далее...
(Это позволяет мне отлаживать процессы из контейнера докеров, используя инструменты, доступные только на хосте, а не в контейнере, например, strace)
Проблема в том, что я не знаю, насколько безопасно предположить, что pstree перечисляет процессы в том же порядке как в контейнере, так и в хосте.
Было бы здорово, если бы кто-то мог предложить более надежный способ определить, что такое PID на узле конкретного процесса, запущенного внутри контейнера Docker.
Ответы
Ответ 1
Вы можете посмотреть файл /proc/<pid>/status
чтобы определить сопоставление между PID пространства имен и глобальным 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