Zbudowałem podstawowy obraz z Dockerfile o nazwie centos + ssh. W Dockerfile centos + ssh używam CMD do uruchamiania usługi ssh.
Następnie chcę zbudować obraz i uruchomić inną usługę o nazwie rabbitmq, plik Dockerfile:
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD /opt/mq/sbin/rabbitmq-server start
Aby uruchomić pojemnik RabbitMQ , Uruchom :
docker run -d -p 222:22 -p 4149:4149 rabbitmq
ale usługa ssh nie działa, wyczuwa, że plik CMD rabbitmq zastępuje CMD centos.
- Jak działa CMD w obrazie dockera?
- Jeśli chcę uruchomić wiele usług, jak to zrobić? Korzystasz z przełożonego?
Masz rację, drugi plik Dockerfile nadpisze
CMD
polecenie pierwszego. Docker zawsze uruchamia jedno polecenie, nie więcej. Na końcu pliku Dockerfile możesz określić jedno polecenie do uruchomienia. Nie więcej.Ale możesz wykonać oba polecenia w jednej linii:
Co możesz również zrobić, aby uczynić plik Dockerfile nieco czystszym, możesz umieścić swoje polecenia CMD w dodatkowym pliku:
I taki plik:
źródło
&&
technika zadziała tylko z usługami nieinteraktywnymi (które mogą być uruchamiane w tle), w przeciwnym razie tylko pierwsza będzie działać.Chociaż szanuję odpowiedź qkrijgera wyjaśniającą, jak możesz obejść ten problem, myślę, że możemy dowiedzieć się o wiele więcej o tym, co się tutaj dzieje ...
Aby właściwie odpowiedzieć na pytanie „ dlaczego ” ... Myślę, że byłoby pomocne, gdybyś zrozumiał, jak
docker stop
działa polecenie i że wszystkie procesy powinny być zamykane w sposób czysty, aby zapobiec problemom podczas próby ich ponownego uruchomienia (uszkodzenie plików itp.).Problem: Co zrobić, jeśli doker zrobił startu SSH od jego polecenia i zaczął RabbitMQ z pliku Docker? „ Polecenie docker stop próbuje najpierw zatrzymać działający kontener, wysyłając sygnał SIGTERM do procesu głównego (PID 1) w kontenerze ” . Który proces jest śledzony przez docker jako PID 1, który otrzyma SIGTERM? Czy to będzie SSH czy Rabbit ?? „Zgodnie z modelem procesu Unix, proces inicjowania - PID 1 - dziedziczy wszystkie osierocone procesy potomne i musi je zbierać. Większość kontenerów Dockera nie ma procesu inicjującego, który robi to poprawnie, w wyniku czego ich kontenery są zapełniane procesy zombie w czasie ”.
Odpowiedź: Docker prostu wykonuje tę ostatnią CMD jako jeden z nich dostanie uruchomiony jako proces korzenia z PID 1 i uzyskać od SIGTERM
docker stop
.Sugerowane rozwiązanie: Powinieneś użyć (lub utworzyć) obraz podstawowy przeznaczony specjalnie do uruchamiania więcej niż jednej usługi, takiej jak phusion / baseimage
Należy zauważyć, że tini istnieje właśnie z tego powodu, a od wersji Docker 1.13 i nowszych tini jest oficjalnie częścią Dockera, co oznacza, że uruchomienie więcej niż jednego procesu w Dockerze JEST PRAWIDŁOWE ... więc nawet jeśli ktoś twierdzi, że Miej większe umiejętności w zakresie Dockera i nalega, abyś myślał o tym absurdalnie, wiedz, że tak nie jest. Istnieją całkowicie uzasadnione sytuacje, w których można to zrobić.
Dobrze wiedzieć:
źródło
Oficjalna odpowiedź Dockera na uruchamianie wielu usług w kontenerze .
Wyjaśnia, jak można to zrobić za pomocą systemu init (systemd, sysvinit, upstart), skryptu (
CMD ./my_wrapper_script.sh
) lub nadzorcy, takiego jaksupervisord
.&&
Obejście może pracować tylko dla usług, które rozpoczyna się w tle (demonów) lub że będzie wykonać szybko, bez interakcji i zwolnić polecenia. Robi to z usługą interaktywną (która zachowuje monit) i tylko pierwsza usługa zostanie uruchomiona.źródło
Aby wyjaśnić, dlaczego CMD jest zaprojektowany do uruchamiania tylko jednej usługi na kontener, uświadommy sobie, co by się stało, gdyby serwery pomocnicze działające w tym samym kontenerze nie były trywialne / pomocnicze, ale „główne” (np. Pamięć masowa w pakiecie z aplikacją frontend). Na początek zepsuje kilka ważnych funkcji kontenerowania, takich jak (automatyczne) skalowanie poziome i zmiana harmonogramu między węzłami, z których oba zakładają, że istnieje tylko jedna aplikacja (źródło obciążenia procesora) na kontener. Następnie pojawia się kwestia podatności - więcej serwerów ujawnionych w kontenerze to częstsze łatanie CVE ...
Przyznajmy więc, że jest to „popychanie” projektantów Dockera (i Kubernetes / Openshift) w kierunku dobrych praktyk i nie powinniśmy wymyślać na nowo obejść (SSH nie jest konieczne -
docker exec / kubectl exec / oc rsh
zaprojektowaliśmy go, aby go zastąpić)./devops/447/why-it-is-recommended-to-run-only-one-process-in-a-container
źródło