Estou tentando listar serviços na minha imagem do CentOS em execução no Docker usando
systemctl list-units
mas recebo esta mensagem de erro:
Failed to get D-Bus connection: Operation not permitted
Alguma sugestão de qual pode ser o problema?
sudo
?systemd
do CentOS, use esta imagem:FROM centos/systemd
Respostas:
Meu palpite é que você está executando um
non-privileged
contêiner. O systemd requer o recurso CAP_SYS_ADMIN, mas o Docker descarta esse recurso nos contêineres não privilegiados, para adicionar mais segurança.O systemd também requer acesso de RO ao sistema de arquivos cgroup dentro de um contêiner. Você pode adicioná-lo com
–v /sys/fs/cgroup:/sys/fs/cgroup:ro
Portanto, aqui estão algumas etapas sobre como executar o CentOS com o systemd dentro de um contêiner do Docker:
docker build --rm -t centos7-systemd - < mydockerfile
Execute um contêiner com
docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init
Você deve ter systemd no seu contêiner
fonte
[ INFO ] Update UTMP about System Boot/Shutdown is not active. [DEPEND] Dependency failed for Update UTMP about System Runlevel Changes. Job systemd-update-utmp-runlevel.service/start failed with result 'dependency'. [ OK ] Started Journal Service. [ OK ] Reached target System Initialization. [ OK ] Reached target Timers. [ OK ] Listening on D-Bus System Message Bus Socket.
Failed to get D-Bus connection: Operation not permitted
/bin/bash
para obter uma concha. No entanto, isso me deu o erro mencionado anteriormente. Quando eu corri com/usr/sbin/init
o sugerido, em seguida, anexado com uma concha, tudo correu bem. Claramente, estou sentindo falta de uma nuance/usr/sbin/init
. Esta resposta merece alguma votação substancial./sys/fs/cgroup:/sys/fs/cgroup
é ou de onde ela vem ... Eu sei como montar a pasta de convidados em um histórico como:/src/:/var/www
mas de onde vem o seu arquivo? É causando-me muitos erros porque eu colou o código, eu estou pensando que eu deveria criar aqueles em algum lugarEsta não é uma resposta direta à sua pergunta, mas pode ser realmente mais importante, e me deparei com essa percepção enquanto lia as outras respostas aqui.
Eu tive alguma experiência na migração de alguns sistemas complicados para o Docker, e uma das realizações significativas que tive é que você deveria idealmente ter um contêiner do Docker por aplicativo / serviço ou "por daemon".
Uma razão muito significativa para isso é que o Docker não desligará corretamente os serviços iniciados com o systemctl e, de fato, você poderá acabar com o mesmo tipo de corrupção de banco de dados resultante de uma falta de energia inesperada.
Para aprofundar isso um pouco mais: quando o Docker emite um comando "stop" para um contêiner, ele envia ao sinal SIGTERM apenas o processo único iniciado com o CMD / ENTRYPOINT, e não a todos os serviços e daemons. Para que um serviço tenha o aviso de desligamento limpo e todos os outros sejam encerrados sem cerimônia.
Se você absolutamente precisar empacotar dois serviços no mesmo contêiner (por exemplo, seu aplicativo e um banco de dados PostgreSQL ou algo parecido), precisará que seu CMD / ENTRYPOINT seja um script que capture o SIGTERM e depois o retransmita para os serviços conhecidos. Isso pode ser feito, mas se você tiver a oportunidade, repensar sua solução e tente dividi-la em vários contêineres.
Um adendo
Há uma nota / página interessante no site do Docker sobre o uso do supervisord se você precisar absolutamente de vários serviços em execução no mesmo contêiner.
fonte
Consegui corrigir esse problema em um contêiner do CentOS: 7 Docker. Acompanhei principalmente o projeto de imagem do Guide on CentOS Docker .
Agora, crie a imagem e execute-a usando pelo menos os seguintes argumentos para
docker run
comandar:-v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro
O ponto principal é que
/usr/sbin/init
deve ser o primeiro processo dentro do contêiner do Docker.Portanto, se você quiser usar um script personalizado que execute alguns comandos antes de executar
/usr/sbin/init
, inicie-o no final do seu script usandoexec /usr/sbin/init
(em um script bash).Aqui está um exemplo:
E aqui está o conteúdo de
cmd.sh
:Você poderia ter,
System is booting up. See pam_nologin(8)
se estiver usando o sistema PAM, nesse caso, excluir/usr/lib/tmpfiles.d/systemd-nologin.conf
no seuDockerfile
porque ele cria o arquivo/var/run/nologin
que gera esse erro específico.fonte
systemd-nologin.conf
/nologin
for the win because CentOS/RHEL 7 claimsUsePAM no
is unsupported and will complain in logs as such. Not sure if RH openssh portable patched / broke it somehow or they're trying to lower their support surface from novice customers.Eu não queria ter que iniciar o systemd como init / PID 1. Depois de executar as etapas de limpeza mencionadas por outras pessoas, inicio o systemd a partir de um script de inicialização como
/usr/lib/systemd/systemd --system &
.Isso permitiu ao systemd iniciar e iniciar os serviços registrados, mas systemctl estava falhando com o erro do D-Bus.
Para mim, o link que faltava era a ausência do diretório / run / systemd / system, descoberto por
strace
ing systemctl.Criar este diretório manualmente antes de executar o systemctl permite que o systemctl funcione para mim.
fonte