Docker-compose ile çalışan konteyner / hizmet olup olmadığını kontrol edin


22

Ben kullanıyorum docker-compose.

Bazı komutlar hemen geri döner up -d service_nameveya start service_namegeri dönerler ve kapların normal durumda olduğu gibi kabuğun durumuna bağlı olarak çalışmasını istemiyorsanız oldukça yararlıdır up service_name. Tek kullanımlık durum, onu bir çeşit sürekli entegrasyon / dağıtım sunucusundan çalıştırmaktır.

Ancak hizmetlerin bu şekilde çalıştırılması / başlatılması, daha sonra hizmetin gerçek durumu hakkında herhangi bir geri bildirim sağlamaz.

İçin Docker Oluştur CLI referans upkomutu çeşitte olduğu gibi, ilgili seçeneği söz yok, ama 1.7.1bu karşılıklı özeldir -d:

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

Bir şekilde kabın gerçekten çalıştığını ve bir hata nedeniyle durmadığını manuel olarak kontrol edebilir miyim?

Yanıtlar:


15
  • docker-compose ps -q <service_name> konteyner kimliğini, çalışıp çalışmadığına bakılmaksızın, yaratıldığı sürece gösterecektir.
  • docker ps sadece gerçekten çalışanları gösterir.

Bu iki komutu birleştirelim:

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 psvarsayılan olarak kimliklerin kısa versiyonunu gösterir, bu yüzden --no-truncbayrak belirtmeliyiz .

GÜNCELLEME : Servis çalışmıyorsa "grep use" uyarısı attı. @Dzhuneyt'e teşekkürler, işte güncellenmiş cevap.

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

Güzel olanı ve yorumlarda belirtilen mevcut cevapla ilgili sorunu da ele alıyor. Bunu yeni bir cevap olarak işaretliyorum.
Ivan Kolmychek

1
Yeniden başlatma politikası kullanıyorsanız, yalnızca çalışan kapsayıcıları (yeniden başlatma durumunda olanlar yerine) içerecek şekilde filtrelemeniz gerekir:docker ps -q -f "status=running" --no-trunc | grep $(docker-compose ps -q <service_name>)
Maks

1
Bu çalışır ancak hizmet çalışmıyorsa, başka bir deyişle, grep ....parça boş bir dizeyle sona erdiğinde "grep use" uyarısı verir .
Dzhuneyt

@Dzhuneyt biliyorum, haklısın. Bu grep uyarısını önlemek / kullanmak için düşünceler?
elquimista

1
Evet @elquimista, ben VEYA operatörünü kullanarak çözdü: if [ -z `docker-compose ps -q mysql` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q mysql)` ]; then. Bunun ne olduğu: önce hizmetin mevcut olup olmadığını (durdurulmuş olsa bile) kontrol eder ve ikinci bölüm mevcut hizmetin gerçekten çalışıp çalışmadığını kontrol eder. Bunu, sadece kabul edilen cevaplara göz gezdiren gelecek okuyucular için örneğinize dahil etmek isteyebilirsiniz. Bence faydalı.
Dzhuneyt

12

Versiyona gelince 1.7.1, yerleşik böyle bir komut yoktur.

Bunun yerine, execbenzer şekilde kullanılabilir.

Bir miktar konteynırlı servis için çalıştırdığınızda, tamam:

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

Ancak çalışan servis konteyneri olmayan servis için çalıştırdığınızda , bir hata gösterecektir:

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

Bu nedenle, kontrol etmek için kullanılabilir, verilen hizmet için herhangi bir "canlı" kap var mıdır.


5

Koşabilirsin:

docker-compose ps -q service-name

Ve eğer service-nameçalışıyorsa kabın kimliğini alacaksın . Gibi bir şey:

18a04e61240d8ffaf4dc3f021effe9e951572ef0cb31da7ce6118f681f585c7f

Hizmet çalışmıyorsa, çıktı boştur, bu nedenle bir komut dosyasında kullanmak istiyorsanız aşağıdaki gibi bir şey yapabilirsiniz:

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

Evet, bu da işe yarıyor. Bunu şimdi cevap olarak işaretledim.
Ivan Kolmychek

12
Bu, kabın çalışıp çalışmadığını, yalnızca var olup olmadığını söylemez. docker-compose upCtrl-C yapmayı deneyin . docker-compose psdaha sonra konteyner durumlarının "Yukarı" olmadığını göstermeli , ancak docker-compose ps -q service-nameyine de size bir kimlik vermektedir.
djanderson

2

Ben de benzer bir ihtiyaç vardı. Ancak restart: alwaysçevremde bir tane var . Bu nedenle, bir döngünün içinde bir şeyin çöküp yeniden başladığını tespit etmek biraz zor olabilir.

Ayrıca oluşturulan ve başlangıç ​​zamanlarını karşılaştırmak için bir Icinga / Nagios kontrolü yaptım. Belki de bu hattın altındaki bir başkası için faydalıdır:

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

Bu senaryoyu varsayarsanız:

  • konteynerler ya başlar ve süresiz çalışır veya bir hata koduyla derhal durur (örneğin, eksik yapılandırma için)
  • docker-bestele-up dönüşlerinden sonra sadece bir kez kontrol yaparsınız

Herhangi durdurulmuş kabı varsa nedeniyle ilgili bir hata kontrol edebilirsiniz: docker ps -a | grep 'Exited (255)'.

Bu kontrol, derhal durması beklenen kaplar (örneğin veri kapları) durumunda, durumları ( docker ps -aişaretli) olarak işaretlendiğinden bile doğru çalışır Exited (0).

Örneğin, docker-compose.yml dosyasında, konteynerlerimizle şu şekilde başlıyoruz:

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

Php-fpm için benzer bir komut kullanırız:

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

dotenv_check.jsVe dotenv_check.phpgerekli bir env değişkeni eksik durumda bir hata kodu ile hangi çıkış komut dosyalarıdır.

set -eKomut, sırayla, kap hemen duracaktır olan, hata durdurmak için komut söyler. Set-e hakkında


0

Buna ne dersin?

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

İşlemleri listeler, "Yukarı" nın 4. sütunda olduğu satırları seçip servis adında bir eşleşme için filtrelersiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.