4
votes

Faire fonctionner systemctl depuis l'intérieur d'un conteneur dans une image debian stretch

Objectif - Qu'est-ce que je veux réaliser?

Je veux accéder à systemctl depuis un conteneur exécutant un nœud kubernetes (ami: exécution de debian stretch)

Fonctionnement configuration:

  • AMI de nœud : kope.io /k8s-1.10-debian-jessie-amd64-hvm-ebs-2018-08-17

  • Répertoires de nœuds Montés dans le conteneur pour faire fonctionner systemctl :

    • / var / run / dbus
    • / run / systemd
    • / bin / systemctl
    • / etc / systemd / system

Configuration ne fonctionne pas:

  • AMI de nœud : kope.io /k8s-1.11-debian-stretch-amd64-hvm-ebs-2018-08-17

  • Répertoires de nœuds Montés dans le conteneur pour faire fonctionner systemctl :

    • / var / run / dbus
    • / run / systemd
    • / bin / systemctl
    • / etc / systemd / system

Débogage pour tenter de résoudre le problème

Pour déboguer ce problème avec l'image debian-stretch ne prenant pas en charge systemctl avec les mêmes montages que debian-jessie

1) J'ai commencé par lancer un déploiement nginx en y montant les volumes mentionnés ci-dessus

$ k logs nginx-deployment-f9c5ff956-b9wn5
standard_init_linux.go:178: exec user process caused "no such file 
or directory"

0 commentaires

3 Réponses :


2
votes

Après avoir monté le répertoire / lib de votre hôte dans le conteneur, votre Pod ne démarrera probablement pas car le répertoire / lib de l'image Docker contenait une bibliothèque nécessaire au serveur Nginx cela devrait commencer dans ce conteneur. En montant / lib depuis l'hôte, les bibliothèques requises par Nginx ne seront plus accessibles. Cela entraînera une erreur Aucun fichier ou répertoire lors de la tentative de démarrage de Nginx.

Pour rendre systemctl disponible à partir du conteneur, je suggérerais simplement de l'installer dans le conteneur, au lieu d'essayer de monter les binaires et bibliothèques nécessaires dans le conteneur. Cela peut être fait dans le Dockerfile de votre conteneur :

FROM whatever

RUN apt-get update && apt-get install systemd

Pas besoin de monter / bin / systemd ou / lib / avec cette solution.


10 commentaires

Je souhaite configurer le hook de terminaison du nœud en utilisant le code dans le conteneur. Le hook de terminaison de nœud est un processus systemd du nœud. Comment l'installation de systemd dans le conteneur aidera-t-elle?


Parce que le paquet systemd contient le binaire systemctl que vous avez demandé dans votre question (et toutes les diverses bibliothèques requises en tant que dépendance).


Merci pour la réponse rapide, j'ai été bloqué avec cela depuis un certain temps maintenant. Vous voulez dire que si j'installe systemctl dans le conteneur, je peux toujours configurer les scripts systemd du nœud depuis l'intérieur du conteneur. Aura-t-il besoin de montures?


Installé le systemctl, obtenant ceci. root @ nginx-deployment-98d4cfc5b-hngl6: / # systemctl Échec de l'émission de l'appel de méthode: n'a pas reçu de réponse. Les causes possibles incluent: l'application distante n'a pas envoyé de réponse, la politique de sécurité du bus de messages a bloqué la réponse, le délai de réponse a expiré ou la connexion réseau a été interrompue.


Oui, si vous souhaitez contrôler le processus d'initialisation systemd sur le nœud, vous aurez probablement besoin du / var / run / dbus , / run / systemd < / code> et probablement aussi / etc / systemd se monte.


Ont ajouté ces montages, mais le nœud bloque la réponse au conteneur avec l'erreur ci-dessus. ^


Je n'ai jamais vu celui-là auparavant. Vous pouvez essayer un peu de démarrer votre conteneur avec l'indicateur privilégié , ainsi que les indicateurs hostPID et / ou hostIPC ( doc )


Merci beaucoup @helmbert Cela a fonctionné. La sortie complète de systemctl n'est pas autorisée par le nœud mais toutes les commandes telles que systemctl status, systemctl enable pour un seul service fonctionnent très bien. Merci beaucoup


Content de l'entendre. Qu'est-ce qui a finalement fait l'affaire? L'indicateur privilégié ?


Non, j'ai juste essayé les commandes que je voulais de systemctl et elles ont toutes fonctionné. Je pense qu'exécuter uniquement $ systemctl retourne une sortie less très énorme, seulement cela a le problème à l'intérieur du conteneur.



5
votes

Plutôt que de monter certains des fichiers de bibliothèque à partir de l'hôte, vous pouvez simplement installer systemd dans le conteneur.

$ apt-get -y install systemd

Maintenant, cela ne fera pas nécessairement systemctl run. Vous aurez besoin de systemd pour s'exécuter dans votre conteneur qui est généré par / sbin / init sur votre système. / sbin / init doit s'exécuter en tant que root, donc vous devrez essentiellement l'exécuter avec l'indicateur privilégié dans le pod ou le conteneur contexte de sécurité sur Kubernetes. Maintenant, ce n'est pas sûr et il existe une longue histoire sur l'exécution de systemd dans un conteneur où se trouvaient les gens de Docker surtout contre (sécurité) et les gens de Red Hat ont dit que c'était nécessaire.

Néanmoins, les gens de Red Hat ont trouvé un moyen de le faire fonctionner sans l'indicateur non privilégié . Vous avez besoin de:

  • / run monté en tant que tmpfs dans le conteneur.
  • / sys / fs / cgroup monté en lecture seule est ok.
  • / sys / fs / cgroup / systemd / monté en lecture / écriture.
  • Utilisation pour STOPSIGNAL SIGRTMIN+3

Dans Kubernetes, vous avez besoin d'un emptyDir pour monter un tmpfs . Les autres peuvent être montés en tant que volumes hôtes.


1 commentaires

Merci Rico. Pour moi, cela a fonctionné après avoir inséré systemd dans le conteneur et monté les répertoires mentionnés ci-dessus dans la question. Je n'ai pas non plus rendu le pod privé. Je ne sais pas pourquoi cela fonctionne pour moi après avoir lu vos informations ci-dessus.



0
votes

J'ai eu un problème similaire où l'une des lignes de mon Dockerfile était: RUN apt-get install -y --reinstall systemd mais après le redémarrage de docker, quand j'ai essayé d'utiliser la commande systemctl. Le résultat était: Échec de la connexion au bus: aucun fichier ou répertoire de ce type. J'ai résolu ce problème en ajoutant ce qui suit à mon docker-compose.yml: volumes: - "/ sys / fs / cgroup: / sys / fs / cgroup: ro" Cela peut également être fait par: sudo docker run -d -v / sys / fs / cgroup: / sys / fs / cgroup: ro {autres options}


0 commentaires