Процесс номер 1 в контейнере

В системе Linux очень важную роль играет процесс с PID 1. После подъема контейнера, поскольку он придерживается принципа «один процесс на контейнер» или «одна вещь на контейнер», кто будет процессом 1 в контейнере в это время?Процесс нумерации — это вопрос, на который необходимо ответить.

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

1. Существует только один процесс — процесс номер 1.

2. Процесс №1 + все производное от него дерево процессов

Чтобы Docker мог остановить контейнер, когда он отправляет команду остановки, он по сути отправляет сигнал SIGTERM процессу № 1 в контейнере, а затем процесс № 1 завершается после получения сигнала. Если есть дочерние процессы, они также нужно выйти вместе.

Для случая 1 ничего страшного, процесс всего 1, а мотыльков не так уж и много. Для случая 2, если процесс № 1 может точно передать сигнал остановки всем дочерним процессам и может успешно завершить все дерево процессов, это нормально.

Проблема в:

1. У многих людей команды запуска контейнера запускаются с помощью сценариев оболочки (теперь вы можете войти в бизнес-контейнер и использовать ps, чтобы увидеть дерево процессов)

2. Многие сценарии оболочки не используют форму exec, рекомендованную Docker.

Это ведет к:

1. Процесс bash на самом деле является процессом № 1 в контейнере, а ваш бизнес-процесс на самом деле является дочерним процессом bash.

2. Процесс bash не может пересылать сигнал.

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

Какие проблемы это вызывает?

Предположения:

1. Бизнес-процесс зарегистрируется в каком-то регистрационном центре (это не слишком частое явление, регистрация услуги в принципе стандартная конфигурация)

2. K8S управляет оркестрацией и планированием контейнеров. В контексте K8S контейнер будет уничтожен или перезапущен в любое время. Kill - это не что иное, как команда для вызова базового механизма контейнера (не только K8S, но и других контейнеров). инструменты оркестрации) аналогичные вопросы)

Результат: если вы хотите отключить службу, используйте K8S, уничтожьте соответствующий контейнер, а затем вернитесь. Поскольку ваша команда запуска обернута оболочкой, bash является процессом № 1 и не может пересылать сигнал завершения бизнес-процессу, поэтому бизнес-процессу в контейнере необходимо дождаться истечения времени ожидания, прежде чем его принудительно остановить ( с вашим "процесс завершается немедленно" ожидания не совпадают), поэтому сервис, который хочет выйти в офлайн, не может находиться в оффлайне от центра регистрации в течение длительного времени.

Как это решить?

Есть несколько вариантов:

1. Используйте форму Shell exec, чтобы сделать свой бизнес-процесс процессом №1. PS: Вы можете посмотреть, как написан docker-entrypoint.sh Redis или MySQL.

2. Используйте такой инструмент, как Tini или Dum-Tini, в качестве процесса № 1, реализующего функцию пересылки. PS: в немом-тини еще есть косточки, можно поискать в интернете. Аналогично можно увидеть, как пишется скрипт запуска Дженкинса.

Среди них вариант 1 является лучшим.

mysql/8.0 по адресу 223f0be1213bbd8647b841243a3114e8b34022f4 · docker-library/mysql · GitHub

Guess you like

Origin blog.csdn.net/chuixue24/article/details/132181602