[docker] Docker CMD를 여러 번 사용하여 여러 서비스를 실행할 수없는 이유는 무엇입니까?

Dockerfile에서 centos + ssh라는 기본 이미지를 빌드했습니다. centos + ssh의 Dockerfile에서 CMD를 사용하여 ssh 서비스를 실행합니다.

그런 다음 rabbitmq라는 다른 서비스 인 Dockerfile을 실행하는 이미지를 빌드하고 싶습니다.

FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD /opt/mq/sbin/rabbitmq-server start

rabbitmq 컨테이너를 시작하려면 다음을 실행합니다.

docker run -d -p 222:22 -p 4149:4149 rabbitmq

그러나 ssh 서비스가 작동하지 않으면 rabbitmq의 Dockerfile CMD가 centos의 CMD를 재정의하는 것을 감지합니다.

  1. CMD는 Docker 이미지 내에서 어떻게 작동합니까?
  2. 여러 서비스를 실행하려면 어떻게해야합니까? 감독자를 사용하십니까?


답변

CMD는 Dockerfile에 기록되어 있지만 실제로는 런타임 정보입니다. EXPOSE와 같지만 예를 들어 RUN 및 ADD와는 반대입니다. 이것은 나중에 Dockerfile을 확장하거나 실행 명령에서 간단히 재정의 할 수 있음을 의미합니다. 항상 하나의 CMD 만있을 수 있습니다.

여러 서비스를 실행하려면 실제로 감독자를 사용합니다. 각 서비스에 대한 감독자 구성 파일을 만들고, 디렉토리에 추가하고, supervisord -c /etc/supervisor모든 서비스를로드하고 다음과 같은 감독자 구성 파일을 가리 키도록 감독자를 실행할 수 있습니다.

[supervisord]
nodaemon=true

[include]
files = /etc/supervisor/conf.d/*.conf

더 자세한 정보를 원하시면 여기에이 주제에 대한 블로그를 작성했습니다. http://blog.trifork.com/2014/03/11/using-supervisor-with-docker-to-manage-processes-supporting-image- 계승/


답변

맞습니다. 두 번째 Dockerfile은 CMD첫 번째 Dockerfile의 명령을 덮어 씁니다 . Docker는 항상 하나의 명령 만 실행합니다. 따라서 Dockerfile의 끝에 하나 를 지정할 수 있습니다. 에서 실행할 명령을 . 아니 더.

그러나 두 명령을 한 줄로 실행할 수 있습니다.

FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD service sshd start && /opt/mq/sbin/rabbitmq-server start

Dockerfile을 좀 더 깔끔하게 만들기 위해 할 수있는 작업은 추가 파일에 CMD 명령을 넣을 수 있습니다.

FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD sh /home/centos/all_your_commands.sh

그리고 다음과 같은 파일 :

service sshd start &
/opt/mq/sbin/rabbitmq-server start


답변

이 문제를 해결하는 방법을 설명하는 qkrijger의 답변을 존중하지만 여기에서 무슨 일이 일어나고 있는지에 대해 배울 수있는 것이 훨씬 더 많다고 생각합니다.

“라는 질문에 실제로 대답하려면 … docker stop명령이 작동 하는 방식을 이해 하고 모든 프로세스를 완전히 종료해야한다는 점 을 이해하는 것이 도움 이 될 것 같습니다. 를 다시 시작하려고 할 때 문제를 방지하기 위해 합니다 (파일 손상 등).

문제 : docker 명령에서 SSH를 시작 하고 Docker 파일에서 RabbitMQ를 시작했다면 어떻게됩니까? ” docker stop 명령은 먼저 SIGTERM 신호를 컨테이너의 루트 프로세스 (PID 1)로 전송하여 실행중인 컨테이너를 중지하려고합니다. “SIGTERM을받을 PID 1로 docker 추적하는 프로세스는 무엇입니까? SSH 또는 Rabbit입니까 ?? “Unix 프로세스 모델에 따르면 init 프로세스 (PID 1)는 분리 된 모든 자식 프로세스를 상속하고이를 수확해야합니다. 대부분의 Docker 컨테이너에는이를 올바르게 수행하는 init 프로세스가 없기 때문에 컨테이너가 채워집니다. 시간이 지남에 따라 좀비 프로세스. “

답변 : 도커는 단순히으로 마지막 CMD 필요 하나 같이 시작 얻을 것이다 루트 프로세스를 PID 1과에서 SIGTERM을 얻을docker stop .

제안 된 솔루션 : phusion / baseimage 와 같이 둘 이상의 서비스를 실행하기 위해 특별히 제작 된 기본 이미지를 사용 (또는 생성)해야합니다.

이 점에 유의하는 것이 중요합니다 TINI는 이런 이유로 정확히 존재하고 도커 1.13의 최대로, TINI는 공식적으로 도커에서 둘 이상의 프로세스를 실행하는 것을 우리에게 알려줍니다 도커의 일부입니다 유효합니다 .. 그래서 경우에도 누군가 에 주장 더 능숙하다 Docker에 대해 하고, 이것을 생각하는 것이 어리 석다고 주장하고, 그렇지 않다는 것을 알고 있습니다. 그렇게하기위한 완벽하게 유효한 상황이 있습니다.

알아 둘만 한:


답변

컨테이너에서 여러 서비스 실행에 대한 공식 Docker 답변 .

init 시스템 (systemd, sysvinit, upstart), 스크립트 ( CMD ./my_wrapper_script.sh) 또는 다음과 같은 수퍼바이저를 사용하여 수행하는 방법을 설명합니다.supervisord .

그만큼 &&해결 방법은 배경 (데몬)에서 시작 서비스에 대해서만 작동하거나 그 상호 작용없이 신속하게 실행하고 프롬프트를 발표 할 예정이다. 대화 형 서비스 (프롬프트를 유지함)로이 작업을 수행하면 첫 번째 서비스 만 시작됩니다.


답변

CMD가 컨테이너 당 하나의 서비스 만 실행하도록 설계된 이유를 해결하기 위해 동일한 컨테이너에서 실행되는 보조 서버가 사소한 / 보조가 아니라 “주요”(예 : 프런트 엔드 앱에 번들로 제공되는 스토리지) 인 경우 어떤 일이 발생하는지 알아 봅시다. 우선, 수평 적 (자동) 확장 및 노드 간 재 스케줄링과 같은 몇 가지 중요한 컨테이너화 기능을 세분화합니다. 두 가지 모두 컨테이너 당 하나의 애플리케이션 (CPU로드 소스) 만 있다고 가정합니다. 그런 다음 취약점 문제가 있습니다. 컨테이너에 더 많은 서버가 노출되면 CVE 패치가 더 자주 발생합니다.

따라서 Docker (및 Kubernetes / Openshift) 디자이너의 모범 사례에 대한 ‘너지’이며 해결 방법을 재발견해서는 안됩니다 (SSH가 필요하지 않으며 docker exec / kubectl exec / oc rsh이를 대체하도록 설계했습니다).

  • 더 많은 정보

/devops/447/why-it-is-recommended-to-run-only-one-process-in-a-container


답변