У меня есть VPS общего назначения, и я докерирую приложения на нем. На нем будет около 5-6 контейнеров и очень мало других, поэтому ящик можно тривиально перестроить по мере необходимости.
Для каждого приложения у меня есть стартовый скрипт. Контейнер WordPress выглядит так:
#!/bin/bash
# Get the host IP address
export DOCKER_HOSTIP=`ifconfig docker0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1`
echo "Connecting to database on Docker host ${DOCKER_HOSTIP}"
docker run \
--add-host=docker:${DOCKER_HOSTIP} \
--network dockernet \
--network-alias jonblog \
--detach \
--restart always \
--rm \
jonblog
Однако это возвращает ошибку:
Конфликтующие параметры: --restart и --rm
Есть несколько тикетов Docker, в которых говорится, что это разумно, но я этого не понимаю. Думаю, смысл ясен: если контейнер не запущен (например, при запуске), я хочу его запустить. Если он умрет, я ожидаю, что контейнер будет удален, а новый новый будет создан из базового образа. Контейнеры в любом случае должны быть неизменными - любое состояние, которое я хочу сохранить, например файлы мультимедиа и журналы, будет записано на тома.
Итак, я подумал, что должен бросить --restart
флаг, а затем используйте диспетчер процессов для остановки и запуска контейнеров Docker. Могу я здесь использовать Monit? Я надеялся, что смогу сделать что-то вроде:
CHECK PROCESS jonblog MATCHING jonblog
START PROGRAM = "/root/docker/jonblog/host-start.sh"
STOP PROGRAM = "docker stop jon-blog"
Однако это проверяет таблицу системных процессов, а не docker ps
, и поэтому он не найдет ничего, соответствующего указанной строке. Могу я заставить его выполнить docker ps
периодически и совпадают строки на выходе?
Я был бы рад использовать другой инструмент, если он окажется надежным. Например, я считаю Supervisor немного тяжелым, но если он лучше работает с Docker, я готов его использовать.
Причина, по которой я хочу --rm
заключается в том, что во время процесса Dockerisation я останавливаю работающий в данный момент контейнер, load
новую версию изображения и повторно запустите указанный выше сценарий. Это означает, что Docker получает уведомление о restart
политика для каждого контейнера. Я обнаружил, что после перезагрузки компьютера у меня будет одновременно работать около 15 слегка различающихся версий приложения, что не является намерением.
Полагаю, я мог бы использовать docker update --restart never
на старых контейнерах, чтобы этого не произошло, но затем, когда мой контейнер останавливается, я остаюсь с ним валяться и сразу же автоматически удаляю его. Я мог периодически очищать старые, используя какую-то работу cron, но это кажется немного взломанным, учитывая, что Docker может сделать это за меня.
Очень полезный комментарий предложил мне изучить Minikube, который, по-видимому, упрощает настройку Kubernetes, даже до такой степени, что достаточно квалифицированный человек может быть запущен за пять минут.
Я все еще очень хотел бы видеть более легкие решения, поэтому у меня есть ряд ответов на выбор. Как указано, я хотел бы узнать ответ на вопрос, будет ли работать супервизор процесса, такой как Monit.
Сверху в голове я мог бы написать цикл оболочки, чтобы написать docker ps
к файлу каждые пять секунд в течение минуты, а затем запускать его в Cron каждую минуту. Затем я мог сканировать этот файл, используя grep
и Монит CHECK PROGRAM
Проверка системы. Это немного взломано, но я могу легко понять, если с этим возникла проблема. Есть какие-нибудь улучшения по этому поводу?
У меня есть ответ, который подходит для моего нынешнего понимания Docker. В комментариях мне посоветовали попробовать Minikube, и хотя, несомненно, это можно быстро развернуть, я опасался, что это будет кроличья нора обучения, из-за которой я застряну в дегте на несколько недель. Один из моих инженерных принципов - знать, когда вы достигли когнитивного предела для наполнения новой информацией!
Таким образом, я решил решить эту проблему простым способом. У меня было два варианта:
Я начал с первого из них, с мыслью, что было бы неплохо использовать супервизор процессов Monit, отчасти потому, что он легкий, а отчасти потому, что я с ним знаком. Однако это начало казаться неправильным решением, поскольку я работал над основной проблемой, заключающейся в том, что он не может получить список процессов контейнера Docker.
Фактически, второй вариант был намного чище, и это было усилено тем фактом, что остановленная очистка контейнеров на самом деле не является приоритетом - это просто для поддержания порядка. Конечно, я использовал для этого Docker; вот Dockerfile
:
# Docker build script for Docker Tidy
FROM alpine:3.6
RUN apk update
RUN apk add docker
# See this for BusyBox cron schedules
# https://gist.github.com/andyshinn/3ae01fa13cb64c9d36e7
COPY bin/docker-tidy.sh /etc/periodic/daily/
RUN chmod +x /etc/periodic/daily/docker-tidy.sh
# Start Cron in the foreground
ENTRYPOINT ["crond", "-l", "2", "-f"]
А вот bin/docker-tidy.sh
:
#!/bin/sh
#
# With thanks to:
# http://www.doublecloud.org/2015/05/simple-script-to-list-and-remove-all-stopped-docker-containers/
docker rm -v $(docker ps -a -q -f status=exited)
Наконец, одним из недостатков моего решения является то, что если хост перезагружается до остановки очистки контейнера, кажется, что эти контейнеры также перезапускаются. Поэтому я сбрасываю политику перезапуска для этих контейнеров перед запуском новых.
Например, вот как я запускаю сам контейнер Docker Tidy на хосте. На практике я собрал код изменения политики в отдельный сценарий, но это даст общее представление:
#!/bin/bash
# Removes the restart policy from previous containers
CONTAINER_LABEL=docker-tidy-instance
docker ps --all --filter label=$CONTAINER_LABEL --quiet | xargs --no-run-if-empty docker update --restart no
docker run \
--label $CONTAINER_LABEL \
--volume /var/run/docker.sock:/var/run/docker.sock \
--detach \
--restart always \
docker-tidy