Как определить, работает ли процесс внутри lxc/Docker?

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

Ответ 1

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

Ответ 2

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

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


MORE: Ubuntu на самом деле имеет bash script: /bin/running-in-container, и он фактически может вернуть тип контейнера, в который он был вызван. Может быть полезно. Однако не знаю о других крупных дистрибутивах.

Ответ 3

В новой системе ubuntu 16.04 новые systemd и lxc 2.0

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

Ответ 4

Кратким способом проверки докеров в bash script является:

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

Ответ 5

Удобная функция 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()

Ответ 6

Мы используем расписание proc (/proc/$PID/sched) для извлечения PID процесса. Процесс 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)

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

Ответ 7

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

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

Ответ 8

Проверьте все решения выше в 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)

Ответ 9

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

У меня была такая же проблема, и я полагался на /proc/self/cgroup, я создал пакет npm только для этой цели - определить, выполняется ли процесс Node.js внутри контейнера Docker или нет.

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

Ответ 10

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

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

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

Ответ 11

Опираясь на принятый ответ, тестирует /proc/*/cgroup.

awk -F: '$3 ~ /^\/$/ {c=1} END{ exit c }' /proc/self/cgroup

Таким образом, для использования в скрипте или около того, тест может быть построен таким образом.

is_running_in_container() {
  awk -F: '$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

Ответ 12

Этот SO Q & A: "Узнайте, работает ли ОС в виртуальной среде" ; хотя и не то же самое, что и вопрос OP, он действительно отвечает на общие случаи нахождения того контейнера, в котором вы находитесь (если вообще).

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

virt-what:

sudo apt install virt-what

Ответ 13

Я перевел ответ 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

Ответ 14

Может быть, это сделать трюк:

if [ -z $(docker ps -q) ]; then
    echo "There is not process currently running"
else
    echo "There are processes running"
fi