development

서비스를 시작한 후 Docker 컨테이너를 계속 실행하는 방법은 무엇입니까?

big-blog 2020. 7. 1. 07:32
반응형

서비스를 시작한 후 Docker 컨테이너를 계속 실행하는 방법은 무엇입니까?


내가하려고하는 것과 똑같은 일을하는 많은 자습서를 보았지만 어떤 이유로 Docker 컨테이너가 종료됩니다. 기본적으로 Docker 컨테이너 안에 웹 서버와 몇 가지 데몬을 설정하고 있습니다. run-all.shDockerfile에서 CMD를 통해 실행 되는 bash 스크립트를 통해 마지막 부분을 수행합니다 . run-all.sh다음과 같이 보입니다 :

service supervisor start
service nginx start

그리고 다음과 같이 Dockerfile 내에서 시작합니다.

CMD ["sh", "/root/credentialize_and_run.sh"]

수동으로 작업을 실행할 때 서비스가 모두 올바르게 시작되는 것을 볼 수 있습니다 (예 : -i -t / bin / bash를 사용하여 이미지에 가져 오기). 이미지를 실행할 때 모든 것이 올바르게 실행되는 것처럼 보이지만 한 번 종료됩니다. 프로세스 시작을 마칩니다. 프로세스가 무기한으로 실행되기를 원하며 이해하는 한 컨테이너가 계속 실행되어야합니다. 그럼에도 불구하고을 실행 docker ps -a하면 다음을 볼 수 있습니다.

➜  docker_test  docker ps -a
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS                      PORTS               NAMES
c7706edc4189        some_name/some_repo:blah   "sh /root/run-all.sh   8 minutes ago       Exited (0) 8 minutes ago                        grave_jones

무엇을 제공합니까? 왜 종료 되나요? 내 bash 스크립트 끝에 while 루프를 넣어 유지할 수 있다는 것을 알고 있지만 종료하지 못하게하는 올바른 방법은 무엇입니까?


이것이 실제로 Docker 컨테이너를 디자인하는 방법이 아닙니다.

도커 컨테이너를 설계 할 때, 당신은이 같은에만이 있음을 구축하는데있어 하나의 실행중인 프로세스 (즉, 하나 개 Nginx에 대한 컨테이너 및 supervisord 또는 응용 프로그램이 실행중인 하나가 있어야합니다) 또한 해당 프로세스는 포 그라운드에서 실행되어야합니다.

컨테이너는 프로세스 자체가 종료 될 때 "종료"됩니다 (이 경우 해당 프로세스는 bash 스크립트입니다).


그러나 실제로 Docker 컨테이너에서 여러 서비스를 실행 해야하는 경우 의사 초기화 프로세스로 사용 되는 "Docker Base Image"로 시작하는 것을 고려하십시오 runit( runitNginx 및 Supervisor가 실행되는 동안 온라인 상태로 유지됨). 다른 프로세스가 자신의 작업을 수행하는 동안

그들은 상당한 문서를 가지고 있으므로, 당신은 당신이 합리적으로 쉽게하려고하는 것을 성취 할 수 있어야합니다.


Dockerfile을 사용하는 경우 다음을 시도하십시오.

ENTRYPOINT ["tail", "-f", "/dev/null"]

(분명히 이것은 개발 목적으로 만 사용됩니다. 예를 들어 nginx ...와 같은 프로세스를 실행하지 않는 한 컨테이너를 살아있게 유지할 필요는 없습니다.)


방금 같은 문제가 있었고 -tand 및 -d플래그로 컨테이너를 실행하면 계속 실행 된다는 것을 알았습니다 .

docker run -td <image>

다음은 플래그에 따라 수행되는 작업입니다 docker run --help.

-d, --detach=false         Run container in background and print container ID
-t, --tty=false            Allocate a pseudo-TTY

가장 중요한 것은 -t깃발입니다. -d컨테이너를 백그라운드에서 실행할 수 있습니다.


종료하는 이유는 쉘 스크립트가 PID 1로 먼저 실행되고 완료되면 PID 1이 없어지고 docker는 PID 1이있는 동안에 만 실행되기 때문입니다.

수퍼바이저를 사용하여 모든 작업을 수행 할 수 있습니다. "-n"플래그를 사용하여 실행하면 데몬으로 초기화하지 않도록 지시되므로 첫 번째 프로세스로 유지됩니다.

CMD ["/usr/bin/supervisord", "-n"]

그리고 supervisord.conf :

[supervisord]
nodaemon=true

[program:startup]
priority=1
command=/root/credentialize_and_run.sh
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=false
startsecs=0

[program:nginx]
priority=10
command=nginx -g "daemon off;"
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.log
autorestart=true

그런 다음 원하는만큼 다른 프로세스를 가질 수 있으며 필요한 경우 감독자가 프로세스 재시작을 처리합니다.

그렇게하면 nginx와 php5-fpm이 필요할 때 supervisord를 사용할 수 있으며 그것들을 구분하는 것이 의미가 없습니다.


catbro @ Sa'ad가 언급 한대로 아무런 주장없이 평범하게 실행할 수 있습니다 . 컨테이너가 실제로 작동하도록 유지하십시오 (실제로 사용자 입력을 기다리는 것만 없음) (Jenkins의 Docker 플러그인은 동일한 작업을 수행합니다)


daemon off;nginx.conf 를 추가 하거나 CMD ["nginx", "-g", "daemon off;"]공식 nginx 이미지에 따라 실행하십시오.

Then use the following to run both supervisor as service and nginx as foreground process that will prevent the container from exiting

service supervisor start && nginx

In some cases you will need to have more than one process in your container, so forcing the container to have exactly one process won't work and can create more problems in deployment.

So you need to understand the trade-offs and make your decision accordingly.


Capture the PID of the ngnix process in a variable (for example $NGNIX_PID) and at the end of the entrypoint file do

wait $NGNIX_PID 

In that way, your container should run until ngnix is alive, when ngnix stops, the container stops as well


Motivation:

There is nothing wrong in running multiple processes inside of a docker container. If one likes to use docker as a light weight VM - so be it. Others like to split their applications into micro services. Me thinks: A LAMP stack in one container? Just great.

The answer:

Stick with a good base image like the phusion base image. There may be others. Please comment.

And this is yet just another plead for supervisor. Because the phusion base image is providing supervisor besides of some other things like cron and locale setup. Stuff you like to have setup when running such a light weight VM. For what it's worth it also provides ssh connections into the container.

The phusion image itself will just start and keep running if you issue this basic docker run statement:

moin@stretchDEV:~$ docker run -d phusion/baseimage
521e8a12f6ff844fb142d0e2587ed33cdc82b70aa64cce07ed6c0226d857b367
moin@stretchDEV:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS
521e8a12f6ff        phusion/baseimage   "/sbin/my_init"     12 seconds ago      Up 11 seconds

Or dead simple:

If a base image is not for you... For the quick CMD to keep it running I would suppose something like this for bash:

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

Or this for busybox:

CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

This is nice, because it will exit immediately on a docker stop. Just plain sleep or cat will take a few seconds before the container exits.


How about using the supervise form of service if available?

service YOUR_SERVICE supervise

Once supervise is successfully running, it will not exit unless it is killed or specifically asked to exit.

Saves having to create a supervisord.conf

참고URL : https://stackoverflow.com/questions/25775266/how-to-keep-docker-container-running-after-starting-services

반응형