चेक कंटेनर/सेवा डॉकर-कंपोज़ के साथ चल रहा है

मैं उपयोग कर रहा हूँ docker-compose.

कुछ आदेश जैसे up -d service_name या start service_name तुरंत लौट रहे हैं और यह बहुत उपयोगी है यदि आप नहीं चाहते कि कंटेनर शेल की स्थिति पर निर्भर रहें, जैसे वे नियमित रूप से करते हैं up service_name. एक उपयोग-मामला इसे किसी प्रकार के निरंतर एकीकरण/वितरण सर्वर से चला रहा है ।

लेकिन सेवाओं को चलाने/शुरू करने का यह तरीका बाद में सेवा की वास्तविक स्थिति के बारे में कोई प्रतिक्रिया नहीं देता है ।

डॉकर के लिए सीएलआई संदर्भ लिखें up आदेश प्रासंगिक विकल्प का उल्लेख करता है, लेकिन, संस्करण के लिए 1.7.1, यह पारस्परिक रूप से अनन्य है -d:

--abort-on-container-exit  Stops all containers if any container was stopped.                           *Incompatible with -d.*

क्या मैं किसी तरह मैन्युअल रूप से जांच सकता हूं कि कंटेनर वास्तव में काम कर रहा है और कुछ त्रुटि के कारण बंद नहीं हुआ है?

  • docker-compose ps -q <service_name> कंटेनर आईडी प्रदर्शित करेगा चाहे वह चल रहा हो या नहीं, जब तक यह बनाया गया था ।
  • docker ps केवल वही दिखाता है जो वास्तव में चल रहे हैं ।

आइए इन दो आदेशों को मिलाएं:

if [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q <service_name>)` ]; then  echo "No, it's not running."else  echo "Yes, it's running."fi

docker ps डिफ़ॉल्ट रूप से आईडी का छोटा संस्करण दिखाता है, इसलिए हमें निर्दिष्ट करने की आवश्यकता है --no-trunc झंडा।

अद्यतन करें: यदि सेवा नहीं चल रही थी तो इसने "ग्रेप उपयोग" चेतावनी दी । @डज़ुनेट के लिए धन्यवाद, यहां अद्यतन उत्तर है।

if [ -z `docker-compose ps -q <service_name>` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q <service_name>)` ]; then  echo "No, it's not running."else  echo "Yes, it's running."fi

संस्करण के लिए के रूप में 1.7.1, ऐसे कोई कमांड बिल्ट-इन नहीं हैं ।

इसके बजाय, exec इसी तरह इस्तेमाल किया जा सकता ।

जब आप इसे उस सेवा के लिए चलाते हैं जिसमें कुछ कंटेनर होते हैं तो यह ठीक चलेगा:

~/apperture-science $ docker-compose exec chell echo 'Still alive!'Still alive!~/apperture-science $ echo $?0

लेकिन जब आप इसे उस सेवा के लिए चलाते हैं जिसमें कोई दौड़ नहीं है सेवा कंटेनर, यह एक त्रुटि दिखाएगा:

~/apperture-science $ docker-compose exec glados echo "Still alive!"ERROR: No container found for apperture-science-glados_1~/apperture-science $ echo $?1

तो, इसका उपयोग जांचने के लिए किया जा सकता है, क्या दी गई सेवा के लिए कोई "जीवित" कंटेनर है ।

देखने के लिए सभी सेवाएं चल रही हैं:

docker-compose ps --services --filter "status=running"

देखने के लिए कि क्या आपकी सेवा चल रहा है:

docker-compose ps --services --filter "status=running" | grep <your-service>

ध्यान दें कि --filter के साथ प्रयोग किया जाना चाहिए --services किसी विदेशी कारण से ।

आप चला सकते हैं:

docker-compose ps -q service-name

और आपको कंटेनर की आईडी मिल जाएगी यदि service-name चल रहा है । कुछ इस तरह:

18a04e61240d8ffaf4dc3f021effe9e951572ef0cb31da7ce6118f681f585c7f

यदि सेवा नहीं चल रही है तो आउटपुट खाली है, इसलिए यदि आप इसे स्क्रिप्ट में उपयोग करना चाहते हैं तो आप कुछ ऐसा कर सकते हैं:

IS_RUNNING=`docker-compose ps -q service-name`if [[ "$IS_RUNNING" != "" ]]; then    echo "The service is running!!!"fi

मुझे एक समान आवश्यकता थी । हालांकि, मेरे पास एक है restart: always मेरे वातावरण में । तो यह पता लगाना थोड़ा मुश्किल हो सकता है कि क्या कुछ दुर्घटनाग्रस्त हो रहा है और लूप में पुनरारंभ हो रहा है ।

मैंने बनाए गए और प्रारंभ समय की तुलना करने के लिए एक आइसिंगा/नागियोस चेक बनाया । शायद यह लाइन के नीचे किसी और के लिए उपयोगी है:

#!/usr/bin/env pythonfrom __future__ import print_functionimport argparsefrom datetime import timedeltafrom datetime import datetimeimport sysfrom dateutil.parser import parse as parse_dateimport dockerimport pytzparser = argparse.ArgumentParser()parser.add_argument("compose_project",                    help="The name of the docker-compose project")parser.add_argument("compose_service",                    help="The name of the docker-compose service")args = vars(parser.parse_args())client = docker.from_env()service_containers = client.containers.list(filters={    "label": [        "com.docker.compose.oneoff=False",        "com.docker.compose.project={}".format(args["compose_project"]),        "com.docker.compose.service={}".format(args["compose_service"])    ]})if len(service_containers) == 0:    print("CRITICAL: project({})/service({}) doesn't exist!".format(        args["compose_project"], args["compose_service"]))    sys.exit(2)elif len(service_containers) > 1:    print("CRITICAL: project({})/service({}) has more than 1 "          "container!".format(              args["compose_project"], args["compose_service"]))    sys.exit(2)service_container = service_containers[0]created_at = parse_date(service_container.attrs['Created'])status = service_container.attrs['State']['Status']started_at = parse_date(service_container.attrs['State']['StartedAt'])now = datetime.utcnow().replace(tzinfo=pytz.utc)uptime = now - started_atif status in ['stopped', 'exited', 'dead']:    print("CRITICAL: project({})/service({}) is status={}".format(        args["compose_project"], args["compose_service"], status))    sys.exit(2)if (started_at - created_at) > timedelta(minutes=5):    if uptime < timedelta(seconds=5):        print("CRITICAL: project({})/service({}) appears to be "              "crash-looping".format(                  args["compose_project"], args["compose_service"]))        sys.exit(2)if status == "restarting":    print("WARNING: project({})/service({}) is restarting".format(        args["compose_project"], args["compose_service"]))    sys.exit(1)print ("OK: project({})/service({}) is up for {}".format(    args["compose_project"], args["compose_service"], uptime))sys.exit(0)

यहां एक साधारण एक लाइनर है जो सेवा की वर्तमान स्थिति देता है:

docker inspect --format "{{.State.Status}}" $(docker-compose ps -q your_service_name)

यह केवल डॉकर कंटेनर की स्थिति लौट रहा है । यदि आप अपने आवेदन की वास्तविक स्थिति की जांच करना चाहते हैं तो आपको अपने डॉकरफाइल में हेल्थचेक जोड़ना चाहिए (https://docs.docker.com/engine/reference/builder/#healthcheck). बाद में आप इसके साथ निरीक्षण कर सकते हैं:

docker inspect --format "{{.State.Health.Status}}" $(docker-compose ps -q your_service_name)

इस बारे में कैसे?

docker-compose ps | awk '$4 == "Up" {print $1}' | grep <service-name>

आप प्रक्रियाओं को सूचीबद्ध करते हैं, उन पंक्तियों का चयन करते हैं जहां "ऊपर" कॉलम 4 में है और सेवा नाम पर एक मैच के लिए फ़िल्टर करें ।

यदि आप इस परिदृश्य को मानते हैं:

  • कंटेनर या तो अनिश्चित काल तक शुरू होते हैं और चलते हैं या त्रुटि कोड के साथ तुरंत बंद हो जाते हैं (यानी लापता कॉन्फ़िगरेशन के लिए)
  • डॉकर-कंपोज़ अप-डी रिटर्न के बाद आप केवल एक बार चेक करते हैं

आप जांच सकते हैं कि किसी त्रुटि के कारण कोई रोका गया कंटेनर है या नहीं:docker ps -a | grep 'Exited (255)'.

यह चेक उन कंटेनरों के मामले में भी सही ढंग से काम करता है, जिनके बिना किसी त्रुटि (यानी डेटा कंटेनर) के साथ तुरंत बंद होने की उम्मीद है, उनकी स्थिति के रूप में (से docker ps -a) के रूप में चिह्नित है Exited (0).

उदाहरण के लिए, हमारे डॉकर-रचना में । वाईएमएल, हम अपने कंटेनरों को शुरू करते हैं:

command: sh -c 'node dotenv_check.js && pm2 start --no-daemon src/worker.js --watch'

पीएचपी-एफपीएम के लिए, हम एक समान कमांड का उपयोग करते हैं:

command: >-  sh -c '  set -e;  for PROJECT in frontend backend; do    cd /var/www/$${PROJECT};    php dotenv_check.php;  done;  php-fpm  '

dotenv_check.js और dotenv_check.php वे स्क्रिप्ट हैं जो एक आवश्यक एनवी चर गायब होने की स्थिति में त्रुटि कोड से बाहर निकलती हैं ।

set -e कमांड, स्क्रिप्ट को त्रुटि पर रोकने के लिए कहता है, जो बदले में, तुरंत कंटेनर को रोक देगा । सेट-ई के बारे में

आप के लिए ग्रेप कर सकते हैं (healthy) या / और (unhealthy) छवियों को ठीक से कार्य करने के लिए ।

इस उदाहरण में, मैं डॉकर की जांच कर रहा हूं-सेवा चलाने के लिए प्रत्येक 5 सेकंड की रचना करें (healthy) स्थिति।यदि स्क्रिप्ट को ऐसी सेवा मिलेगी, तो यह निष्पादन को तोड़ देगा । यदि स्क्रिप्ट 300 सेकंड से अधिक हो जाएगी, तो यह त्रुटि कोड के साथ बाहर निकल जाएगी ।

#!/bin/bashSECONDS=0LIMIT=300x=$(docker-compose -f /mnt/<service>/docker-compose.yaml ps <service> | grep -c '(healthy)')while [[ $x == "0" ]]; do    echo "Please wait until <service> becomes healthy"    sleep 5    x=$(docker-compose -f /mnt/<service>/docker-compose.yaml ps <service> | grep -c '(healthy)')    EXPIRED=$SECONDS    if [[ $x == "1" ]]; then      echo "<service> is healthy..."      break    elif [[ $LIMIT -lt $EXPIRED ]]; then      echo "<service> startup has exceeded 5m timeout, exiting!"      exit 1    fidone

अल्मक्विस्टा के उत्तर के आधार पर यहां एक सरलीकृत एक-लाइनर है:

docker ps -q --no-trunc | grep -q "^$(docker-compose ps -q app-service)$"

हम ग्रेप का उपयोग करते हैं -q ध्वज इसलिए एक गैर-शून्य निकास कोड इंगित करता है कि सेवा नहीं चल रही है । उदाहरण के लिए:

if docker ps -q --no-trunc | grep -q "^$(dc-audo-dev ps -q app-service)$"; then    echo "Container is still running..."fi