2013-11-15 10 views
88

Gibt es eine Möglichkeit festzustellen, ob ein Prozess (Skript) in einem lxc-Container (~ Docker Runtime) ausgeführt wird? Ich weiß, dass einige Programme erkennen können, ob sie in einer virtuellen Maschine laufen, ist etwas ähnliches für lxc/docker verfügbar?Ermitteln, ob ein Prozess in lxc/Docker ausgeführt wird

+0

Es mag pedantisch erscheinen, aber es wäre am besten, Ihre Frage neu zu formulieren, um ein Problem zu beschreiben, das Sie haben, und zu fragen, wie Sie es lösen können - ohne t hat die Frage eine höhere Chance geschlossen zu werden. In vielen Fällen ist es schwierig, diese Änderung vorzunehmen, aber bei Ihnen ist es nicht schwer, einfach umzuformulieren, wenn Sie es wünschen. – mah

+0

gibt es eine interessante Antwort, wenn Sie diesen Befehl innerhalb eines Containers ausgeben: uptime –

Antwort

87

Der zuverlässigste Weg ist die Überprüfung /proc/1/cgroup. Es wird Ihnen die Kontrollgruppen des Init-Prozesses mitteilen, und wenn Sie nicht in einem Container sind, wird das / für alle Hierarchien sein. Wenn Sie innerhalb eines Containers sind, sehen Sie den Namen des Ankerpunkts; was mit LXC/Docker-Containern ungefähr so ​​aussieht wie /lxc/<containerid> oder /docker/<containerid>.

+10

Docker jetzt verwendet 'Docker' anstelle von 'lxc' in diesen Pfaden – Andy

+3

Funktioniert nicht für LXD/LXC-Container, aber http://stackoverflow.com/a/20010626/170230 tut. –

+0

Mit späteren Versionen von Systemd sieht es so aus, als könnten Sie sich nicht auf Prozess 1 verlassen, indem Sie '/' für alle Gruppen verwenden; auf meinem Debian-9-System (systemd 232) befinden sich nur drei der zehn C-Gruppen ('3: CPU-Satz', '4: PERF_Ereignis' und' 7: Tiefkühlschrank') im Stammverzeichnis; der Rest steht unter '/ init.scope'. Das heißt, dass das Durchsuchen dieser Datei nach ':/docker /' im Moment wahrscheinlich die zuverlässigste Heuristik ist. –

9

Der einfachste Weg wäre, die Umgebung zu überprüfen. Wenn Sie die Variable container=lxc haben, befinden Sie sich in einem Container.

Andernfalls, wenn Sie root sind, können Sie versuchen, mknod oder mount Operation auszuführen, wenn es fehlschlägt, sind Sie höchstwahrscheinlich in einem Container mit ausgefallenen Funktionen.

+0

Dieser funktioniert nicht nur für docker (ich habe das nicht überprüft), aber wichtiger für lxd/lxc container (checked), wo '/ proc/1/cgroup' lässt Sie das nicht erkennen. –

+0

Funktioniert nicht für Docker. Die Variable ist nicht festgelegt. – hakre

+0

können Sie die Antwort mit Code statt Pseudocode bearbeiten? "container = lxc"? ist nichts richtiges. meinst du etwas wie wenn [["lxc" = "$ container"]]? –

81

Docker erstellt eine .dockerenv Datei im Stammverzeichnis des Verzeichnisbaums innerhalb des Containers. Sie können dieses Skript ausführen

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


MEHR zu überprüfen: Ubuntu tatsächlich hat einen Bash-Skript. /bin/running-in-container und es kann tatsächlich die Art des Behälters zurückkehrt es in aufgerufen wurde sein könnte hilfreich. Weiß aber nicht über andere große Distributionen.

+8

Wichtiger Hinweis: Die '.dockerinit'-Datei wurde [in neueren Versionen von Docker] entfernt (https://github.com/docker/docker/issues/18355), so dass diese Methode nicht mehr funktioniert. Zum Zeitpunkt des Schreibens wird die '.dockerenv'-Datei immer noch gespeichert, vielleicht könnte sie stattdessen verwendet werden. –

+0

Unter Debian wird '/ bin/running-in-container' von' upstart' bereitgestellt. Mit dem Übergang zu Systemd könnte es weggehen. Ich hoffe nicht - es klingt sinnvoll! –

+0

"über dem Verzeichnisbaum", was bedeutet das? wo ist das? –

3

Meine Antwort gilt nur für Node.js Prozesse aber möglicherweise relevant für einige Besucher, die zu dieser Frage auf der Suche nach einer Node.js spezifische Antwort stolpern.

hatte ich das gleiche Problem und unter Berufung auf /proc/self/cgroup ich ein npm Paket diesen Zweck allein geschaffen - zu erkennen, ob ein Node.js Prozess in einem Container Docker läuft oder nicht.

Die containerized npm module wird Ihnen in Node.js helfen. Es wird derzeit nicht in Io.js getestet, kann aber genauso gut dort arbeiten.

8

Auf einer neuen Ubuntu 16.04-System, neue systemd & lxc 2,0

sudo grep -qa container=lxc /proc/1/environ 
4

Wir verwenden die Sched des proc (/ proc/$ PID/Sched), um die PID des Prozesses zu extrahieren. Die PID des Prozesses innerhalb des Containers unterscheidet sich von der PID auf dem Host (einem Nicht-Container-System).

Zum Beispiel kann die Ausgabe von/proc/1/auf einem Container Sched zurückkehren:

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

Während auf einem Nicht-Container host:

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

Dies hilft zu unterscheiden, wenn Du bist in einem Container oder nicht.

+0

Je nach Betriebssystem muss "init" möglicherweise durch "systemd" ersetzt werden. Weitere Informationen zu systemd [hier] (https://www.tecmint.com/systemd-replaces-init-in-linux/). – BrianV

2

Docker entwickelt sich Tag für Tag, so dass wir nicht sicher sagen können, ob sie in Zukunft .dockerenv .dockerinit behalten werden. In den meisten Linux-Varianten init ist der erste Prozess zu starten. Aber im Falle von Containern ist das nicht wahr.

#!/bin/bash 
if ps -p1|grep -q init;then 
    echo "non-docker" 
else 
    echo "docker" 
fi 
+0

Dies funktioniert nicht unter MacOS X. –

+5

@RomanTrofimov LXC/Docker auch nicht. Was für ein lustiger Kommentar. – abourget

+0

Es funktioniert auch nicht in Centos 7. Wenn ich in meinem Host-Rechner laufe, heißt es Docker.Sieht aus, als ob Systemd als Prozess-ID 1 ausgeführt wird. –

5

Eine prägnante Art und Weise für Docker in einem Bash-Skript zu überprüfen ist:

#!/bin/bash 
if grep docker /proc/1/cgroup -qa; then 
    echo I'm running on docker. 
fi 
5

Handlich Python Funktion, wenn in Docker laufen zu überprüfen (Linux-only, obvs.):

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() 
0

Diese SO Q & A: "Find out if the OS is running in a virtual environment"; obwohl es nicht das gleiche wie die Frage des OP ist, beantwortet es in der Tat häufig auftretende Fälle, in denen Sie herausfinden, in welchem ​​Container Sie sich befinden (wenn überhaupt).

Insbesondere installieren und den Code dieses Bash-Skript lesen, die ziemlich gut zu funktionieren scheint:

virt-was:

sudo apt install virt-what 
+0

Funktioniert nicht mit' virt-what' Version 1.14 -1 auf Ubuntu 16.04. Benötigt Patch. – Lucas

1

prüfen für alle Lösungen, die oben in 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) 
Verwandte Themen