프로세스 (스크립트)가 lxc 컨테이너 내에서 실행되는지 확인하는 방법이 있습니까 (~ Docker runtime)? 일부 프로그램이 가상 시스템 내에서 실행되는지 여부를 감지 할 수 있다는 것을 알고 있습니다.
프로세스 (스크립트)가 lxc 컨테이너 내에서 실행되는지 확인하는 방법이 있습니까 (~ Docker runtime)? 일부 프로그램이 가상 시스템 내에서 실행되는지 여부를 감지 할 수 있다는 것을 알고 있습니다.
답변:
가장 신뢰할 수있는 방법은 확인하는 것 /proc/1/cgroup
입니다. 그것은 당신에게 init 프로세스의 컨트롤 그룹을 알려줄 것이고 당신이 컨테이너에 있지 않을 때는 /
모든 계층을위한 것입니다. 컨테이너 안에 있으면 앵커 포인트의 이름이 표시됩니다. LXC / Docker 컨테이너를 사용하면 비슷 /lxc/<containerid>
하거나 /docker/<containerid>
각각 비슷 합니다.
docker
대신에 사용 lxc
합니다
/
모든 cgroup에 사용하는 프로세스 1에 의존 할 수없는 것처럼 보입니다 . 내 데비안 9 시스템 (시스템 232)에서는 열 개의 cgroup ( 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
더 :
우분투는 실제로 bash 스크립트를 가지고 있으며 /bin/running-in-container
실제로 호출 된 컨테이너 유형을 반환 할 수 있습니다. 도움이 될 수 있습니다. 그래도 다른 주요 배포판에 대해서는 모른다.
.dockerinit
파일이 제거 되었으므로이 방법은 더 이상 작동하지 않습니다. 이 글을 쓰는 시점에서 .dockerenv
파일은 계속 유지되므로 대신 사용할 수 있습니다.
/bin/running-in-container
은에서 제공합니다 upstart
. systemd로 전환하면 사라질 수 있습니다. 도움이되지 않기를 바랍니다.
새로운 우분투 16.04 시스템, 새로운 systemd & lxc 2.0
sudo grep -qa container=lxc /proc/1/environ
Docker에서 실행 중인지 확인하는 편리한 Python 함수 :
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를 추출하기 위해 proc의 sched (/ 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
변수 가 있으면 컨테이너 내에 있습니다.
그렇지 않으면 루트 인 경우 수행 mknod
또는 mount
조작을 시도 할 수 있으며 , 실패하면 기능이 떨어지는 컨테이너에있을 가능성이 높습니다.
/proc/1/cgroup
작동합니다.
docker run alpine env
변수처럼 보이는 것은 없습니다
내 답변은 Node.js 프로세스 에만 적용 되지만 Node.js 관련 답변을 찾는이 질문에 걸려 넘어지는 일부 방문자에게는 관련이있을 수 있습니다.
동일한 문제가 있었고 Node.js 프로세스가 Docker 컨테이너 내에서 실행되는지 여부를 감지하기 위해이 목적으로 만 npm 패키지 를 /proc/self/cgroup
만들었습니다 .
컨테이너 NPM 모듈은 Node.js.에 당신을 도울 것입니다 현재 Io.js에서 테스트되지는 않았지만 작동 할 수도 있습니다.
파이썬에서 위의 모든 솔루션을 확인하십시오.
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
! 좋은 것
Docker는 날마다 진화하고 있으므로 .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. 여기를 참조하십시오 . 대부분의 최신 리눅스 기반의 시스템을 사용하는 것이 systemd
일부 오래된 것들, 신출내기 .... 모든 현대의 OS X 시스템을 사용하는 것,launchd
이 SO Q & A : "OS가 가상 환경에서 실행되고 있는지 확인하십시오" ; OP의 질문과 동일하지는 않지만 실제로 어떤 컨테이너에 있는지 (있는 경우) 찾는 일반적인 경우에 대답합니다.
특히,이 bash 스크립트의 코드를 설치하고 읽으십시오.
미덕 :
sudo apt install virt-what
virt-what
Ubuntu 16.04의 버전 1.14-1 에서는 작동하지 않습니다 . 패치가 필요합니다.
도커 컨테이너에서 항목 /proc/self/cgroup
은 호스트의 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
있고 호스트의 도커 소켓에 액세스하는 상황 (예 : gitlab docker-in-docker)에서 실패 합니다.