it-swarm.com.de

So überprüfen Sie, ob ein Prozess im Docker-Container ausgeführt wird

[Updated1] Ich habe eine Shell, die TCP -Kernelparameter in einigen Funktionen ändert, aber jetzt muss diese Shell im Docker-Container ausgeführt werden. Das heißt, die Shell muss wissen, dass sie in einem Container läuft und stoppt den Kernel konfigurieren. 

Nun bin ich mir nicht sicher, wie ich das erreichen kann, hier ist der Inhalt von /proc/self/cgroup im Container: 

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

Obige Flags können verwendet werden, um herauszufinden, ob dieser Prozess in einem Container ausgeführt wird?

[Updated2]: Ich habe auch festgestellt Das Bestimmen, ob ein Prozess in lxc/Docker ausgeführt wird, aber es scheint nicht zu funktionieren, ist der Inhalt in /proc/1/cgroup meines Containers in diesem Fall:

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

Nein/lxc/containerid

46
harryz

Um in einem Docker-Container nachzuschauen, ob Sie sich in einem Docker-Container befinden oder nicht, können Sie über /proc/1/cgroup erfolgen. Als dieser Beitrag schlägt Ihnen folgendes vor:

Außerhalb eines Docker-Containers enden alle Einträge in /proc/1/cgroup mit /, wie Sie hier sehen können:

[email protected]:~$ 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:/

In einem Docker-Container gehören einige der Kontrollgruppen zu Docker (oder LXC):

[email protected]:~$ 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 erstellt .dockerenv und .dockerinit ( in v1.11 entfernt) - Dateien am oberen Rand der Verzeichnisstruktur des Containers, so dass Sie überprüfen möchten, ob diese vorhanden sind.

So etwas sollte funktionieren.

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

Wir verwenden den sched (/ proc/$ PID/sched) der proc, um die PID des Prozesses zu extrahieren. Die PID des Prozesses innerhalb des Containers unterscheidet sich von der PID des Hosts (eines Nicht-Containersystems).

Beispielsweise gibt die Ausgabe von/proc/1/sched für einen Container Folgendes zurück:

[email protected]:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)

Während eines Hosts ohne Container:

$ cat /proc/1/sched  | head -n 1
init (1, #threads: 1)

Dies hilft zu unterscheiden, ob Sie sich in einem Container befinden oder nicht. Sie können zB:

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

Thomas 'Lösung als Code:

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

Hinweis

Die Variable read mit einer Dummy-Variablen ist eine einfache Sprache für Erzeugt dies eine Ausgabe?. Es ist eine kompakte Methode, um eine möglicherweise verbose grep oder awk in ein test eines Musters zu verwandeln.

Zusätzlicher Hinweis zum Lesen

14
Henk Langeveld

Was für mich funktioniert, ist nach der Inode-Nummer des '/' zu suchen. Innerhalb des Dockers ist es eine sehr hohe Zahl . Außerhalb des Dockers ist es eine sehr niedrige Zahl wie '2' . Ich denke, dieser Ansatz würde auch vom verwendeten Dateisystem abhängen. 

Beispiel

Innerhalb des Dockers:

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

Außerhalb des Dockers

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

In einem Skript:

#!/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

Wir mussten Prozesse ausschließen, die in Containern ausgeführt werden. Statt jedoch nur nach Andockgruppen zu suchen, haben wir uns entschlossen, /proc/<pid>/ns/pid mit dem init-System unter /proc/1/ns/pid zu vergleichen. Beispiel:

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

Oder in unserem Fall wollten wir einen Einzeiler, der einen Fehler generiert, wenn sich der Prozess NICHT in einem Container befindet

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

die wir von einem anderen Prozess aus ausführen können, und wenn der Exit-Code Null ist, wird die angegebene PID in einem anderen Namespace ausgeführt.

1
Greg Bray

Ich habe ein kleines Python-Skript erstellt. Hoffe, jemand findet es nützlich. :-)

#!/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