도커 컨테이너가 가동될 때까지 어떻게 기다려야 합니까?
컨테이너 내에서 서비스를 실행할 때 mongodb 명령어라고 합시다.
docker run -d myimage
아이디CI 스크립트에서는 mongo 컨테이너 실행 직후 mongodb 연결을 테스트하기 위해 클라이언트를 실행합니다.문제는 서비스가 아직 시작되지 않았기 때문에 클라이언트가 접속할 수 없다는 것입니다. 것을 하는 것 sleep 10내 스크립트에는 컨테이너가 가동될 때까지 기다릴 수 있는 옵션이 없습니다.
.wait그런 경우에는 통하지 않습니다. 용기가 존재하지 않기 때문입니다.커제 ??
이 간단한 해결책을 찾았고, 더 나은 방법을 찾고 있었지만, 운이 없었다.
until [ "`docker inspect -f {{.State.Running}} CONTAINERNAME`"=="true" ]; do
sleep 0.1;
done;
또는 컨테이너가 정상으로 보고될 때까지 기다리려는 경우(상태 점검이 있어야 함)
until [ "`docker inspect -f {{.State.Health.Status}} CONTAINERNAME`"=="healthy" ]; do
sleep 0.1;
done;
도커 1.12에 대해서도 같은 호에서 코멘트하고 있습니다.
HEALTHCHECK지원은 도커/도커#23218에 따라 업스트림에서 Marge됩니다.이것에 의해, 다음의 순서로 기동하기 전에, 컨테이너가 정상인 것을 판단할 수 있습니다.
도커 1.12rc3(2016-07-14) 이후 이용 가능
docker-compose 는 특정 조건을 대기하는 기능을 지원하는 중입니다.
it it를 한다.
libcompose(도커 인터랙션을 재구축할 필요가 없습니다).그리고 이를 위해 다수의 config 명령어를 추가합니다.여기를 봐주세요.https://github.com/dansteen/controlled-compose
Dockerfile에서는 다음과 같이 사용할 수 있습니다.
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
공식문서: https://docs.docker.com/engine/reference/builder/#/healthcheck
컨테이너를 링크할 계획이며 테스트를 위해 여러 인스턴스를 실행하는 경우처럼 포트를 노출하지 않는 경우 이 방법은 한 줄로 실행하는 것이 좋습니다.다음 예시는 Elastic Search가 준비되기를 기다리는 것을 기반으로 합니다.
docker inspect --format '{{ .NetworkSettings.IPAddress }}:9200' elasticsearch | xargs wget --retry-connrefused --tries=5 -q --wait=3 --spider
이를 위해서는 Ubuntu에서 표준으로 제공되는 wget이 필요합니다.접속이 거부되어도 5회, 3초 간격으로 재시도하고 아무것도 다운로드하지 않습니다.
또는 요구에 반응하지 않는 서비스에서 할 수 에는 wget을 사용할 수 .nc★★★★★★ 。
Postgres 컨테이너를 시작하고 계속하기 전에 사용할 수 있을 때까지 기다리는 호스트 스크립트의 일부를 다음에 나타냅니다.
POSTGRES_CONTAINER=`docker run -d --name postgres postgres:9.3`
# Wait for the postgres port to be available
until nc -z $(sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' $POSTGRES_CONTAINER) 5432
do
echo "waiting for postgres container..."
sleep 0.5
done
편집 - 이 예에서는 컨테이너에 대해 도커가 할당한 '개인' IP 주소에 액세스하므로 테스트 중인 포트를 노출할 필요가 없습니다.단, 이것은 도커호스트 데몬이 루프백(127.x.x.x) 상에서 리슨하고 있는 경우에만 기능합니다.예를 들어 Mac에서 boot2docker VM을 실행하는 경우 Mac 쉘에서 컨테이너의 '개인' IP 주소로 라우팅할 수 없으므로 이 방법을 사용할 수 없습니다.
합니다(MongoDB를 에+포트를 알고 있습니다).-link, 「」를 삽입했기 때문에, 「」를 참조해 주세요.-e를 사용하면 .curlMongoDB mong mong mongdb mong mong mong mong mong mong mong mong 。
다음 스니펫은 성공할 때까지 매초 연결을 시도합니다.
#!/bin/sh
while ! curl http://$DB_PORT_27017_TCP_ADDR:$DB_PORT_27017_TCP_PORT/
do
echo "$(date) - still trying"
sleep 1
done
echo "$(date) - connected successfully"
결국엔 이런 일이 생겼죠
#!/bin/bash
attempt=0
while [ $attempt -le 59 ]; do
attempt=$(( $attempt + 1 ))
echo "Waiting for server to be up (attempt: $attempt)..."
result=$(docker logs mongo)
if grep -q 'waiting for connections on port 27017' <<< $result ; then
echo "Mongodb is up!"
break
fi
sleep 2
done
저만의 솔루션을 제안하고 있습니다.
저는 도커 네트워크를 사용하고 있기 때문에 Mark의 넷캣 트릭은 통하지 않습니다(호스트 네트워크로부터의 액세스 없음).Erik의 아이디어는 포스트그레스 컨테이너에서는 통하지 않습니다(포스트그레는 아직 접속할 수 없지만 컨테이너는 실행 중인 것으로 표시됩니다).루프의 ephemeral 컨테이너를 통해 postgres에 접속하려고 합니다.
#!/bin/bash
docker network create my-network
docker run -d \
--name postgres \
--net my-network \
-e POSTGRES_USER=myuser \
postgres
# wait for the database to come up
until docker run --rm --net my-network postgres psql -h postgres -U myuser; do
echo "Waiting for postgres container..."
sleep 0.5
done
# do stuff with the database...
나는 이것을 다시 시도해야 했고 아이디어가 떠올랐다.이 과제를 위해 조사를 할 때, 이 포스트의 향후 방문자와 솔루션을 공유하려고 합니다.
도커 기반 솔루션
도커 컴포지트를 사용하는 경우 도커 동기화 POC를 확인할 수 있습니다.나는 다른 질문에서 몇 가지 아이디어를 결합했다.
기본 개념은 복합체의 모든 컨테이너가 진단 서비스를 제공한다는 것입니다.이 서비스를 호출하면 필요한 포트 세트가 컨테이너에서 열려 있는지 확인하고 컨테이너의 전체 상태(POC에 따라 WARMUP/RUNNING)를 반환합니다.또, 각 컨테이너에는, 기동시에 의존 서비스가 기동하고 있는지를 체크하는 유틸리티도 있습니다.그 다음에야 용기가 시작됩니다.
도커 컴포지트 환경의 예에서는 2개의 서비스 서버1과 서버2가 있으며 클라이언트서비스는 양쪽 서버의 기동을 기다렸다가 양쪽 서버에 요구를 송신하고 종료합니다.
POC에서 발췌
wait_for_server 입니다.쉿
#!/bin/bash
server_host=$1
sleep_seconds=5
while true; do
echo -n "Checking $server_host status... "
output=$(echo "" | nc $server_host 7070)
if [ "$output" == "RUNNING" ]
then
echo "$server_host is running and ready to process requests."
break
fi
echo "$server_host is warming up. Trying again in $sleep_seconds seconds..."
sleep $sleep_seconds
done
여러 컨테이너 대기 중:
trap 'kill $(jobs -p)' EXIT
for server in $DEPENDS_ON
do
/assets/wait_for_server.sh $server &
wait $!
done
Diagnostic srervice 기본 구현(checkports).sh) :
#!/bin/bash
for port in $SERVER_PORT; do
nc -z localhost $port;
rc=$?
if [[ $rc != 0 ]]; then
echo "WARMUP";
exit;
fi
done
echo "RUNNING";
진단 서비스를 포트에 배선하는 방법:
nc -v -lk -p 7070 -e /assets/checkports.sh
열린 포트를 기다리는 경우 다음 간단한 스크립트를 사용할 수 있습니다.
until </dev/tcp/localhost/32022; do sleep 1; done
포트 32022가 접속할 수 있을 때까지 기다립니다.
test/test_runner
#!/usr/bin/env ruby
$stdout.sync = true
def wait_ready(port)
until (`netstat -ant | grep #{port}`; $?.success?) do
sleep 1
print '.'
end
end
print 'Running supervisord'
system '/usr/bin/supervisord'
wait_ready(3000)
puts "It's ready :)"
$ docker run -v /tmp/mnt:/mnt myimage ruby mnt/test/test_runner
포트가 수신 중인지 아닌지를 이렇게 테스트하고 있습니다.이 경우, 컨테이너 내부에서 테스트를 실시합니다만, mongodb의 준비가 완료되었는지 아닌지는 외부에서도 가능합니다.
$ docker run -p 37017:27017 -d myimage
그리고 포트 37017이 호스트 컨테이너로부터 수신하고 있는지 여부를 확인합니다.
wait-for-it 를 사용하면, 호스트와 TCP 포토가 사용 가능하게 될 때까지 대기하는 순수 bash 스크립트를 사용할 수 있습니다. 이 기능은 연결된 도커 컨테이너와 같은 상호 종속 서비스의 스핀업을 동기화하는 데 유용합니다. 순수 bash 스크립트이기 때문에 외부 의존관계는 없습니다.
단, 서비스 간의 이러한 상호의존성을 방지하기 위해 서비스를 설계해야 합니다.서비스가 데이터베이스에 재접속을 시도할 수 있습니까?컨테이너가 데이터베이스에 접속할 수 없는 경우 컨테이너를 정지시키고 컨테이너 오케스트레이터(Docker Swarm 등)에게 맡길 수 있습니까?
도커 컴포지트 솔루션
도커 구성 후 도커 컨테이너 이름을 모르기 때문에 사용합니다.
docker inspect -f {{.State.Running}} $(docker-compose ps -q <CONTAINER_NAME>)
하고 있습니다.true여기 https://stackoverflow.com/a/33520390/7438079와 같이
Postgre가 있는지 확인하기 위해SQL 또는 MySQL(현재) Docker 컨테이너가 가동 중(Flyway 등의 마이그레이션 도구에 필요), 바이너리 대기 https://github.com/arcanjoaq/wait-for를 사용할 수 있습니다.
mongoDB 도커 인스턴스의 경우 다음과 같이 처리하여 매력적으로 작동합니다.
#!/usr/bin/env bash
until docker exec -i ${MONGO_IMAGE_NAME} mongo -u ${MONGO_INITDB_ROOT_USERNAME} -p ${MONGO_INITDB_ROOT_PASSWORD}<<EOF
exit
EOF
do
echo "Waiting for Mongo to start..."
sleep 0.5
done
여기 조금 더 간결하게 앞의 답변과 비슷한 내용이 있습니다.
until [[ $(docker logs $db_container_name) == *"waiting for connections on port 27017"* ]]
do
echo "waiting on mongo to boot..."
sleep 1
done
1 : Synology NAS 부팅 시 도커 컴포지트를 사용하여 서비스에 연결된 컨테이너가 시작되지 않습니다.
Synology NAS에서 도커 컨테이너를 실행하는 데 문제가 있었습니다. 도커 구성은 다음과 같습니다.
...
---
version: "3"
services:
gluetun:
image: qmcgaw/gluetun
container_name: gluetun
...
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
# Connect the service to gluetun
network_mode: "service:gluetun"
...
Synology에서 사용되는 도커가 다르거나 최신 버전이 아니며 컨테이너가 다른 컨테이너에 연결되어 있는 것을 좋아하지 않는 것 같습니다.network_modeSynology 도커는 컨테이너가 네트워크에 연결되어 있지 않기 때문에 컨테이너를 기동할 수 없다고 간주합니다.그러나 명령줄에서는 매우 잘 작동하기 때문에 예약된 작업에 의해 NAS 부팅 시 자동으로 실행되는 스크립트를 만들고 싶었습니다.
메모: 포트라이너로 도커를 작성합니다.
2 : 조건을 기술하는 방법이 모두 다른 경우에도 toil 루프는 기능하지 않습니다.
Synology NAS에 있는 저처럼until슈퍼히어로의 설명대로 루프워크: 여기서 당신은 그 슈퍼히어로를 통과해야 할 것입니다.while고리.
단,-x의 의론.bash내 코드를 디버깅하려면 String 비교가 정상적으로 수행되었습니다.
출력 행(식을 설명하는 모든 방법과 동일):
...
+ [' false = true ']'
...
결과가 어떻게 되든 매번 확인해보니 뜻대로 되지 않는 순간이 항상 있었다.
4: Synology 솔루션
환경
DSM : 7.1.1
bash: 4.4.23
도커: 20.10.3
올바른 구문을 찾은 후 다음 문제를 해결해야 했습니다.
도커 컨테이너 상태 확인은 Synology 도커 패키지가 실행 중인 경우에만 작동합니다.
그래서 나는 사용했다.synopkg와 함께is_onoff,is_active동작하지 않습니다.status너무 많은 끈을 주었기 때문에 솔루션에서는 다음과 같이 되어 있습니다.
#!/bin/bash
while [ "$(synopkg is_onoff Docker)" != "package Docker is turned on" ]; do
sleep 0.1;
done;
echo "Docker package is running..."
echo ""
while [ "$(docker inspect -f {{.State.Running}} gluetun)" = "false" ]; do
sleep 0.1;
done;
echo "gluetun is running..."
echo ""
if [ "$(docker ps -a -f status=exited -f name=qbittorrent --format '{{.Names}}')" ]; then
echo "Qbittorrent is not running I try to start this container"
docker start qbittorrent
else
echo "Qbittorrent docker is already started"
fi
을 할 수.root사용자가 DSM 구성에서 Boot-Up을 실행했을 때 Synology Docker 패키지의 기동 상태를 확인하지 않고 재부팅 후 정상적으로 동작했습니다.synopkg효과가 없었습니다.
메모
★★★★★★★★의 버전이라고 생각합니다.BashDSM에서는, Diagnostics가until잘못 해석되었습니다.이 솔루션은 다음과 같은 시스템에서도 사용할 수 있습니다.bash를 할 수 X의 하지 않을 수 .Bash시스템을 망가뜨리지 않도록 합니다.
언급URL : https://stackoverflow.com/questions/21183088/how-can-i-wait-for-a-docker-container-to-be-up-and-running
'programing' 카테고리의 다른 글
| spread 구문 및 typescript에 새로운 Set() 사용 (0) | 2023.02.28 |
|---|---|
| WooCommerce 서브스크립션 - 특정 서브스크립션 관련 주문 ID 가져오기 (0) | 2023.02.28 |
| index.css 와"create-react-app"에 의해 작성된 기본 앱의 App.css는 어떤 차이가 있습니까? (0) | 2023.02.28 |
| google이 create-display-app을 사용하는 리액트 앱에 정의되어 있지 않습니다. (0) | 2023.02.28 |
| 에서 json 키가 소문자임을 확인합니다.그물 (0) | 2023.02.28 |