Докер - проверьте готовность postgres

У меня есть контейнер Kong API Gateway и концентратор postgres, и мне нужно проверить, запущен ли и готов ли postgres из контейнера Kong, прежде чем запускать миграции. Я думал об установке клиентских утилит postgres в пользовательский образ, основанный на официальном образе Kong, используя RUN yum install postgresql -y && yum clean all в моем Dockerfile и используя для этого либо psql, либо pg_isready. Я создал пользователя postgres с именем polling с пустым паролем специально для проверки состояния сервера этими двумя утилитами. Ни один из них не работает.

Я попытался выполнить эти команды из пользовательского образа Kong:

  1. psql. Команда psql -h postgres -U polling -w -c '\l' завершается ошибкой psql: fe_sendauth: no password supplied. Но у пользователя нет пароля. Что я делаю неправильно? Полный сценарий оболочки, проверяющий готовность сервера с помощью psql, описан здесь.

  2. pg_isready. Я не понимаю, как установить эту утилиту отдельно в пользовательский образ на основе официального образа Kong, который, в свою очередь, основан на образе centos:7, пакет postgresql не включает pg_isready. Устанавливаются только эти утилиты, их можно найти в /usr/bin: pg_config, pg_dump, pg_dumpall, pg_restore, psql. Как установить pg_isready? Я не хочу, чтобы в образе Kong была установлена ​​полная установка сервера.


person super.t    schedule 01.10.2017    source источник
comment
Что касается №1, вы изменили pg_hba.conf? См. dba.stackexchange.com/questions / 83164 /   -  person bluescores    schedule 01.10.2017
comment
@bluescores правильно, мне нужно изменить эту конфигурацию или добавить .pgpass на клиенте. Решил вопрос с последним. Я должен заметить, что мне пришлось установить пароль для моего пользователя опроса, psql кричал на меня, если проход был пуст, независимо от .pgpass   -  person super.t    schedule 02.10.2017


Ответы (4)


Вот оболочка с одним лайнером, использующая pg_isready инструмент, предоставленный PostgreSQL.

Чтобы вызвать внешний докер:

DOCKER_CONTAINER_NAME="mypgcontainer"
timeout 90s bash -c "until docker exec $DOCKER_CONTAINER_NAME pg_isready ; do sleep 5 ; done"

На основе сообщения Джеромы Беллеман.

person Mikko Ohtamaa    schedule 21.07.2020
comment
Я удивлен, что этот ответ не получил больше голосов. Я пришел к такому же выводу, он действительно работает с pg_isready, но не работает с bash-скриптом wait for-it.sh, поскольку порт TCP готов до того, как postgres действительно будет готов к работе. В противном случае вы можете получить такие ошибки: An exception occurred in driver: SQLSTATE[08006] [7] server closed the connection unexpectedly. - person COil; 30.08.2020
comment
Это новый ответ. - person Mikko Ohtamaa; 30.08.2020

Мы решаем эту проблему с помощью простой проверки TCP на порту 5432 без каких-либо инструментов PG. Мы просто используем wait-for-it.sh, и это хорошо работает. Postgres не открывает порт до тех пор, пока сервер действительно не готов к работе, так что, по-видимому, это нормально.

Пример файла Docker: https://github.com/apim-haufe-io/wicked.kong/blob/master/Dockerfile

Соответствующий стартовый скрипт (для данной конкретной задачи интересна только последняя строка): https://github.com/apim-haufe-io/wicked.kong/blob/master/startup.sh

Фрагмент:

wait-for-it.sh -h $KONG_PG_HOST -p 5432 -t 30 -- kong start --run-migrations

Подождите: https://github.com/vishnubob/wait-for-it

person donmartin    schedule 04.10.2017
comment
это не работает, когда вам нужно запустить postgres в контейнере в первый раз, поскольку сервер будет готов и попытается запустить сценарии запуска. У меня были запросы к серверу, которые, к сожалению, вызвали сбой сценария инициализации. - person jemiloii; 29.11.2018
comment
Согласен с @jemiloii. Порт доступен раньше, чем Postgres готов к запуску скриптов. - person ka3ak; 26.02.2020
comment
Я тоже видел это время от времени, но не так часто. В некоторых местах я также видел sleep 5 после возвращения ожидания, и этого обычно достаточно. Пояс и подтяжки требовали бега, ждите, спите, ждите. Обычно для меня достаточно хорошо. - person donmartin; 28.02.2020

Мое решение заключалось в том, чтобы создать новый образ на основе официального образа конга и переопределить точку входа следующим образом:

#!/usr/bin/env bash
set -e

# Disabling nginx daemon mode
export KONG_NGINX_DAEMON="off"

# Setting default prefix (override any existing variable)
export KONG_PREFIX="/usr/local/kong"

# Prepare Kong prefix
if [ "$1" = "/usr/local/openresty/nginx/sbin/nginx" ]; then
    kong prepare -p "/usr/local/kong"
fi

#waiting for postgres
until psql --host=$KONG_PG_HOST --username=$POLLING_USER $POLLING_DATABASE -w &>/dev/null
do
  echo "Waiting for PostgreSQL..."
  sleep 1
done

echo "Postgres is ready, running the migrations..."

kong migrations up

echo "READY TO START UP KONG USING CMD" $@;

exec "$@"
person super.t    schedule 21.10.2017

Я пробовал подождать, но запускать его в контейнере докера может быть проблемой, так как в образе докера может не быть установлен nc (иногда нет даже ping, telnet, curl ..). Итак, чтобы проверить, запущена ли и работает БД, я использовал HealthCheck в файле docker compose, который проверял возвращаемое значение pg_isready, что является частью базы данных postgres, поэтому вам не нужно ничего устанавливать в образы докеров:

version: '2.3'
services:
  postgres-db:
    image: postgresImage
    healthcheck:
      test: /usr/bin/pg_isready
      interval: 5s
      timeout: 10s
      retries: 120
    ports:
      - '5432:5432'

  aplication:
    image: applicationImage
    depends_on:
      postgres-db:
        condition: service_healthy
person Thuthu    schedule 19.02.2019
comment
В составлении v3 был удален файл depends_on. - person super.t; 19.02.2019
comment
@ super.t depends_on все еще присутствует в v3. - person Mike Branski; 11.10.2019