도커 컨테이너가 즉시 종료되는 이유


239

나는 백그라운드에서 컨테이너를 사용하여

 docker run -d --name hadoop h_Service

빠르게 종료됩니다. 그러나 전경에서 실행하면 정상적으로 작동합니다. 사용하여 로그를 확인했습니다.

docker logs hadoop

오류가 없었습니다. 어떤 아이디어?

독커 파일

 FROM java_ubuntu_new
 RUN wget http://archive.cloudera.com/cdh4/one-click-install/precise/amd64/cdh4-repository_1.0_all.deb
 RUN dpkg -i cdh4-repository_1.0_all.deb
 RUN curl -s http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh/archive.key | apt-key add -
 RUN  apt-get update
 RUN apt-get install -y hadoop-0.20-conf-pseudo
 RUN dpkg -L hadoop-0.20-conf-pseudo
 USER hdfs
 RUN hdfs namenode -format
 USER root
 RUN apt-get install -y sudo
 ADD . /usr/local/
 RUN chmod 777 /usr/local/start-all.sh
 CMD ["/usr/local/start-all.sh"]

start-all.sh

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start
 /etc/init.d/hadoop-hdfs-datanode start
 /etc/init.d/hadoop-hdfs-secondarynamenode start
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start
 /bin/bash

1
가장 중요한 규칙은 dockerized 서버가 디먼을 수행하지 못하게하는 것입니다. 대부분의 서버 패키지에는 데몬 화가 일반적인 경우이므로 포 그라운드에서 강제로 실행할 수있는 옵션이 있습니다.
Arnaud Meuret

당신이 성취하고자하는 chmod 777것은 안전하지 않으며 잘못입니다. 정상 권한 (이 경우에는 755)으로 되돌려 야합니다.
tripleee

답변:


125

기본 프로세스가 완료되면 도커 컨테이너가 종료됩니다.

이 경우 start-all.sh스크립트가 끝나면 종료됩니다. 이 경우 hadoop에 대해 알려주는 hadoop에 대해 충분히 알지 못하지만 포 그라운드에서 무언가를 실행하거나 runit 또는 supervisord와 같은 프로세스 관리자를 사용하여 프로세스를 실행해야합니다.

나는 당신이 지정하지 않으면 당신은 그것이 작동하는 것에 대해 착각해야한다고 생각합니다 -d. 정확히 같은 효과를 가져야합니다. 약간 다른 명령으로 실행하거나 -it변경 하여 사용할 수 있다고 생각합니다 .

간단한 해결책은 다음과 같은 것을 추가하는 것입니다.

while true; do sleep 1000; done

스크립트 끝까지. 그러나 스크립트가 실제로 시작된 프로세스를 모니터링해야하기 때문에 이것을 좋아하지 않습니다.

( https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh 에서 해당 코드를 훔쳤다고 말해야합니다 )


217

이것은 나를 위해 속임수를했다 :

docker run -dit ubuntu

그 후, 나는 다음을 사용하여 실행중인 프로세스를 확인했다.

docker ps -a

컨테이너를 다시 부착

docker attach CONTAINER_NAME

힌트 : 컨테이너 유형을 중지하지 않고 종료하는 경우 : ^P^Q


15
@Tommy, docs.docker.com/engine/reference/commandline/run -d, --detach 분리 모드 : 백그라운드에서 명령 실행, -i, --interactive 연결되지 않은 경우에도 STDIN을 열어 두십시오. -t,- -tty 의사 TTY 할당은 -dit속기입니다

3
@ am17torres 맞습니다. 죄송합니다. 혼란스러운 질문을 명확하게 해 드리겠습니다. d는 분리되어 있고 i는 대화 형이므로 d와 i의 조합은 혼란 스럽습니다. d는 백그라운드 (비 대화식) 프로세스로 시작해야한다고 생각했습니다.
Tommy

2
@Tommy이 옵션을 결합하면 컨테이너가 백그라운드에서 대화식 모드로 들어갑니다 .
Yon

2
@Tommy, @ am17torres -di가 최소 요구 -t사항입니다 . 옵션을 -d올바르게 이해하면 옵션이 중복됩니다.
Renaud

2
실제로 -t활성화 하지 않고 다시 연결하면 프롬프트가 표시되지 않지만 ... 보통 exec매번 새로운 bash를 사용하기 때문에 알 수 없습니다. Mac에서 분리하는 데 문제가 있었지만 아마도이 작업을 잘못하고있을 것입니다.
Renaud

65

나는 말을 확장하거나 감히하고 싶습니다.

달릴 때

docker run -dit ubuntu

기본적으로 컨테이너를 대화식 모드로 백그라운드에서 실행 중입니다.

CTRL + D (가장 일반적인 방법)로 컨테이너를 연결하고 종료하면 컨테이너를 중지 한 위의 명령으로 컨테이너를 중지했기 때문에 컨테이너를 중지합니다.

이미 실행중인 컨테이너를 활용하기 위해 다른 bash 프로세스를 포크하고 다음을 실행하여 의사 TTY를 얻습니다.

docker exec -it <container ID> /bin/bash

29

스크립트 실행을 마친 후에 컨테이너가 유지되기를 원할 때마다

&& tail -f /dev/null

명령의 끝에서. 따라서 다음과 같아야합니다.

/usr/local/start-all.sh && tail -f /dev/null

19

도커 컨테이너가 즉시 종료되는 이유는 무엇입니까?

무언가를 디버깅하거나 파일 시스템의 상태를 검사하기 위해 이미지를 강제로 정지 시키려면 시작점을 재정 의하여 셸로 변경할 수 있습니다.

docker run -it --entrypoint=/bin/bash myimagename

18

좋은 접근 방법은 프로세스와 서비스를 백그라운드에서 시작하고 wait [n ...]스크립트 끝에 명령을 사용하는 것 입니다. bash에서 wait 명령은 현재 프로세스가 다음을 수행하도록합니다.

지정된 각 프로세스를 기다렸다가 종료 상태를 반환하십시오. n을 지정하지 않으면 현재 활성화 된 모든 하위 프로세스가 대기되고 리턴 상태는 0입니다.

나는 그의 엘크 빌드를 위해 Sébastien Pujadas의 시작 스크립트 에서이 아이디어를 얻었습니다 .

원래 질문에서 시작하면 start-all.sh는 다음과 같습니다.

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start &
 /etc/init.d/hadoop-hdfs-datanode start &
 /etc/init.d/hadoop-hdfs-secondarynamenode start &
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start &
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start &
 wait

5

Dockerfile 끝에 이것을 추가하십시오 :

CMD tail -f /dev/null

샘플 도커 파일 :

FROM ubuntu:16.04

# other commands

CMD tail -f /dev/null

참고


CMD tail -f /dev/null그것을 통해 실행합니다 sh -c "...". exec대신 양식 을 사용할 수 있습니까 ? 즉CMD ["tail", "-f", "/dev/null"]
Meglio

4

내 pracitce는 Dockerfile에 있으며 즉시 종료되지 않는 쉘을 시작한 CMD [ "sh", "-c", "service ssh start; bash"]다음 실행하십시오 docker run -dit image_name. 이 방법으로 (ssh) 서비스 및 컨테이너가 실행 중입니다.


1

read끝에 쉘 문장을 추가했습니다 . 이렇게하면 컨테이너의 기본 프로세스 (시작 쉘 스크립트)가 계속 실행됩니다.


1

첨가

exec "$@"

내 쉘 스크립트의 끝에 내 수정했다!


당신의 cmd를 다음 단지 'bash는'아직하지 않습니다 일 경우 그 단지 수단은, 당신의 cmd를 실행하겠습니다
Shardj

1

컨테이너에서 Dockerfile을 확인하면 (예 : fballiano / magento2-apache-php)

파일의 끝에 다음 명령을 추가 함을 알 수 있습니다. while true; 잠을 1; 끝난

이제 제가 추천하는 것은

docker container ls --all | grep 127

그런 다음 docker 이미지에 오류가 있는지 확인하고 0으로 종료하면 영원히 잠들 수있는 명령 중 하나가 필요할 것입니다.


0

도커를 즉시 종료시키는 방법에는 여러 가지가 있습니다. 나를 위해, 그것은 내 문제였습니다 Dockerfile. 해당 파일에 버그가있었습니다. 나는 한 ENTRYPOINT ["dotnet", "M4Movie_Api.dll]대신ENTRYPOINT ["dotnet", "M4Movie_Api.dll"] . 보시다시피 마지막에 한 개의 인용 ( ")을 놓쳤습니다.

문제를 분석하기 위해 컨테이너를 시작하고 컨테이너를 빠르게 연결하여 정확한 문제가 무엇인지 알 수있었습니다.

C:\SVenu\M4Movie\Api\Api>docker start 4ea373efa21b


C:\SVenu\M4Movie\Api\Api>docker attach 4ea373efa21b

4ea373efa21b는 내 컨테이너 ID입니다. 이것은 실제 문제로 나를 안내합니다.

여기에 이미지 설명을 입력하십시오

문제를 찾은 후에 컨테이너를 다시 빌드, 복원 및 게시해야했습니다.


0

복제본에서 나오면 기본 작업을 백그라운드 작업으로 실행 한 다음 Docker가 종료되는 이유에 대한 일반적인 반 패턴을 다루는 대답이 없습니다.

간단한 용어로

my-main-thing &

그런 다음 &포 그라운드에서 작업을 실행하기 위해를 꺼내 거나

wait

스크립트가 끝날 때 모든 백그라운드 작업을 기다립니다.

그런 다음 메인 워크로드가 종료되면 여전히 종료되므로 while true루프 에서 실행 하여 영원히 다시 시작되도록하십시오.

while true; do
    my-main-thing &
    other things which need to happen while the main workload runs in the background
    maybe if you have such things
    wait
done

(주의는 어떻게 작성하는 while true. 그것의 일반적인 같이 어리석은 일을보고 while [ true ]또는 while [ 1 ]어떤 우연히 일이 일어날하지만 저자는 아마 상상 것을 의미하지 않는다 그 의미해야한다.)


0

백그라운드에서 데몬으로 실행되도록하려면 -d 플래그를 사용하여 실행해야합니다.

docker run -d -it 우분투 bash


-5

이 재시작 플래그를 사용하여 컨테이너를 실행할 수 있습니다.

docker run -d --name=<some-name> -p xxxx:xxxx ... <image-name> --restart=unless-stopped

-8

이미지는 리눅스이기 때문에 컨테이너에서 사용되는 쉘 스크립트에 유닉스 줄 끝이 있는지 확인해야합니다. 끝에 ^ M이 있으면 창 줄 끝입니다. 이를 해결하는 한 가지 방법은 /usr/local/start-all.sh에서 dos2unix를 사용하여 창에서 유닉스로 변환하는 것입니다. 대화식 모드에서 도커를 실행하면 다른 문제를 파악하는 데 도움이 될 수 있습니다. 파일 이름이 오타 일 수 있습니다. 참조 https://en.wikipedia.org/wiki/Newline를

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.