ตรวจสอบว่าเป็นคอนเทนเนอร์ / บริการทำงานด้วยนักเทียบท่าเขียน


22

docker-composeฉันใช้

คำสั่งบางคนชอบup -d service_nameหรือจะกลับทันทีและนี่คือประโยชน์สวยถ้าคุณไม่ต้องการภาชนะที่ใช้ขึ้นอยู่กับสถานะของเปลือกเช่นที่พวกเขาทำกับปกติstart service_name up service_nameกรณีใช้เดียวกำลังเรียกใช้จากเซิร์ฟเวอร์การรวม / การจัดส่งบางประเภท

แต่วิธีการทำงาน / เริ่มบริการนี้ไม่ได้ให้ข้อเสนอแนะใด ๆ เกี่ยวกับสถานะที่แท้จริงของบริการในภายหลัง

การอ้างถึงupคำสั่งDocker Compose CLI สำหรับคำสั่งไม่พูดถึงตัวเลือกที่เกี่ยวข้อง แต่สำหรับรุ่น1.7.1นั้นจะไม่สามารถใช้ร่วมกับ-d:

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

ฉันสามารถตรวจสอบด้วยตนเองได้ว่าภาชนะนั้นทำงานจริงและยังไม่หยุดเพราะข้อผิดพลาดบางอย่าง?

คำตอบ:


15
  • docker-compose ps -q <service_name> จะแสดง ID คอนเทนเนอร์ไม่ว่าจะทำงานหรือไม่ก็ตามตราบใดที่มันถูกสร้างขึ้น
  • 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ตั้งค่าสถานะ

ปรับปรุง : มันโยน "การใช้ grep" คำเตือนหากบริการไม่ได้ทำงานอยู่ ขอบคุณ @Dzhuneyt นี่คือคำตอบล่าสุด

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

ดีมากและยังแก้ไขปัญหาของคำตอบปัจจุบันที่ระบุไว้ในความคิดเห็น ทำเครื่องหมายว่านี่เป็นคำตอบใหม่
Ivan Kolmychek

1
หากคุณกำลังใช้นโยบายการเริ่มระบบใหม่คุณจำเป็นต้องกรองให้รวมเฉพาะการเรียกใช้คอนเทนเนอร์ (แทนที่จะเป็นสถานะการรีสตาร์ท):docker ps -q -f "status=running" --no-trunc | grep $(docker-compose ps -q <service_name>)
สูงสุด

1
วิธีนี้ใช้งานได้ แต่จะส่งสัญญาณเตือน "การใช้ grep" หากบริการไม่ทำงานหรืออีกนัยหนึ่งเมื่อgrep ....ส่วนนั้นลงท้ายด้วยสตริงว่าง
Dzhuneyt

@ Dzhuneyt ฉันรู้ว่าใช่คุณพูดถูก คิดว่าจะหลีกเลี่ยง / จัดการกับคำเตือน grep นั้นหรือไม่
elquimista

1
@elquimista if [ -z `docker-compose ps -q mysql` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q mysql)` ]; thenใช่ฉันจะแก้ไขได้โดยใช้หรือผู้ประกอบการ: สิ่งนี้คือ: ตรวจสอบก่อนว่าบริการมีอยู่จริงหรือไม่ (แม้ว่าจะหยุดทำงาน) และส่วนที่สองจะตรวจสอบว่าบริการที่มีอยู่นั้นกำลังทำงานอยู่หรือไม่ คุณอาจต้องการรวมสิ่งนี้ไว้ในตัวอย่างของคุณสำหรับผู้อ่านในอนาคตที่มองข้ามคำตอบที่ยอมรับเท่านั้น ฉันคิดว่ามันมีประโยชน์
Dzhuneyt

12

สำหรับเวอร์ชั่น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

ดังนั้นจึงสามารถใช้เพื่อตรวจสอบว่ามีคอนเทนเนอร์ "ชีวิต" สำหรับการให้บริการหรือไม่


5

คุณสามารถเรียกใช้:

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

ใช่มันก็ใช้ได้เช่นกัน ทำเครื่องหมายว่านี่เป็นคำตอบทันที
Ivan Kolmychek

12
สิ่งนี้ไม่ได้บอกคุณว่าคอนเทนเนอร์กำลังทำงานอยู่หรือไม่ถ้ามีอยู่หรือไม่ ลองทำdocker-compose upแล้วกด Ctrl-C docker-compose psควรแสดงให้เห็นว่าสถานะคอนเทนเนอร์ไม่ใช่ "ขึ้น" แต่docker-compose ps -q service-nameยังคงให้รหัสคุณ
djanderson

2

ฉันมีความต้องการที่คล้ายกัน อย่างไรก็ตามฉันมีrestart: alwaysในสภาพแวดล้อมของฉัน ดังนั้นจึงเป็นการยากที่จะตรวจสอบว่ามีบางสิ่งผิดพลาดและเริ่มใหม่ในลูป

ฉันทำการตรวจสอบ Icinga / Nagios เพื่อเปรียบเทียบเวลาที่สร้างและเริ่มต้นด้วย อาจเป็นประโยชน์กับคนอื่นในบรรทัด:

#!/usr/bin/env python
from __future__ import print_function
import argparse
from datetime import timedelta
from datetime import datetime
import sys

from dateutil.parser import parse as parse_date
import docker
import pytz
parser = 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_at

if 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)

0

หากคุณสมมติสถานการณ์นี้:

  • ภาชนะเริ่มต้นและเรียกใช้ไปเรื่อย ๆ หรือหยุดทันทีด้วยรหัสข้อผิดพลาด
  • คุณทำการตรวจสอบเพียงครั้งเดียวหลังจากนักเทียบท่าเขียนผลตอบแทน -d

คุณสามารถตรวจสอบว่ามีภาชนะหยุดใด ๆ docker ps -a | grep 'Exited (255)'อันเนื่องจากข้อผิดพลาดกับ:

การตรวจสอบนี้ทำงานอย่างถูกต้องแม้ในกรณีของภาชนะบรรจุซึ่งคาดว่าจะหยุดทันทีไม่มีข้อผิดพลาด (ภาชนะบรรจุข้อมูล IE) เป็นสถานะของพวกเขา (จากdocker ps -a) Exited (0)ถูกทำเครื่องหมายเป็น

ตัวอย่างเช่นใน docker-compose.yml ของเราเราเริ่มคอนเทนเนอร์ด้วย:

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

สำหรับ php-fpm เราใช้คำสั่งที่คล้ายกัน:

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สคริปต์ซึ่งทางออกที่มีรหัสข้อผิดพลาดในกรณีที่ตัวแปร env จำเป็นขาดหายไป

set -eคำสั่งบอกสคริปต์เพื่อหยุดข้อผิดพลาดซึ่งในการเปลี่ยนทันทีจะหยุดคอนเทนเนอร์ เกี่ยวกับ set-e


0

แล้วเรื่องนี้ล่ะ

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

คุณแสดงรายการกระบวนการเลือกบรรทัดที่ "ขึ้น" อยู่ในคอลัมน์ 4 และกรองผ่านเพื่อให้ตรงกับชื่อบริการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.