web-dev-qa-db-fra.com

Comment vérifier si un processus est en cours d'exécution dans le conteneur de docker

[Updated1] J'ai un shell qui va modifier TCP les paramètres du noyau dans certaines fonctions, mais je dois maintenant faire en sorte que ce shell s'exécute dans le conteneur Docker. configuration du noyau. 

Maintenant, je ne suis pas sûr de savoir comment y parvenir, voici le contenu de /proc/self/cgroup à l'intérieur du conteneur: 

9:hugetlb:/
8:perf_event:/
7:blkio:/
6:freezer:/
5:devices:/
4:memory:/
3:cpuacct:/
2:cpu:/docker/25ef774c390558ad8c4e9a8590b6a1956231aae404d6a7aba4dde320ff569b8b
1:cpuset:/

Les indicateurs ci-dessus puis-je utiliser pour déterminer si ce processus s'exécute dans un conteneur?

[Updated2]: J'ai aussi remarqué Déterminer si un processus s'exécute dans lxc/Docker , mais cela ne semble pas fonctionner dans ce cas, le contenu dans /proc/1/cgroup de mon conteneur est:

8:perf_event:/
7:blkio:/
6:freezer:/
5:devices:/
4:memory:/
3:cpuacct:/
2:cpu:/docker/25ef774c390558ad8c4e9a8590b6a1956231aae404d6a7aba4dde320ff569b8b
1:cpuset:/

Non/lxc/conteneurid

46
harryz

Pour vérifier à l'intérieur d'un conteneur Docker si vous êtes ou non à l'intérieur d'un conteneur Docker, procédez via /proc/1/cgroup. Comme ce post suggère que vous pouvez ce qui suit:

En dehors d'un conteneur fixe, toutes les entrées dans /proc/1/cgroup se terminent par / comme vous pouvez le voir ici:

vagrant@ubuntu-13:~$ cat /proc/1/cgroup
11:name=systemd:/
10:hugetlb:/
9:perf_event:/
8:blkio:/
7:freezer:/
6:devices:/
5:memory:/
4:cpuacct:/
3:cpu:/
2:cpuset:/

Dans un conteneur Docker, certains des groupes de contrôle appartiendront à Docker (ou LXC):

vagrant@ubuntu-13:~$ docker run busybox cat /proc/1/cgroup
11:name=systemd:/
10:hugetlb:/
9:perf_event:/
8:blkio:/
7:freezer:/
6:devices:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2
5:memory:/
4:cpuacct:/
3:cpu:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2
2:cpuset:/
42
Thomas Uhrig

Docker crée .dockerenv et .dockerinit ( supprimé dans v1.11 ) dans la partie supérieure de l’arborescence de répertoires du conteneur afin que vous souhaitiez vérifier s’ils existent.

Quelque chose comme ça devrait marcher.

#!/bin/bash
if [ -f /.dockerenv ]; then
    echo "I'm inside matrix ;(";
else
    echo "I'm living in real world!";
fi
68
at0S

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. par exemple vous pouvez faire:

if [[ ! $(cat /proc/1/sched | head -n 1 | grep init) ]]; then {
    echo in docker
} else {
    echo not in docker
} fi
19
Founder

La solution de Thomas en tant que code:

running_in_docker() {
  (awk -F/ '$2 == "docker"' /proc/self/cgroup | read non_empty_input)
}

Remarque

La variable read avec une variable muette est un idiome simple pour Est-ce que cela produit une sortie? C'est une méthode compacte pour transformer une grep ou awk éventuellement verbeuse en un test d'un motif.

Note complémentaire à lire

14
Henk Langeveld

Ce qui fonctionne pour moi est de vérifier le numéro d'inode du '/.' À l’intérieur du menu fixe, c’est un nombre très élevé . En dehors du menu fixe, c’est un nombre très faible, comme «2» . Je pense que cette approche dépend également du système de fichiers utilisé. 

Exemple

À l'intérieur du docker:

# ls -ALi / | sed '2!d' |awk {'print $1'}
1565265

En dehors du docker

$ ls -ALi / | sed '2!d' |awk {'print $1'}
2

Dans un script:

#!/bin/bash
INODE_NUM=`ls -ALi / | sed '2!d' |awk {'print $1'}`
if [ $INODE_NUM == '2' ];
then
        echo "Outside the docker"
else
        echo "Inside the docker"
fi
1
trohit

Nous devions exclure les processus s'exécutant dans des conteneurs, mais au lieu de rechercher uniquement les groupes de contrôle docker, nous avons décidé de comparer /proc/<pid>/ns/pid au système init à /proc/1/ns/pid. Exemple:

pid=$(ps ax | grep "[r]edis-server \*:6379" | awk '{print $1}')
if [ $(readlink "/proc/$pid/ns/pid") == $(readlink /proc/1/ns/pid) ]; then
   echo "pid $pid is the same namespace as init system"
else
   echo "pid $pid is in a different namespace as init system"
fi

Ou, dans notre cas, nous voulions une ligne qui génère une erreur si le processus N'EST PAS dans un conteneur.

bash -c "test -h /proc/4129/ns/pid && test $(readlink /proc/4129/ns/pid) != $(readlink /proc/1/ns/pid)"

que nous pouvons exécuter à partir d'un autre processus et si le code de sortie est zéro, le PID spécifié s'exécute dans un espace de noms différent.

1
Greg Bray

J'ai créé un petit script python. J'espère que quelqu'un le trouvera utile. :-)

#!/usr/bin/env python3
#@author Jorge III Altamirano Astorga 2018
import re
import math

total = None
meminfo = open('/proc/meminfo', 'r')
for line in meminfo:
    line = line.strip()
    if "MemTotal:" in line:
        line = re.sub("[^0-9]*", "", line)
        total = int(line)
meminfo.close()
print("Total memory: %d kB"%total)

procinfo = open('/proc/self/cgroup', 'r')
for line in procinfo: 
    line = line.strip()
    if re.match('.{1,5}:name=systemd:', line):
        dockerd = "/sys/fs/cgroup/memory" + \
            re.sub("^.{1,5}:name=systemd:", "", line) + \
            "/memory.stat"
        #print(dockerd)
        memstat = open(dockerd, 'r')
        for memline in memstat:
            memline = memline.strip()
            if re.match("hierarchical_memory_limit", memline):
                memline = re.sub("[^0-9]*", \
                    "", memline)  
                total = math.floor(int(memline) / 2**10)
        memstat.close()
procinfo.close()
print("Total available memory to the container: %d kB"%total)
0
Jorge Altamirano