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.
dockerzamiast lxcw tych ścieżkach
/wszystkich cgroup; w moim systemie Debian 9 (Systemd 232) tylko trzy z dziesięciu cgroups ( 3:cpuset, 4:perf_eventi 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/cgroupdziała dla mnie na Dockerze 18.09.
Docker tworzy .dockerenvplik 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-containeri 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.
.dockerinitplik został usunięty w ostatnich wersjach Dockera , więc ta metoda nie będzie już działać. W chwili pisania tego .dockerenvpliku plik jest nadal przechowywany, więc być może można go zamiast tego użyć.
/bin/running-in-containerjest 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()
kubepodschyba.
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.
shi nie initma, 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=lxczmienną, jesteś w kontenerze.
W przeciwnym razie, jeśli jesteś rootem, możesz spróbować wykonać mknodlub wykonać mountoperację, jeśli to się nie powiedzie, najprawdopodobniej znajdziesz się w kontenerze z utraconymi możliwościami.
/proc/1/cgroupnie pozwala ci tego wykryć.
docker run alpine envnie 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/cgrouputworzeniu 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 .dockerinitw przyszłości.
W większości odmian Linuksa initjest 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 systemdlub launchdopartych ...
init), OpenRC, initng, runit. Zobacz tutaj . Większość nowoczesnych systemów opartych na Linuksie systemduż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-whatwersją 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/cgroupsą 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 =)
dockerOczywiście żaden plik binarny nie jest dostępny z wnętrza kontenera.
dockerdostęp do gniazda docker hosta .