Наши команды активно используют ansible
для создания шаблонов и финальной
конфигурации виртуальных машин. Поэтому перед нами встаёт вопрос обеспечения
работоспособности и корректности сценариев развёртывания.
В этой заметке будет рассказано об имитации systemd
внутри docker
-контейнера
и валидации финального результата с помощью фреймворка testinfra
.
Работа с molecule
будет рассмотрена в других заметках.
ansbile
.ssh
для запуска ansbile
.ansible.builtin.systemd
.Наша задача — обеспечить быструю проверку на ноутбуке разработчика. Поэтому:
virtualbox
+ vagrant
:
multipass
:
ssh
требуется несложная дополнительная настройка.docker
:
sshd
;systemd
в качестве init
-процесса.В своей работе мы используем два варианта:
multipass
+ multipass-compose
, когда нам требуется работа с “настоящими”
виртуальными машинами;docker
, когда необходимо быстро проверить изменения.Рассмотрим решение с docker
-образом.
Очевидное решение — запустить systemd
как init
-процесс контейнера. И,
конечно, это так работать не будет.
# syntax=docker/dockerfile:1
FROM ubuntu:focal
ENV DEBIAN_FRONTEND=noninteractive
RUN <<EOF
apt update
apt install -y --no-install-recommends \
systemd
EOF
CMD ["/bin/systemd"]
Контейнер будет запущен, но, как только вы обратитесь к systemctl
, будет
получен следующий результат:
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
Подготовим образ, внутри которого будет установлены и настроены:
systemd
(нужен, фактически, только для создания структуры каталогов);gdraheim/docker-systemctl-replacement
для имитации systemctl
и journalctl
;sudo
.Точкой входа будет выступать sshd
.
# syntax=docker/dockerfile:1
FROM ubuntu:focal
ENV DEBIAN_FRONTEND=noninteractive
RUN <<EOF
apt update
apt install -y --no-install-recommends \
openssh-server \
sudo \
gnupg \
systemd \
python3
useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo -u 1000 ubuntu
echo 'ubuntu:ubuntu' | chpasswd
service ssh start
EOF
COPY systemctl3.py /usr/bin/systemctl
COPY journalctl3.py /usr/bin/journalctl
RUN chmod +x /usr/bin/systemctl /usr/bin/journalctl
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
При работе sshd
будет игнорировать сигнал SIGTERM
для остановки контейнера,
поэтому запускать его следует либо с опцией --init
, либо с указанием сигнала
остановки --stop-signal
.
После запуска контейнера, в него можно будет зайти по ssh
, что нам необходимо
для запуска ansible
и testinfra
.
ssh \
-o UserKnownHostsFile=/dev/null \
-o ControlMaster=auto -o \
ControlPersist=60s \
ubuntu@localhost
Для проверок состояния сервисов с помощью модуля Service
testinfra
выполняет
ряд инспекций, выбирая, какая подсистема инициализации используется на данной
машине.
Чтобы явно сообщить об использовании systemd
, нужно использовать довольно
безобидный и компактный monkeypatch
:
import testinfra.modules.service
testinfra.modules.service.Service.get_module_class = classmethod(
lambda *args, **kwargs: testinfra.modules.service.SystemdService
)
Это явно указывает testinfra
опираться на systemctl
.
Что получили в итоге?
systemd
и доступом по ssh
.ansbile
.testinfra
.Всё в комплексе можно посмотреть и пощупать у меня на github
:
Успехов в работе с ansible
и тестировании!