Рейтинг:1

Как запустить etcd в докере из systemd?

флаг jp

Я хочу запустить etcd (один узел) в докере из systemd, но, похоже, что-то пошло не так — он завершается примерно через 30 секунд после запуска.

Похоже, служба запускается в статусе "активация" но завершается примерно через 30 секунд, не достигая статуса "активный". Возможно, между контейнером докеров и systemd отсутствует какая-либо сигнализация?

Обновлять (см. внизу поста): статус службы systemd достигает не удалось (Результат: тайм-аут) - когда я удаляю Перезапуск = при сбое инструкция.

Когда я проверяю состояние службы etcd после загрузки, я получаю такой результат:

$ sudo systemctl status etcdâ etcd.service - etcd Loaded: загружен (/etc/systemd/system/etcd.service; включен; предустановка поставщика: отключена)
   Активно: активация (автоматический перезапуск) (Результат: код выхода) со среды 18.08.2021 20:13:30 UTC; 4 с назад
  Процесс: 2971 ExecStart=/usr/bin/docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data --name etcd my-aws-account.dkr.ecr.eu- north-1.amazonaws.com/etcd:v3.5.0 /usr/local/bin/etcd --data-dir=/etcd-data --name etcd0 --advertise-client-urls http://10.0.0.11: 2379 --listen-client-urls http://0.0.0.0:2379 --initial-advertise-peer-urls http://10.0.0.11:2380 --listen-peer-urls http://0.0.0.0: 2380 --initial-cluster etcd0=http://10.0.0.11:2380 (код=выход, статус=125)
 Основной PID: 2971 (код=выход, статус=125)

Я запускаю это на машине Amazon Linux 2 со сценарием пользовательских данных, который запускается при запуске. Я подтвердил, что докер.сервис и docker_ecr_login.service запустить успешно.

И вскоре после запуска машины я вижу, что etcd работает:

 sudo systemctl статус etcd
etcd.service - etcd
   Загружено: загружено (/etc/systemd/system/etcd.service; включено; настройка поставщика: отключена)
   Активно: активация (начало) с 18 августа 2021 г. 20:30:07 UTC; 1 мин 20 с назад
 Основной PID: 1573 (докер)
    Заданий: 9
   Память: 24,3 Мб
   Группа CG: /system.slice/etcd.service
           ââ1573 /usr/bin/docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data --name etcd my-aws-account.dkr.ecr. eu-север-1.amazonaws.com...

18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.690Z","регистратор":"плот","звонящий":"...rm 2"}
18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.691Z","вызывающий":"etcdserver/serve..."3.5"}
18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","вызывающий":"членство/группа..."3.5"}
18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","вызывающий":"etcdserver/server.go:2...
18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","вызывающий":"api/capability.g..."3.5"}
18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","вызывающий":"etcdserver/serve..."3.5"}
18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","вызывающий":"embed/serve.go:9...ests"}
18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.695Z","вызывающий":"etcdmain/main.go...emon"}
18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.695Z","вызывающий":"etcdmain/main.go...emon"}
18 августа, 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.702Z","вызывающий":"embed/serve.go:1...2379"}
Подсказка: некоторые строки были выделены эллипсами, используйте -l, чтобы показать их полностью.

Я получаю такое же поведение, когда etcd слушает IP-адрес узла (10.0.0.11) или 127.0.0.1.

Я могу запустить etcd локально из командной строки (и он не прекращается через 30 секунд), с:

sudo docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data --name etcd-local \
my-aws-account.dkr.ecr.eu-north-1.amazonaws.com/etcd:v3.5.0 \
/usr/local/bin/etcd --data-dir=/etcd-данные \
--имя etcd0 \
--advertise-client-urls http://127.0.0.1:2379 \
--listen-client-urls http://0.0.0.0:2379 \
--initial-advertise-peer-urls http://127.0.0.1:2380 \
--listen-peer-urls http://0.0.0.0:2380 \
--initial-cluster etcd0=http://127.0.0.1:2380

Параметры etcd аналогичны Запуск одного узла etcd — документация по ectd 3.5.

Это важная часть сценария запуска, которая предназначена для запуска etcd:

том sudo docker создать --name etcd-данные

кошка <<ЕОФ | sudo тройник /etc/systemd/system/etcd.service
[Ед. изм]
Описание=и т.д.
После=docker_ecr_login.service

[Оказание услуг]
Тип=уведомить
ExecStart=/usr/bin/docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data \
 --name etcd my-aws-account.dkr.ecr.eu-north-1.amazonaws.com/etcd:v3.5.0 \
 /usr/local/bin/etcd --data-dir=/etcd-данные \
 --имя etcd0 \
 --advertise-client-urls http://10.0.0.11:2379 \
 --listen-client-urls http://0.0.0.0:2379 \
 --initial-advertise-peer-urls http://10.0.0.11:2380 \
 --listen-peer-urls http://0.0.0.0:2380 \
 --initial-cluster etcd0=http://10.0.0.11:2380
Перезапуск = при сбое
Рестартсек=5

[Установить]
WantedBy=многопользовательская.цель
EOF

sudo systemctl включить etcd
sudo systemctl запустить etcd

При перечислении всех контейнеров на машине я вижу, что она запущена:

судо докер пс -а
ИДЕНТИФИКАТОР КОНТЕЙНЕРА ИЗОБРАЖЕНИЕ КОМАНДА СОЗДАНА СТАТУС ИМЕНА ПОРТОВ
a744aed0beb1 my-aws-account.dkr.ecr.eu-north-1.amazonaws.com/etcd:v3.5.0 "/usr/local/bin/etcd…" 25 минут назад Вышел (0) 24 минуты назад etcd

но я подозреваю, что его нельзя перезапустить, так как имя контейнера уже существует.

Почему контейнер etcd завершается через ~ 30 секунд при запуске из systemd? Похоже, что он успешно запущен, но systemd показывает его только в статусе «активация», но никогда не в статусе «активен», и кажется, что он завершается примерно через 30 секунд.Отсутствует ли какая-то сигнализация из док-контейнера etcd в systemd? Если да, то как мне правильно настроить эту сигнализацию?


ОБНОВИТЬ:

После удаления Перезапуск = при сбое инструкции в файле сервисного модуля, теперь я получаю статус: не удалось (Результат: тайм-аут):

$ sudo systemctl статус etcd
etcd.service - etcd
   Загружено: загружено (/etc/systemd/system/etcd.service; включено; настройка поставщика: отключена)
   Активно: не удалось (Результат: тайм-аут) со среды 18 августа 2021 г., 21:35:54 UTC; 5 минут назад
  Процесс: 1567 ExecStart=/usr/bin/docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data --name etcd my-aws-account.dkr.ecr.eu- north-1.amazonaws.com/etcd:v3.5.0 /usr/local/bin/etcd --data-dir=/etcd-data --name etcd0 --advertise-client-urls http://127.0.0.1: 2379 --listen-client-urls http://0.0.0.0:2379 --initial-advertise-peer-urls http://127.0.0.1:2380 --listen-peer-urls http://0.0.0.0: 2380 --initial-cluster etcd0=http://127.0.0.1:2380 (код=выход, статус=0/УСПЕХ)
 Основной PID: 1567 (код=выход, статус=0/УСПЕХ)

18 августа, 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.332Z","вызывающий":"утил/прервал... ат"}
18 августа, 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.333Z","вызывающий":"вставить/etcd.go:36...379"]}
18 августа 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: ПРЕДУПРЕЖДЕНИЕ: 2021/08/18 21:35:54 [ядро] grpc: addrConn. createTransport не удалось ...ing...
18 августа, 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.335Z","вызывающий":"etcdserver/serve...6a6c"}
18 августа, 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.337Z","вызывающий":"embed/etcd.go:56...2380"}
18 августа, 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.338Z","вызывающий":"embed/etcd.go:56...2380"}
18 августа, 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.339Z","вызывающий":"вставить/etcd.go:36...379"]}
18 августа, 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal systemd[1]: не удалось запустить etcd.
18 августа, 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal systemd[1]: устройство etcd.service перешло в состояние сбоя.
18 августа, 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal systemd[1]: ошибка etcd.service.
Подсказка: некоторые строки были выделены эллипсами, используйте -l, чтобы показать их полностью.
Рейтинг:1
флаг cn

Обновление: Публикация тестовых данных и интеграция обновлений на основе полученных комментариев. docker -d не требуется для интеграции с systemd, как предполагалось изначально. Параметр Type=, как указал Майкл, по моему опыту, кажется более важным, чем разгрузка демонизированного статуса службы в докер. Проблема с ОП на первый взгляд казалась побочным эффектом отсутствия предыстории, как я первоначально объяснил. Этот фон кажется неактуальным после дальнейшего тестирования.

Обратите внимание, что образ Amazon AWS, используемый в OP, не является чем-то, что я могу протестировать или непосредственно устранить неполадки. Здесь показан контрастный пример для etcd и systemd, чтобы помочь с настройкой конечной системы аналогично моему. Детали системы:

  • Убунту 20.04 ЛТС
  • докер 20.10.7
  • и т. д. 3.5.0

системная конфигурация

В итоге я получил следующий файл службы systemd. Обратите внимание, что Type=simple из-за того, что Майкл предложил прояснить этот момент в ответе (и, по-видимому, мое собственное понимание этой части головоломки). Вы можете узнать больше о типах systemd здесь:

https://www.freedesktop.org/software/systemd/man/systemd.service.html

Тип имеет значение; Более того, мое первоначальное понимание простого типа было близоруко сосредоточено на отсутствии обратной связи с systemd, из-за чего я игнорировал применимые поведение того, что делает настройка типа в ответ на ответы вызываемого приложения (в данном случае докера).

Удаление типа или добавление типа к простому в любом случае приведет к одному и тому же поведению. Следующая конфигурация в моем тесте работала надежно, как и наличие -d в команде запуска docker:

[Ед. изм]
Описание=Docker container-etcd.service
Документация=человек:докер
Требует = docker.service
Хочет=network.target
After=network-online.target

[Оказание услуг]
ExecStartPre=- /usr/bin/docker stop и т.д.
ExecStartPre=- /usr/bin/docker rm и т.д.
ExecStart=docker run --rm -d -p 2379:2379 -p 2380:2380 --volume=/home/user/etcd-data:/etcd-data --name etcd quay.io/coreos/etcd:v3. 5.0 /usr/local/bin/etcd --data-dir=/etcd-data --name etcd --initial-advertise-peer-urls http://10.4.4.132:2380 --listen-peer-urls http: //0.0.0.0:2380 --advertise-client-urls http://10.4.4.132:2379 --listen-client-urls http://0.0.0.0:2379 --initial-cluster etcd=http:// 10.4.4.132:2380
ExecStop=/usr/bin/docker stop etcd -t 10
ExecRestart=/usr/bin/перезапуск докеров и т.д.
KillMode=нет
RemainAfterExit=1
Перезапуск = при сбое
Тип=простой

[Установить]
WantedBy=multi-user.target default.target

Примечания

  • Добавлен RemainAfterExit, так как systemd будет считать службу закрытой после запуска, если она отсутствует; Отсутствие этого логического значения создает кажущуюся ошибочной ситуацию, когда докер пс показывает работающий контейнер, но Статус systemctl контейнер-etcd показал возбужденный и неактивный.
  • Файл модуля systemd несколько синтаксически неверен. %n обычно используется для строк Exec для ссылки на имя службы (например, ... перезапуск докера %n); Я не хотел вносить дополнительную путаницу, пытаясь решить проблему ОП. Не говоря уже о том, что я использовал etcd в качестве имени контейнера докера, а не container-etcd в качестве имени службы модуля.
  • ExecStart был свернут до однострочной команды. \ стандартный синтаксис у меня не работал, равно как и цитирование команды вызова etcd для контейнера. Мои вчерашние тесты, казалось, работали нормально, но сегодняшняя конфигурация не вела себя так, как вчера. Поэтому я переделал тест и настройки, чтобы найти то, что показалось мне наиболее стабильным.
  • Очевидно, что если вы собираетесь использовать docker rm в любой момент, вы должен или очень сильно должен используйте привязки, как указано в OP и здесь с --volume. Лично я использую полные пути, хранящиеся в каталоге /srv, а затем привязываю mount к контейнеру. Таким образом, у меня есть одна папка для резервного копирования, и состояние контейнеров, присутствующих или нет, не имеет значения.

Подтверждение

После обновления служебного файла systemd, выполнения перезагрузки демона и т. д. я зашел в контейнер и запустил тестовую команду для etcd:

  • docker exec -it etcd sh
  • etcdctl --endpoints=http://10.4.4.132:2379 список участников

Результат

9a552f9b95628384, запущено, etcd, http://10.4.4.132:2380, http://10.4.4.132:2379, ложь
Michael Hampton avatar
флаг cz
Зачем демонизировать докер вместо того, чтобы просто использовать `Type=simple` (по умолчанию)? Какое преимущество дает это изменение?
флаг cn
@MichaelHampton Почему вы хотите использовать Type=simple ?? Вы документацию читали?? Цитата: «Обратите внимание, что это означает, что командные строки запуска systemctl для простых служб будут сообщать об успехе, даже если двоичный файл службы не может быть успешно запущен». Итак, причина 1 не использовать этот тип; Это и неэффективно, и может вызвать проблемы у иждивенцев службы.Во-вторых, использование -d с запуском docker является основным способом запуска демонизированных контейнеров. В-третьих, dockerd управляет контейнерами, а не systemctl. Последние просто вызывают демона, который ими управляет. Итак, как минимум 3 причины.
Michael Hampton avatar
флаг cz
Дело было не в том, каков мой уровень знаний, а в том, чтобы помочь вам улучшить свой ответ. Это хорошая информация, и ее следует включить, чтобы менее опытные люди, у которых может быть такая же идея, также знали, почему им не следует этого делать.
флаг jp
Это не сработало, служба etcd systemd завершилась с ошибкой: «Активно: сбой (результат: протокол)».
флаг cn
@MichaelHampton Извинения. Тон плохо передается в тексте, поэтому я предположил худшее. Мало того, ваш первоначальный вопрос был на самом деле тем, что в итоге оказалось правильным ответом в моем опыте. Раздражает то, что я до сих пор не осознал, что на самом деле делает значение поля Type; Извинения и за это. Я обновил текст для обоих комментариев здесь с другими данными и выводами. Надеюсь, Джонас, эта версия приблизит вас к желаемому функционированию.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.