Periksa apakah container / service berjalan dengan docker-compose

Saya menggunakan docker-compose.

Beberapa perintah seperti up -d service_name atau start service_name kembali segera dan ini cukup berguna jika Anda tidak ingin wadah berjalan bergantung pada keadaan shell, seperti yang mereka lakukan dengan biasa up service_name. Satu kasus penggunaan menjalankannya dari beberapa jenis server integrasi/pengiriman berkelanjutan.

Tetapi cara menjalankan/memulai layanan ini tidak memberikan umpan balik apa pun tentang keadaan layanan yang sebenarnya setelahnya.

The Docker menulis referensi CLI untuk up perintah memang menyebutkan opsi yang relevan, tetapi, untuk versi 1.7.1, itu saling eksklusif dengan -d:

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

Dapatkah saya entah bagaimana secara manual memeriksa bahwa wadah memang berfungsi dan belum berhenti karena beberapa kesalahan?

  • docker-compose ps -q <service_name> akan menampilkan ID penampung tidak peduli itu berjalan atau tidak, selama itu dibuat.
  • docker ps menunjukkan hanya mereka yang benar-benar berjalan.

Mari kita menggabungkan dua perintah ini:

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 menunjukkan versi pendek dari ID secara default, jadi kita perlu menentukan --no-trunc bendera.

Pembaruan: Ini melemparkan" grep penggunaan " peringatan jika layanan tidak berjalan. Terima kasih kepada @ Dzhuneyt, inilah jawaban yang diperbarui.

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

Adapun versi 1.7.1, tidak ada perintah seperti itu built-in.

Sebagai gantinya, the exec dapat digunakan dengan cara yang sama.

Ketika Anda menjalankannya untuk layanan yang memiliki beberapa wadah, itu akan berjalan dengan baik:

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

Tetapi ketika Anda menjalankannya untuk layanan yang tidak berjalan layanan kontainer, ia akan menampilkan kesalahan:

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

Jadi, dapat digunakan untuk memeriksa, apakah ada wadah "hidup" untuk layanan yang diberikan.

Untuk melihat semua layanan berjalan:

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

Untuk melihat apakah layanan Anda sedang berjalan:

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

Perhatikan bahwa --filter harus digunakan dengan --services untuk beberapa alasan asing.

Anda dapat menjalankan:

docker-compose ps -q service-name

Dan Anda akan mendapatkan ID dari wadah jika service-name sedang berjalan. Sesuatu seperti:

18a04e61240d8ffaf4dc3f021effe9e951572ef0cb31da7ce6118f681f585c7f

Jika layanan tidak berjalan output kosong, jadi jika Anda ingin menggunakan ini dalam script Anda dapat melakukan sesuatu seperti:

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

Saya memiliki kebutuhan yang sama. Namun, saya memiliki restart: always di lingkungan saya. Jadi mungkin agak sulit untuk mendeteksi jika ada sesuatu yang mogok dan memulai ulang dalam satu lingkaran.

Saya membuat pemeriksaan Icinga / Nagios untuk juga membandingkan waktu yang dibuat dan mulai. Mungkin itu berguna untuk orang lain di telepon:

#!/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)

Berikut ini adalah Satu liner sederhana yang mengembalikan status layanan saat ini:

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

Ini hanya mengembalikan status wadah buruh pelabuhan. Jika Anda ingin memeriksa keadaan sebenarnya dari aplikasi Anda, Anda harus menambahkan HEALTHCHECK ke Dockerfile Anda (https://docs.docker.com/engine/reference/builder/#healthcheck). Setelah itu Anda dapat memeriksanya dengan:

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

Bagaimana dengan ini?

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

Anda daftar proses, pilih baris di mana" up " di kolom 4 dan menyaring melalui untuk pertandingan pada nama layanan.

Jika Anda menganggap skenario ini:

  • kontainer mulai dan berjalan tanpa batas waktu atau segera berhenti dengan kode kesalahan (yaitu untuk konfigurasi yang hilang)
  • anda melakukan pemeriksaan hanya sekali setelah docker-compose up-d kembali

Anda dapat memeriksa apakah ada wadah yang berhenti karena kesalahan dengan:docker ps -a | grep 'Exited (255)'.

Pemeriksaan ini berfungsi dengan benar bahkan dalam kasus wadah yang diharapkan segera berhenti tanpa kesalahan( yaitu wadah data), sebagai statusnya (dari docker ps -a) ditandai sebagai Exited (0).

Misalnya, dalam docker-compose kami.yml, kita mulai kontainer kami dengan:

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

Untuk php-fpm, kami menggunakan perintah serupa:

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

The dotenv_check.js dan dotenv_check.php adalah skrip yang keluar dengan kode kesalahan jika variabel env yang diperlukan tidak ada.

The set -e perintah, memberitahu script untuk berhenti pada kesalahan, yang, pada gilirannya, akan segera menghentikan wadah. Tentang set-e

Anda dapat grep untuk (healthy) atau / dan (unhealthy) gambar untuk bertindak dengan benar.

Dalam contoh ini, saya menyelidiki docker-compose setiap 5 detik untuk menjalankan layanan dengan (healthy) status.Jika script akan menemukan layanan tersebut, itu akan mematahkan eksekusi.Jika script akan melebihi 300 detik, itu akan keluar dengan kode kesalahan.

#!/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