2013-11-15 5 views
88

Есть ли способ определить, выполняется ли процесс (скрипт) внутри контейнера lxc (~ время выполнения Docker)? Я знаю, что некоторые программы могут определить, работают ли они на виртуальной машине, что-то подобное для lxc/docker?Определение, выполняется ли процесс внутри lxc/Docker

+0

Это может показаться педантичным, но лучше всего перефразировать ваш вопрос, чтобы описать проблему, с которой вы столкнулись, и спросить, как ее решить - без t шляпа, вопрос имеет более высокий шанс быть закрытым. Во многих случаях это трудно изменить, но в вашем случае было бы непросто перефразировать, если хотите. – mah

+0

есть интересный ответ при выдаче этой команды в контейнере: время безотказной работы –

ответ

87

Самый надежный способ - проверить /proc/1/cgroup. Он сообщит вам группы управления процесса инициализации, а когда вы находитесь , а не в контейнере, это будет / для всех иерархий. Когда вы внутри контейнер, вы увидите название точки привязки; который, с контейнерами LXC/Docker, будет примерно /lxc/<containerid> или /docker/<containerid> соответственно.

+10

docker теперь использует 'docker' вместо' lxc' в этих путях – Andy

+3

Не работает для контейнеров lxd/lxc, но http://stackoverflow.com/a/20010626/170230. –

+0

С более поздними версиями systemd похоже, что вы не можете полагаться на процесс 1, используя '/' для всех групп; на моей системе Debian 9 (systemd 232) только три из десяти групп ('3: cpuset',' 4: perf_event' и '7: freezer') находятся в корне; остальные находятся под '/ init.scope'. Тем не менее, я думаю, что поиск этого файла для ':/docker /', вероятно, является наиболее надежной эвристикой на данный момент. –

9

Самый простой способ - проверить окружающую среду. Если у вас есть переменная container=lxc, вы находитесь в контейнере.

В противном случае, если вы являетесь пользователем root, вы можете попробовать выполнить операцию mknod или mount, если она не удалась, вы, скорее всего, находитесь в контейнере со сброшенными возможностями.

+0

Это работает не только для докеров (я этого не проверял), но что более важно для контейнеров lxd/lxc (checked), где '/ proc/1/cgroup' не позволяет вам это обнаружить. –

+0

Не работает для Docker. Переменная не установлена. – hakre

+0

вы можете отредактировать ответ с кодом вместо псевдокода? «container = lxc»? не является правильным. вы имеете в виду что-то вроде if [["lxc" = "$ container"]]? –

81

Docker создает файл .dockerenv в корне дерева каталогов внутри контейнера. Вы можете запустить этот скрипт для проверки

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


MORE: Ubuntu на самом деле имеет Баш скрипт:. /bin/running-in-container и он на самом деле может возвращать тип контейнера он был вызван в Может быть полезно. Не знаю о других крупных дистрибутивах.

+8

Важное примечание: файл '.dockerinit' [был удален в последних версиях Docker] (https://github.com/docker/docker/issues/18355), поэтому этот метод больше не будет работать. На момент написания этого файла файл '.dockerenv' по-прежнему хранился, поэтому, возможно, его можно было бы использовать. –

+0

В Debian '/ bin/running-in-container' предоставляется' upstart'. С переходом на systemd он может исчезнуть. Надеюсь, что нет - это звучит полезно! –

+0

«поверх дерева каталогов», что это значит? где это? –

3

Мой ответ применим только для Процессы Node.js, но могут иметь значение для некоторых посетителей, которые спотыкаются на этот вопрос, ища конкретный ответ Node.js.

У меня была такая же проблема, и опираясь на /proc/self/cgroup я создал пакет НПМ для исключительно с этой целью - обнаружить ли работает процесс Node.js внутри контейнера Докер или нет.

containerized npm module поможет вам в Node.js. В настоящее время он не тестируется в Io.js, но может также работать там.

8

На новой системы Ubuntu 16.04, новый Systemd & LXC 2,0

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

Мы используем прок в SCHED (/ ргос/$ PID/SCHED) для извлечения PID процесса. ПИД-процесс процесса внутри контейнера будет отличаться, то есть PID на хосте (неконтейнерная система).

Например, выход/Proc/1/SCHED на контейнере вернется:

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

В то время как на не-контейнера хоста:

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

Это помогает дифференцировать если вы находитесь в контейнере или нет.

+0

В зависимости от ОС «init» может потребоваться заменить на «systemd». Дополнительная информация о systemd [здесь] (https://www.tecmint.com/systemd-replaces-init-in-linux/). – BrianV

2

Docker развивается изо дня в день, поэтому мы не можем точно сказать, сохранят ли они в будущем .dockerenv .dockerinit.

В большинстве вариантов Linux init - это первый процесс запуска. Но в случае с контейнерами это не так.

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

Это не работает под MacOS X. –

+5

@RomanTrofimov LXC/Docker тоже не работает. Какой смешной комментарий. – abourget

+0

Он также не работает в centos 7. Когда я запускаю свою машину, она говорит докер.Похоже, systemd запущен как идентификатор процесса 1 –

5

Краткий способ проверить грузчиком в Баш скрипт является:

функция
#!/bin/bash 
if grep docker /proc/1/cgroup -qa; then 
    echo I'm running on docker. 
fi 
5

Handy Python, чтобы проверить, работает в Докер (Linux-только, 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

This SO Q & A: "Find out if the OS is running in a virtual environment"; хотя и не совпадает с вопросом OP, он действительно отвечает на обычные случаи нахождения того контейнера, в котором вы находитесь (если вообще).

В частности, установить и прочитать код этого Баш скрипт, который, кажется, работает очень хорошо:

вирт-то, что:

sudo apt install virt-what 
+0

Не работает с 'virt-what' version 1.14 -1 на Ubuntu 16.04. Нужен патч. – Lucas

1

Проверить для всех перечисленных выше в 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) 
Смежные вопросы