Рейтинг:0

Не удалось запустить команды systemctl на хосте из контейнера, который работал до Ubuntu 16.04.

флаг ve

Когда основной ОС является Ubuntu 16.04 или RHEL 7.x, работает следующая команда, которая помогает нам запускать команды systemctl на хосте из контейнера докеров:

# nsenter --mount=/hostroot/proc/1/ns/mnt -- запуск systemctl dummy.service

Но в более новых хост-ОС, Ubuntu 20.04 и RHEL 8.x, это не работает, и мы получаем следующую ошибку:

# nsenter --mount=/hostroot/proc/1/ns/mnt -- запуск systemctl dummy.service
Не удалось подключиться к шине: нет доступных данных

Я прикрепил минималистичный пример и команды для запуска и воспроизведения проблемы:

Пример сервиса, который я хотел запустить на хосте, из контейнера:

# кошка /etc/systemd/system/dummy.service
[Ед. изм]
Описание = фиктивный сервис
[Оказание услуг]
ExecStart=/usr/bin/бесконечный сон

Dockerfile моего контейнера:

# cat Докерфайл
ИЗ убунту: 20.04
ENV TZ=UTC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt update -y --fix-missing
RUN apt install -y util-linux
СТОП СИГНАЛ МИН+3
CMD [ "/bin/bash" ]

Создайте образ:

# docker build -t пробная версия.

Удалите все устаревшие контейнеры:

# пробная версия docker rm -f

Запустите образ:

# docker run -it -d --net=host --privived -v /:/hostroot -v /sys/fs/cgroup:/sys/fs/cgroup:ro --name пробная версия

Воспроизведите проблему:

# docker exec -it пробная версия bash
# nsenter --mount=/hostroot/proc/1/ns/mnt -- запуск systemctl dummy.service
Не удалось подключиться к шине: нет доступных данных

Я хотел бы знать, есть ли какие-либо дополнительные параметры или какая-либо команда запуска докера, которую необходимо изменить, чтобы это заработало.

Рейтинг:0
флаг cn

Я изучал это в течение нескольких часов, кажется, метод sd_bus_start был изменен, чтобы включить дополнительные проверки. Я не смог определить, что еще он ищет, однако я смог найти более элегантное решение для выполнения той же задачи с помощью удаленных команд systemctl вместо монтирования всех каталогов с хоста.

Удаленная системаctl

systemctl поддерживает удаленные команды через --хост / -Х флаг. Он использует ssh для подключения к удаленному хосту, поэтому потребуется пара ключей ssh. Поскольку мы контролируем хост, на котором находимся, это довольно просто настроить.

Команда Docker (или аргумент Kubernetes)

Вот полная команда, которую можно использовать, я разберу каждую часть ниже. Предполагается, что контейнер имеет systemctl и ssh установлен, контейнер работает в хост-сети и что корень домашний каталог учетной записи смонтирован (вы можете использовать его по-другому, если хотите).

(ls ~/.ssh/id_rsa || ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N "") 
  && (grep -qxF $(cat ~/.ssh/id_rsa.pub) ~/.ssh/authorized_keys || echo $(cat ~/.ssh/id_rsa.pub) > ~/.ssh/authorized_keys)
  && (grep -qxF "StrictHostKeyChecking no" ~/.ssh/config || echo "StrictHostKeyChecking no" >> ~/.ssh/config)
  && (grep -qxF "UserKnownHostsFile /dev/null" ~/.ssh/config || echo "UserKnownHostsFile /dev/null" >> ~/.ssh/config)
  && systemctl -H [email protected] запустить nfs-server.service

Эта команда проверяет, ~/.ssh/id_rsa файл существует, в противном случае создайте его.

(ls ~/.ssh/id_rsa || ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N "")

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

(grep -qxF "$(cat ~/.ssh/id_rsa.pub)" ~/.ssh/authorized_keys || echo "$(cat ~/.ssh/id_rsa.pub)" > ~/.ssh/authorized_keys)

Вероятно, это можно сделать более безопасным, поместив его в раздел конфигурации ssh только для 127.0.0.1, но нам нужно

(grep -qxF "StrictHostKeyChecking no" ~/.ssh/config || echo "StrictHostKeyChecking no" >> ~/.ssh/config) 
  && (grep -qxF "UserKnownHostsFile /dev/null" ~/.ssh/config || echo "UserKnownHostsFile /dev/null" >> ~/.ssh/config)

Наконец-то мы имеем настоящее systemctl команда. Обратите внимание на -H корень@127.0.0.1.

systemctl -H [email protected] запустить nfs-server.service

Для максимальной безопасности было бы лучше сначала настроить ключи и пользователей за пределами контейнеров (через Ansible или аналогичный) и разрешить только systemctl -H команда внутри контейнера.

Aravindhan Krishnan avatar
флаг ve
Спасибо, что потратили на это свое драгоценное время.Мы также внутренне пришли к очень похожему выводу (хотя и посредством только наблюдения, а не чтения кода), что некоторые дополнительные новые проверки вызывают изменение в поведении. Мы также отметили, что в более ранних ОС выполнение такой команды приводило к падению. Вероятно, systemd-dev исправил эту проблему, которая вызывала поведенческие аномалии у конечного пользователя. Предлагаемое вами решение такое же, как и у канонического. Спасибо

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

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