[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
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:/
Docker crée .dockerenv
et ( 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..dockerinit
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
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
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.
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
# ls -ALi / | sed '2!d' |awk {'print $1'}
1565265
$ 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
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.
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)