Czy istnieje sposób, aby określić, czy proces (skrypt) działa w kontenerze LXC (środowisko wykonawcze ~ Docker)? Wiem, że niektóre programy są w stanie wykryć, czy działają w maszynie wirtualnej, czy coś podobnego jest dostępne dla lxc / docker?
Czy istnieje sposób, aby określić, czy proces (skrypt) działa w kontenerze LXC (środowisko wykonawcze ~ Docker)? Wiem, że niektóre programy są w stanie wykryć, czy działają w maszynie wirtualnej, czy coś podobnego jest dostępne dla lxc / docker?
Odpowiedzi:
Najbardziej niezawodnym sposobem jest sprawdzenie /proc/1/cgroup
. Powie to grupy kontrola procesu init, a kiedy jesteś nie w pojemniku, który będzie /
dla wszystkich hierarchiach. Gdy jesteś w kontenerze, zobaczysz nazwę punktu zakotwiczenia. W przypadku kontenerów LXC / Docker będzie to coś podobnego /lxc/<containerid>
lub /docker/<containerid>
odpowiednio.
docker
zamiast lxc
w tych ścieżkach
/
wszystkich cgroup; w moim systemie Debian 9 (Systemd 232) tylko trzy z dziesięciu cgroups ( 3:cpuset
, 4:perf_event
i 7:freezer
) są u nasady; reszta jest pod /init.scope
. To powiedziawszy, myślę, że wyszukiwanie tego pliku :/docker/
jest obecnie prawdopodobnie najbardziej niezawodną heurystyką.
grep 'docker\|lxc' /proc/1/cgroup
działa dla mnie na Dockerze 18.09.
Docker tworzy .dockerenv
plik w katalogu głównym drzewa katalogów wewnątrz kontenera. Możesz uruchomić ten skrypt, aby zweryfikować
#!/bin/bash
if [ -f /.dockerenv ]; then
echo "I'm inside matrix ;(";
else
echo "I'm living in real world!";
fi
WIĘCEJ:
Ubuntu faktycznie ma skrypt bash: /bin/running-in-container
i faktycznie może zwrócić typ kontenera, w którym został wywołany. Może być pomocny. Nie wiem jednak o innych głównych dystrybucjach.
.dockerinit
plik został usunięty w ostatnich wersjach Dockera , więc ta metoda nie będzie już działać. W chwili pisania tego .dockerenv
pliku plik jest nadal przechowywany, więc być może można go zamiast tego użyć.
/bin/running-in-container
jest dostarczane przez upstart
. Wraz z przejściem na systemd może to zniknąć. Mam nadzieję, że nie - to brzmi pożytecznie!
W nowym systemie ubuntu 16.04, nowy systemd i lxc 2.0
sudo grep -qa container=lxc /proc/1/environ
Zwięzły sposób sprawdzenia, czy docker jest w skrypcie bash jest:
#!/bin/bash
if grep docker /proc/1/cgroup -qa; then
echo I'm running on docker.
fi
Poręczna funkcja Pythona do sprawdzenia, czy działa w Dockerze:
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()
kubepods
chyba.
Używamy harmonogramu proc (/ proc / $ PID / schedule), aby wyodrębnić PID procesu. PID procesu wewnątrz kontenera będzie się różnił od jego PID na hoście (system niekontenerowy).
Na przykład wynik operacji / proc / 1 / schedule w kontenerze zwróci:
root@33044d65037c:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)
Na hoście innym niż kontener:
$ cat /proc/1/sched | head -n 1
init (1, #threads: 1)
Pomaga to w rozróżnieniu, czy jesteś w kontenerze, czy nie.
sh
i nie init
ma, ale może to być prawie wszystko.
bash-5.0# cat /proc/1/sched bash (1, #threads: 1)
Najłatwiej byłoby sprawdzić otoczenie. Jeśli masz container=lxc
zmienną, jesteś w kontenerze.
W przeciwnym razie, jeśli jesteś rootem, możesz spróbować wykonać mknod
lub wykonać mount
operację, jeśli to się nie powiedzie, najprawdopodobniej znajdziesz się w kontenerze z utraconymi możliwościami.
/proc/1/cgroup
nie pozwala ci tego wykryć.
docker run alpine env
nie daje niczego, co wygląda jak ta zmienna
Moja odpowiedź dotyczy tylko procesów Node.js, ale może być odpowiednia dla niektórych odwiedzających, którzy natkną się na to pytanie, szukając konkretnej odpowiedzi na Node.js.
Miałem ten sam problem i polegając na /proc/self/cgroup
utworzeniu pakietu npm wyłącznie w tym celu - aby wykryć, czy proces Node.js działa w kontenerze Docker, czy nie.
Kontenerowy moduł npm pomoże Ci w Node.js. Obecnie nie jest testowany w Io.js, ale równie dobrze może tam działać.
Sprawdź wszystkie powyższe rozwiązania w Pythonie:
import os
def in_container():
proc_1 = r'/proc/1/sched'
if os.path.exists(proc_1):
with open(proc_1, 'r') as fp:
out = fp.read()
else:
out = ''
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') is not None
]
return any(checks)
if __name__ == '__main__':
print(in_container())
Dowód koncepcji:
$ docker run --rm -it --mount type=bind,source=${PWD}/incontainer.py,target=/tmp/script.py python:3 python /tmp/script.py
True
def is_non_docker(): return os.path.exists('/proc/1/cgroup')
zgodnie z zaakceptowaną odpowiedzią tutaj stackoverflow.com/questions/20010199/…
cat
! Niezły :-D
Docker ewoluuje z dnia na dzień, więc nie możemy z całą pewnością stwierdzić, czy utrzymają się .dockerenv .dockerinit
w przyszłości.
W większości odmian Linuksa init
jest to pierwszy proces do uruchomienia. Ale w przypadku kontenerów to nieprawda.
#!/bin/bash
if ps -p1|grep -q init;then
echo "non-docker"
else
echo "docker"
fi
init
, co nie jest prawdą w systemach opartych systemd
lub launchd
opartych ...
init
), OpenRC, initng, runit. Zobacz tutaj . Większość nowoczesnych systemów opartych na Linuksie systemd
używałaby, niektóre starsze, startowałyby ... Wszystkie nowoczesne systemy OS X by używałylaunchd
Pytania i odpowiedzi dotyczące SO: „Dowiedz się, czy system operacyjny działa w środowisku wirtualnym” ; choć nie jest to to samo, co pytanie OP, faktycznie odpowiada na typowe przypadki znalezienia kontenera, w którym się znajdujesz (jeśli w ogóle).
W szczególności zainstaluj i przeczytaj kod tego skryptu bash, który wydaje się działać całkiem dobrze:
virt-what :
sudo apt install virt-what
virt-what
wersją 1.14-1 na Ubuntu 16.04. Potrzebuje poprawki.
Przetłumaczyłem odpowiedź JJC na rubin
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
W kontenerze Dockera wpisy /proc/self/cgroup
są montowane do cgroups na hoście.
np. w pojemniku
# awk -F: '/cpuset/' /proc/self/cgroup
3:cpuset:/docker/22bd0c154fb4e0d1b6c748faf1f1a12116acc21ce287618a115ad2bea41256b3
podczas gdy to samo na hoście
$ awk -F: '/cpuset/' /proc/self/cgroup
3:cpuset:/
Używanie czegoś w powłoce do testu niskoprofilowego
is_running_in_container() {
awk -F: '/cpuset/ && $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
Może to załatwi sprawę:
if [ -z $(docker ps -q) ]; then
echo "There is not process currently running"
else
echo "There are processes running"
fi
Czy tego chcesz? Mam nadzieję, że to pomoże =)
docker
Oczywiście żaden plik binarny nie jest dostępny z wnętrza kontenera.
docker
dostęp do gniazda docker hosta .