В системе 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