Vous ne devriez pas utiliser systemd, si vous n'en avez pas besoin. Essayez de démarrer l'application sans celle-ci dans le CMD ou le RUN, ou en utilisant un script wrapper.
nelaaro
Si vous avez besoin systemdde CentOS, utilisez cette image: FROM centos/systemd
james.garriss
Réponses:
24
Je suppose que vous exécutez un non-privilegedconteneur. systemd nécessite la capacité CAP_SYS_ADMIN mais Docker supprime cette capacité dans les conteneurs non privilégiés, afin d'ajouter plus de sécurité.
systemd nécessite également un accès RO au système de fichiers cgroup dans un conteneur. Vous pouvez l'ajouter avec–v /sys/fs/cgroup:/sys/fs/cgroup:ro
Voici donc quelques étapes pour exécuter CentOS avec systemd dans un conteneur Docker:
Pull image centos
Configurez un fichier Docker comme celui ci-dessous:
FROM centos
MAINTAINER "Yourname" <[email protected]>
ENV container docker
RUN yum -y update; yum clean all
RUN yum -y install systemd; yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
Construit le - docker build --rm -t centos7-systemd - < mydockerfile
Exécutez un conteneur avec docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init
Génial! Cependant, au moins, je reçois plus d'informations maintenant. Voici ce que je me connecte:[ 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.
Snowcrash
1
Au cas où je ne serais pas clair! Je reçois toujours l'erreurFailed to get D-Bus connection: Operation not permitted
Snowcrash
Vous avez créé votre propre image à partir du Dockerfile copié dans ma réponse, vous exécutez un conteneur à partir de cette image et vous obtenez toujours une erreur?
13dimitar du
4
Bingo! J'exécutais le conteneur avec /bin/bashpour obtenir un shell. Cependant, cela m'a donné l'erreur mentionnée précédemment. Quand je l'ai couru avec /usr/sbin/initcomme suggéré puis attaché avec une coque, tout s'est bien passé. De toute évidence, il me manque une nuance /usr/sbin/init. Cette réponse mérite un vote positif substantiel.
Snowcrash
J'y suis depuis 2 jours, et je n'arrive toujours pas à comprendre de quoi il /sys/fs/cgroup:/sys/fs/cgroups'agit ou d'où il vient ... Je sais comment monter le dossier invité sur hist comme: /src/:/var/wwwmais d'où vient votre fichier? Cela me cause beaucoup d'erreurs parce que j'ai collé le code, je pense que je devrais les créer quelque part
samayo
4
Ce n'est pas une réponse directe à votre question, mais elle peut en fait être plus importante, et je suis tombé sur cette réalisation alors que je lisais les autres réponses ici.
J'ai eu une certaine expérience de la migration de certains systèmes complexes vers Docker, et l'une des réalisations importantes que j'ai eues est que vous devriez idéalement avoir un conteneur Docker par application / service ou "par démon".
Une raison très importante à cela est que Docker ne fermera pas proprement les services que vous démarrez avec systemctl et, en fait, vous pourriez vous retrouver avec le même type de corruption de base de données provenant d'une panne de courant inattendue.
Pour approfondir ceci: lorsque Docker émet une commande "stop" vers un conteneur, il envoie le signal SIGTERM uniquement le seul processus qui a été démarré avec le CMD / ENTRYPOINT, pas à tous les services et démons. Pour qu'un service ait l'avertissement de s'arrêter proprement et que tous les autres soient arrêtés sans cérémonie.
Si vous devez absolument empaqueter deux services dans le même conteneur (c'est-à-dire votre application et une base de données PostgreSQL ou quelque chose comme ça), alors vous devez avoir votre CMD / ENTRYPOINT être un script qui attrape SIGTERM puis le rediffuse vers ces services connus. Cela peut être fait, mais si vous en avez l'occasion, repensez votre solution et essayez de la diviser en plusieurs conteneurs.
Un addendum
Il y a une note / page intéressante sur le site Docker à propos de l'utilisation de supervisord si vous devez absolument avoir plusieurs services en cours d'exécution dans le même conteneur.
FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
# Install anything. The service you want to start must be a SystemD service.
CMD ["/usr/sbin/init"]
Maintenant, créez l'image et exécutez-la en utilisant au moins les arguments suivants pour docker runcommander:-v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro
Ensuite, le point principal est que ce /usr/sbin/initdoit être le premier processus à l'intérieur du conteneur Docker.
Donc, si vous souhaitez utiliser un script personnalisé qui exécute certaines commandes avant de s'exécuter /usr/sbin/init, lancez-le à la fin de votre script en utilisant exec /usr/sbin/init(dans un script bash).
Voici un exemple:
ADD cmd.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/cmd.sh
CMD ["/usr/local/bin/cmd.sh"]
Et voici le contenu de cmd.sh:
#!/bin/bash
# Do some stuffs
exec /usr/sbin/init # To correctly start D-Bus thanks to https://forums.docker.com/t/any-simple-and-safe-way-to-start-services-on-centos7-systemd/5695/8
Vous pourriez avoir System is booting up. See pam_nologin(8)si vous utilisez le système PAM, dans ce cas, supprimez- /usr/lib/tmpfiles.d/systemd-nologin.confle Dockerfilecar cela crée le fichier /var/run/nologinqui génère cette erreur spécifique.
systemd-nologin.conf/ nologinpour la victoire car CentOS / RHEL 7 ne UsePAM noprend pas en charge les réclamations et se plaindra dans les journaux en tant que tels. Je ne sais pas si RH openssh portable a patché / cassé d'une manière ou d'une autre ou essaie de réduire la surface de support des clients novices.
1
Je ne voulais pas avoir à lancer systemd en tant que init / PID 1. Après avoir effectué les étapes de nettoyage mentionnées par d'autres, je lance systemd à partir d'un script de démarrage en tant que /usr/lib/systemd/systemd --system &.
Cela a permis à systemd de démarrer et de lancer les services enregistrés, mais systemctl échouait avec l'erreur D-Bus.
Pour moi, le lien manquant était l'absence du répertoire / run / systemd / system, découvert par straceing systemctl.
La création manuelle de ce répertoire avant d'exécuter systemctl permet à systemctl de fonctionner pour moi.
sudo
?systemd
de CentOS, utilisez cette image:FROM centos/systemd
Réponses:
Je suppose que vous exécutez un
non-privileged
conteneur. systemd nécessite la capacité CAP_SYS_ADMIN mais Docker supprime cette capacité dans les conteneurs non privilégiés, afin d'ajouter plus de sécurité.systemd nécessite également un accès RO au système de fichiers cgroup dans un conteneur. Vous pouvez l'ajouter avec
–v /sys/fs/cgroup:/sys/fs/cgroup:ro
Voici donc quelques étapes pour exécuter CentOS avec systemd dans un conteneur Docker:
docker build --rm -t centos7-systemd - < mydockerfile
Exécutez un conteneur avec
docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init
Vous devriez avoir systemd dans votre conteneur
la source
[ 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
pour obtenir un shell. Cependant, cela m'a donné l'erreur mentionnée précédemment. Quand je l'ai couru avec/usr/sbin/init
comme suggéré puis attaché avec une coque, tout s'est bien passé. De toute évidence, il me manque une nuance/usr/sbin/init
. Cette réponse mérite un vote positif substantiel./sys/fs/cgroup:/sys/fs/cgroup
s'agit ou d'où il vient ... Je sais comment monter le dossier invité sur hist comme:/src/:/var/www
mais d'où vient votre fichier? Cela me cause beaucoup d'erreurs parce que j'ai collé le code, je pense que je devrais les créer quelque partCe n'est pas une réponse directe à votre question, mais elle peut en fait être plus importante, et je suis tombé sur cette réalisation alors que je lisais les autres réponses ici.
J'ai eu une certaine expérience de la migration de certains systèmes complexes vers Docker, et l'une des réalisations importantes que j'ai eues est que vous devriez idéalement avoir un conteneur Docker par application / service ou "par démon".
Une raison très importante à cela est que Docker ne fermera pas proprement les services que vous démarrez avec systemctl et, en fait, vous pourriez vous retrouver avec le même type de corruption de base de données provenant d'une panne de courant inattendue.
Pour approfondir ceci: lorsque Docker émet une commande "stop" vers un conteneur, il envoie le signal SIGTERM uniquement le seul processus qui a été démarré avec le CMD / ENTRYPOINT, pas à tous les services et démons. Pour qu'un service ait l'avertissement de s'arrêter proprement et que tous les autres soient arrêtés sans cérémonie.
Si vous devez absolument empaqueter deux services dans le même conteneur (c'est-à-dire votre application et une base de données PostgreSQL ou quelque chose comme ça), alors vous devez avoir votre CMD / ENTRYPOINT être un script qui attrape SIGTERM puis le rediffuse vers ces services connus. Cela peut être fait, mais si vous en avez l'occasion, repensez votre solution et essayez de la diviser en plusieurs conteneurs.
Un addendum
Il y a une note / page intéressante sur le site Docker à propos de l'utilisation de supervisord si vous devez absolument avoir plusieurs services en cours d'exécution dans le même conteneur.
la source
J'ai réussi à résoudre ce problème dans un conteneur Docker CentOS: 7. J'ai principalement suivi le projet d'image Guide sur CentOS Docker .
Maintenant, créez l'image et exécutez-la en utilisant au moins les arguments suivants pour
docker run
commander:-v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro
Ensuite, le point principal est que ce
/usr/sbin/init
doit être le premier processus à l'intérieur du conteneur Docker.Donc, si vous souhaitez utiliser un script personnalisé qui exécute certaines commandes avant de s'exécuter
/usr/sbin/init
, lancez-le à la fin de votre script en utilisantexec /usr/sbin/init
(dans un script bash).Voici un exemple:
Et voici le contenu de
cmd.sh
:Vous pourriez avoir
System is booting up. See pam_nologin(8)
si vous utilisez le système PAM, dans ce cas, supprimez-/usr/lib/tmpfiles.d/systemd-nologin.conf
leDockerfile
car cela crée le fichier/var/run/nologin
qui génère cette erreur spécifique.la source
systemd-nologin.conf
/nologin
pour la victoire car CentOS / RHEL 7 neUsePAM no
prend pas en charge les réclamations et se plaindra dans les journaux en tant que tels. Je ne sais pas si RH openssh portable a patché / cassé d'une manière ou d'une autre ou essaie de réduire la surface de support des clients novices.Je ne voulais pas avoir à lancer systemd en tant que init / PID 1. Après avoir effectué les étapes de nettoyage mentionnées par d'autres, je lance systemd à partir d'un script de démarrage en tant que
/usr/lib/systemd/systemd --system &
.Cela a permis à systemd de démarrer et de lancer les services enregistrés, mais systemctl échouait avec l'erreur D-Bus.
Pour moi, le lien manquant était l'absence du répertoire / run / systemd / system, découvert par
strace
ing systemctl.La création manuelle de ce répertoire avant d'exécuter systemctl permet à systemctl de fonctionner pour moi.
la source