도커 실행이 프로그래밍 방식으로 성공했는지 감지하는 방법은 무엇입니까?


82

컨테이너가 여전히 올바르게 빌드되고 시작되는지, 내부 앱이 요청에 응답하는지 빠르게 확인하기 위해 매우 간단한 bash 스크립트를 작성하고 있습니다.

docker run예를 들어 컨테이너를 바인딩하려는 포트가 이미 할당되어 있기 때문에 때때로 실패합니다. 그러나 이것이 발생하면 docker run종료 코드는 여전히 0이므로 종료 코드를 사용할 수 없습니다. 컨테이너가 올바르게 시작되었는지 프로그래밍 방식으로 어떻게 확인할 수 있습니까?

내가 고려중인 솔루션은 다음과 같습니다.

  • 오류에 대한 출력 구문 분석
  • docker ps 컨테이너가 실행 중인지 확인

그러나 이것들은 약간 과잉이고 추한 것처럼 보입니다. docker run성공 여부를 확인하는 더 좋은 방법을 놓치고 있습니까?


1
여기서 문제가 무엇인지 잘 모르겠습니다. 문제의 프로세스가 일반적인 방식으로 작동하면 간단히 종료 코드를 확인할 수 있습니다. 실패한 경우에도 종료 코드 0이 나오면 버그인지 파악하십시오. 어떤 경우 에든 프로그램이 종료 코드 0을 반환하면 출력을 구문 분석 할 수밖에 없습니다.
devnull

@devnull이 말했듯이 docker run실패시 0이 아닌 반환 코드를 반환하는 것을 신뢰할 수 없다면 출력 (복잡하거나 깨지기 쉬울 수 있음)을 구문 분석하거나 다른 명령 (예 : ps제안 )를 사용하여 첫 번째 명령의 결과를 확인합니다. docker로 티켓을 제출하여 반환 코드를 수정할 수 있는지 확인하는 것이 run좋습니다.
Etan Reisner 2014

최신 버전인지 확인하십시오.
ooga

컨테이너에서 실행되는 사용자 지정 코드입니까? 그렇다면 프로그램이 안정적인 실행 상태에있을 때 Dockerfile에서 포트를 내보낼 수 있으며 해당 포트에서 "OK"메시지를 보냅니다. 클라이언트 코드는 "OK"메시지를 기다립니다.
rexposadas

3
Docker를 실행하는 방법과 버전에 대한 예를 제공 할 수 있습니까? 빠른 테스트 쇼 고정 표시기 종료 코드는 나를 위해 일을 할 수docker run -d -p 9010:9010 busybox true ; echo $?
아벨 Muiño

답변:


116

Abel Muiño가 의견에서 제안했듯이 이것은 최신 Docker 버전에서 수정되었을 수 있습니다 (현재 0.9.1을 실행 중입니다).

그러나 일시적으로 이전 버전에서 나와 같이 갇혀 있다면 컨테이너가 .NET을 사용하여 시작되었는지 확인하는 적절한 해결 방법을 찾았습니다 docker inspect.

docker inspect컨테이너에 대한 많은 정보, 특히 컨테이너가 현재 실행 중인지 여부와 함께 JSON 개체를 반환합니다. -f플래그는 쉽게 필요한 비트를 추출 할 수 있습니다 :

docker inspect -f {{.State.Running}} $CONTAINER_ID

또는

docker inspect -f "{{.State.Running}}" $CONTAINER_ID

반환 true또는 false.

sleep 1컨테이너 시작과 작동 여부 확인 사이 에 (또는 그 이상) 원할 수 있습니다. 설정에 문제가있는 경우 실제로 종료하기 전에 매우 짧은 시간 동안 '실행 중'으로 나타날 수 있습니다.


11
대신 사용 docker inspect -f {{.State.Running}} <container-id>하고 사용 하지 않는 이유는 무엇 jq입니까? 그냥 궁금해.
Dharmit

2
내가 깨닫지 못했기 때문에 검사를 직접 수행 할 수 있습니다! 감사합니다 @DharmitShah 좋은 제안입니다. 제 답변을 업데이트하겠습니다.
Jules Olléon 2014

2
이러한 컨테이너가없는 경우 오류 메시지를 표시하지 않으려면 stderr을 2> /dev/null.
thSoft

이것을 var에 할당하면 2> /dev/null아무것도 평가하지 않기 때문에 사용할 때 오류가 발생 합니다. false컨테이너가없는 경우 어떻게 기본값으로 만들 수 있습니까?
제이크 Sankey

1
그러나 이것은 다시 시작 정책으로 인해 계속 다시 시작되는 컨테이너를 수용하지 않습니다. 즉, 컨테이너에 중지되지 않은 / 항상 다시 시작 정책이 주어지면 .State.Running은 항상 true를 반환합니다 .... 지치다!
geekscrap

22

아무것도 파싱하지 않으려면 컨테이너가 실행 중이 아니면 1을 반환 하는 docker top을 사용할 수 있습니다 .

id=$(docker run mycontainer)
if ! docker top $id &>/dev/null
then
    echo "Container crashed unexpectedly..."
    return 1
fi

10

우리는 docker exec $id true 2>/dev/null || echo not running.

이 명령은 "docker top"처럼 stdout에 쓰지 않습니다. 컨테이너가 실행되지 않을 때 "docker top"과 동일한 메시지를 stderr에 기록합니다.


2

앞서 언급 한 제안 사항을 스크립트에 적용합니다.

1-keepMyDockerUp.sh 스크립트를 만듭니다 .

vi keepMyDockerUp.sh


#!/bin/bash
Container_ID=INSERT_YOUR_CONTAINER_ID HERE
result=$( docker inspect -f {{.State.Running}} $Container_ID)
echo "result is" $result
if [ $result = "true" ]
then
echo "docker is already running"
else
systemctl restart docker
docker start $Container_ID
fi

2-그런 다음 간단히 cron에 추가하면 스크립트가 Docker 컨테이너가 수시로 작동하는지 확인합니다.

crontab -e

마지막 줄로 이동하여 스크립트 파일을 추가하십시오. 예를 들면 :

* * * * * /root/keepMyDockerUp.sh

3-crontab을 저장하고 Docker 컨테이너가 다시 다운되는 것에 대해 걱정하지 마십시오.

도움이 되길 바랍니다 ...

;-)


1

나는 사용해야했다 :

$ docker inspect -f {{.State.Health.Status}} xxx

(컨테이너가 실행중인 상태 였지만 컨테이너 내부의 서비스가 완전히 시작되지 않았습니다.

검사 출력의 일부 :

"State": {
    "Status": "running",
    "Running": true,
    "Paused": false,
    "Restarting": false,
    "OOMKilled": false,
    "Dead": false,
    "Pid": 1618,
    "ExitCode": 0,
    "Error": "",
    "StartedAt": "2019-03-08T10:39:24.061732398Z",
    "FinishedAt": "0001-01-01T00:00:00Z",
    "Health": {
        "Status": "starting",
        "FailingStreak": 0,
        "Log": []

실행이 성공했는지 여부는 표시되지 않습니다. 컨테이너가 실행되고 실패 할 수 있기 때문입니다.
Vino
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.