Перевірка, чи контейнер / послуга працює з докер-композитом


22

Я використовую docker-compose.

Деякі команди люблять up -d service_nameабо start service_nameповертаються відразу, і це дуже корисно, якщо ви не хочете, щоб контейнери працювали залежали від стану оболонки, як це робиться з регулярними up service_name. Один з випадків використання - це запуск його з якогось неперервного сервера інтеграції / доставки.

Але такий спосіб запуску / запуску послуг не надає жодного відгуку про фактичний стан сервісу після цього.

Посилання CLI на upкоманду Docker Compose зазначає відповідний варіант, але, що стосується версії 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> відображатиме ідентифікатор контейнера незалежно від того, працює він чи ні, доки він був створений.
  • 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прапор.

ОНОВЛЕННЯ : Якщо сервіс не працював, він кинув попередження "використання грепу". Завдяки @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

Хороший, і він також вирішує проблему з поточною відповіддю, яка була заявлена ​​в коментарях. Позначивши це новою відповіддю.
Іван Колмичек

1
Якщо ви використовуєте політику перезавантаження, вам також потрібно її відфільтрувати, щоб вона включала лише запущені контейнери (а не ті, що перебувають у стані перезавантаження):docker ps -q -f "status=running" --no-trunc | grep $(docker-compose ps -q <service_name>)
Макс

1
Це працює, але викидає попередження "grep використання", якщо служба не працює, іншими словами, коли grep ....частина закінчується порожнім рядком.
Джунейт

@Dzhuneyt Я знаю, так, ти маєш рацію. Думки про те, щоб уникнути / обробляти це греп-попередження?
elquimista

1
@elquimista Так, я вирішив його з допомогою оператора OR: if [ -z `docker-compose ps -q mysql` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q mysql)` ]; then. Це означає: він спочатку перевіряє, чи служба існує взагалі (навіть якщо вона зупинена), а друга частина перевіряє, чи наявна служба працює. Ви можете включити це у свій приклад для майбутніх читачів, які розглядають лише прийняту відповідь. Я думаю, що це корисно.
Джунейт

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

Так, це теж працює. Позначив це зараз як відповідь.
Іван Колмичек

12
Це не говорить вам про те, чи працює контейнер чи ні, просто він існує чи ні. Спробуйте виконати docker-compose upCtrl-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

Якщо ви припускаєте такий сценарій:

  • контейнери або запускаються та працюють безстроково, або негайно зупиняються кодом помилки (тобто для відсутньої конфігурації)
  • Ви перевіряєте лише один раз після повернення docker-compose up -d

Ви можете перевірити, чи є якийсь - або зупинений контейнер з - за помилки з: docker ps -a | grep 'Exited (255)'.

Ця перевірка працює правильно навіть у випадку контейнерів, які, як очікується, зупиняться негайно (тобто контейнери даних), оскільки їх статус (від 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скрипти, вихід з кодом помилки в разі необхідності змінна окр відсутня.

set -eКоманда, повідомляє скрипт зупинитися на помилки, які, в свою чергу, буде негайно зупинити контейнер. Про сет-е


0

Як щодо цього?

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

ви перераховуєте процеси, вибираєте рядки, де "вгору" стовпчик 4, і фільтруєте для відповідності на ім'я служби.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.