Чи є спосіб визначити, чи працює процес (скрипт) всередині контейнера lxc (~ час виконання Docker)? Я знаю, що деякі програми здатні виявити, чи працюють вони у віртуальній машині, чи є щось подібне для lxc / docker?
Чи є спосіб визначити, чи працює процес (скрипт) всередині контейнера lxc (~ час виконання Docker)? Я знаю, що деякі програми здатні виявити, чи працюють вони у віртуальній машині, чи є щось подібне для lxc / docker?
Відповіді:
Найбільш надійний спосіб - перевірити /proc/1/cgroup
. Він розповість вам про групи управління процесом init, і коли ви не знаходитесь в контейнері, це буде /
для всіх ієрархій. Коли ви знаходитесь всередині контейнера, ви побачите назву точки прив’язки. З контейнерами LXC / Docker це буде щось подібне /lxc/<containerid>
або /docker/<containerid>
відповідно.
docker
замість lxc
цих шляхів
/
для всіх груп; в моїй Debian 9 (Systemd 232) тільки три з десяти контрольних груп ( 3:cpuset
, 4:perf_event
і 7:freezer
) знаходяться в кореневому каталозі; решта - під /init.scope
. З цього приводу я думаю, що пошук цього файлу :/docker/
, мабуть, є найбільш надійним евристичним на даний момент.
grep 'docker\|lxc' /proc/1/cgroup
працює для мене на Docker 18.09.
Docker створює .dockerenv
файл у корені дерева каталогів всередині контейнера. Ви можете запустити цей сценарій для підтвердження
#!/bin/bash
if [ -f /.dockerenv ]; then
echo "I'm inside matrix ;(";
else
echo "I'm living in real world!";
fi
БІЛЬШЕ:
Насправді Ubuntu має сценарій bash: /bin/running-in-container
і він фактично може повернути тип контейнера, в який він викликався. Можливо, це буде корисним. Не знаю, проте, про інші основні дистрибуції.
.dockerinit
файл видалено в останніх версіях Docker , тому цей спосіб більше не працюватиме. На момент написання цього .dockerenv
файлу все ще зберігається, тому, можливо, він може бути використаний замість цього.
/bin/running-in-container
надає компанія upstart
. З переходом на systemd він може піти. Сподіваюсь, що ні - це звучить корисно!
.dockerenv
є не рекомендується
На новій системі ubuntu 16.04 новий systemd & lxc 2.0
sudo grep -qa container=lxc /proc/1/environ
Зручна функція Python, щоб перевірити, чи працює в Docker:
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
я здогадуюсь.
Для вилучення PID процесу ми використовуємо scha (/ proc / $ PID / sched). PID процесу всередині контейнера буде відрізнятися, тоді це PID на хості (без контейнерної системи).
Наприклад, вихід / proc / 1 / sched на контейнер поверне:
root@33044d65037c:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)
Перебуваючи на неконтейнерному хості:
$ cat /proc/1/sched | head -n 1
init (1, #threads: 1)
Це допомагає розрізнити, знаходитесь ви в контейнері чи ні.
sh
і не init
існує, але це може бути майже все , що ні в одному.
bash-5.0# cat /proc/1/sched bash (1, #threads: 1)
Найпростіше було б перевірити навколишнє середовище. Якщо у вас є container=lxc
змінна, ви знаходитесь в контейнері.
В іншому випадку, якщо ви root, ви можете спробувати виконати mknod
або виконати mount
операцію, якщо це не вдасться, ви, швидше за все, знаходитесь в контейнері зі скинутими можливостями.
/proc/1/cgroup
це не дозволяє виявити.
docker run alpine env
не дає нічого, що схоже на цю змінну
Моя відповідь стосується лише процесів Node.js, але може бути актуальною для деяких відвідувачів, які натрапляють на це питання, шукаючи конкретної відповіді Node.js.
У мене була така ж проблема, і покладаючись на те, що /proc/self/cgroup
я створив пакет npm виключно для цієї мети - виявити, чи працює процес Node.js всередині контейнера Docker чи ні.
Контейнерний модуль НПМ допоможе вам в Node.js. В даний час він не тестується в Io.js, але може також так само добре працювати там.
Перевірте всі рішення вище в Python:
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())
Доказ концепції:
$ 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')
відповідно до прийнятої відповіді тут stackoverflow.com/questions/20010199/…
cat
! Хороший :-D
Докер розвивається з кожним днем, тому ми не можемо точно сказати, чи збираються вони .dockerenv .dockerinit
в майбутньому.
У більшості Linux аромати init
- це перший процес, який розпочато. Але у випадку з контейнерами це неправда.
#!/bin/bash
if ps -p1|grep -q init;then
echo "non-docker"
else
echo "docker"
fi
init
, що не відповідає дійсності systemd
або launchd
на базі систем ...
init
хоча), OpenRC, initng, runit. Дивіться тут . Використовували б більшість сучасних систем на базі Linux systemd
, деякі старіші, на початку .... Всі сучасні системи OS X використовували бlaunchd
Це ТАК питання: "Дізнайтесь, чи працює ОС у віртуальному середовищі" ; Хоча це не те саме, що питання ОП, воно дійсно відповідає на поширені випадки пошуку того, в якому контейнері ви знаходитесь (якщо він є).
Зокрема, встановіть та прочитайте код цього скрипту bash, який, здається, працює досить добре:
virt-що :
sudo apt install virt-what
virt-what
версією 1.14-1 на Ubuntu 16.04. Потребує виправлення.
Відповідь JJC я переклав на рубін
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
У контейнері docker записи /proc/self/cgroup
монтуються до груп на хості.
наприклад у контейнері
# awk -F: '/cpuset/' /proc/self/cgroup
3:cpuset:/docker/22bd0c154fb4e0d1b6c748faf1f1a12116acc21ce287618a115ad2bea41256b3
тоді як те саме на хості
$ awk -F: '/cpuset/' /proc/self/cgroup
3:cpuset:/
Використання чого-небудь в оболонці для тесту на низький профіль
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
Можливо, це зробити трюк:
if [ -z $(docker ps -q) ]; then
echo "There is not process currently running"
else
echo "There are processes running"
fi
Це те, чого ти хочеш? Сподіваюся, що це допомагає =)
docker
двоичная доступний з внутрішньої сторони контейнера, очевидно.
docker
доступ та доступ до гнізда докера хоста.