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


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.