Existe-t-il un moyen de déterminer si un processus (script) s'exécute dans un conteneur lxc (~ runtime Docker)? Je sais que certains programmes sont capables de détecter s’ils s’exécutent dans une machine virtuelle. Existe-t-il quelque chose de similaire pour lxc/docker?
Le moyen le plus fiable est de vérifier /proc/1/cgroup
. Il vous indiquera les groupes de contrôle du processus init, et quand vous serez pas dans un conteneur, ce sera /
pour toutes les hiérarchies. Lorsque vous êtes à l'intérieur un conteneur, vous verrez le nom du point d'ancrage. Avec les conteneurs LXC/Docker, ce sera quelque chose comme /lxc/<containerid>
ou /docker/<containerid>
respectivement.
Docker crée un .dockerenv
fichier à la racine de l'arborescence de répertoires à l'intérieur du conteneur. Vous pouvez exécuter ce script pour vérifier
#!/bin/bash
if [ -f /.dockerenv ]; then
echo "I'm inside matrix ;(";
else
echo "I'm living in real world!";
fi
MORE: Ubuntu a en réalité un script bash: /bin/running-in-container
et il peut effectivement renvoyer le type de conteneur dans lequel il a été appelé. Peut-être utile. Je ne sais pas sur les autres principales distributions cependant.
Sur un nouveau système Ubuntu 16.04, un nouveau système et lxc 2.0
Sudo grep -qa container=lxc /proc/1/environ
Une manière concise de vérifier le menu fixe dans un script bash est la suivante:
#!/bin/bash
if grep docker /proc/1/cgroup -qa; then
echo I'm running on docker.
fi
Handy Python pour vérifier si vous utilisez Docker:
def in_docker():
""" Returns: True if running in a Docker container, else False """
with open('/proc/1/cgroup', 'rt') as ifh:
return 'docker' in ifh.read()
Nous utilisons le sched du proc (/ proc/$ PID/sched) pour extraire le PID du processus. Le PID du processus à l'intérieur du conteneur sera différent, puis il sera le même sur l'hôte (système non conteneur).
Par exemple, la sortie de/proc/1/sched sur un conteneur retournera:
root@33044d65037c:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)
En tant qu'hôte non conteneur:
$ cat /proc/1/sched | head -n 1
init (1, #threads: 1)
Cela aide à différencier si vous êtes dans un conteneur ou non.
Le moyen le plus simple serait de vérifier l'environnement. Si vous avez le container=lxc
variable, vous êtes dans un conteneur.
Sinon, si vous êtes root, vous pouvez essayer d'effectuer l'opération mknod
ou mount
. Si elle échoue, vous vous trouvez probablement dans un conteneur dont les fonctionnalités ont été abandonnées.
Vérifiez toutes les solutions ci-dessus en Python:
import os
import subprocess
def in_container():
# type: () -> bool
""" Determines if we're running in an lxc/docker container. """
out = subprocess.check_output('cat /proc/1/sched', Shell=True)
out = out.decode('utf-8').lower()
checks = [
'docker' in out,
'/lxc/' in out,
out.split()[0] not in ('systemd', 'init',),
os.path.exists('/.dockerenv'),
os.path.exists('/.dockerinit'),
os.getenv('container', None) is not None
]
return any(checks)
Ma réponse ne s'applique qu'aux processus de Node.js , mais peut être utile pour certains visiteurs qui tombent sur cette question à la recherche d'une réponse spécifique à Node.js.
J'ai eu le même problème et en s'appuyant sur /proc/self/cgroup
J'ai créé un package npm uniquement dans le but de détecter si un processus Node.js s'exécute ou non dans un conteneur Docker.
Le module npm conteneurisé vous aidera dans Node.js. Il n’a pas encore été testé sur Io.js mais pourrait tout aussi bien fonctionner là-bas.
Docker évolue de jour en jour, nous ne pouvons donc pas dire avec certitude s'ils vont conserver .dockerenv .dockerinit
Dans le futur.
Dans la plupart des versions de Linux, init
est le premier processus à démarrer. Mais dans le cas des conteneurs, ce n'est pas vrai.
#!/bin/bash
if ps -p1|grep -q init;then
echo "non-docker"
else
echo "docker"
fi
S'appuyant sur la réponse acceptée qui teste /proc/*/cgroup
..
awk -F: '$3 ~ /^\/$/ {c=1} END{ exit c }' /proc/self/cgroup
Donc, pour une utilisation dans un script, un test pourrait être construit de cette façon.
is_running_in_container() {
awk -F: '$3 ~ /^\/$/{ c=1 } END { exit c }' /proc/self/cgroup
}
if is_running_in_container; then
echo "Aye!! I'm in a container"
else
echo "Nay!! I'm not in a container"
fi
J'ai traduit la réponse de JJC en Ruby
def in_docker
File.open('/proc/1/cgroup', 'rt') do |f|
contents = f.read
return contents =~ /docker/i || contents =~ /kubepod/i
end
rescue StandardError => e
p 'Local development'
p e
false
end
This SO Questions-réponses: "Détermine si le système d'exploitation fonctionne dans un environnement virtuel" ; bien que différent de la question du PO, il répond effectivement aux cas courants de trouver dans quel conteneur vous vous trouvez (le cas échéant).
En particulier, installez et lisez le code de ce script bash qui semble plutôt bien fonctionner:
virt-what :
Sudo apt install virt-what