web-dev-qa-db-ja.com

プロセスがdockerコンテナー内で実行されているかどうかを確認する方法

[Updated1]一部の関数でTCPカーネルパラメーターを変更するシェルがありますが、このシェルをDockerコンテナーで実行する必要があります。つまり、シェルは実行中であることを知る必要がありますコンテナ内でカーネルの構成を停止します。

今、私はそれを達成する方法がわかりません、これはコンテナ内の/proc/self/cgroupの内容です:

9:hugetlb:/
8:perf_event:/
7:blkio:/
6:freezer:/
5:devices:/
4:memory:/
3:cpuacct:/
2:cpu:/docker/25ef774c390558ad8c4e9a8590b6a1956231aae404d6a7aba4dde320ff569b8b
1:cpuset:/

上記のフラグを使用して、このプロセスがコンテナ内で実行されているかどうかを判断できますか?

[Updated2]: プロセスがlxc/Docker内で実行されるかどうかを判断する にも気付きましたが、この場合は動作していないようです。私のコンテナの/proc/1/cgroupの内容は次のとおりです。

8:perf_event:/
7:blkio:/
6:freezer:/
5:devices:/
4:memory:/
3:cpuacct:/
2:cpu:/docker/25ef774c390558ad8c4e9a8590b6a1956231aae404d6a7aba4dde320ff569b8b
1:cpuset:/

いいえ/ lxc/containerid

61
harryz

Dockerコンテナ内にいるかどうかをDockerコンテナ内で確認するには、/proc/1/cgroupを使用します。 この投稿 は、次のことができることを示唆しています。

Dockerコンテナの外部では、次のように/proc/1/cgroupのすべてのエントリが/で終了します。

vagrant@ubuntu-13:~$ cat /proc/1/cgroup
11:name=systemd:/
10:hugetlb:/
9:perf_event:/
8:blkio:/
7:freezer:/
6:devices:/
5:memory:/
4:cpuacct:/
3:cpu:/
2:cpuset:/

Dockerコンテナー内では、いくつかのコントロールグループがDocker(またはLXC)に属します。

vagrant@ubuntu-13:~$ docker run busybox cat /proc/1/cgroup
11:name=systemd:/
10:hugetlb:/
9:perf_event:/
8:blkio:/
7:freezer:/
6:devices:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2
5:memory:/
4:cpuacct:/
3:cpu:/docker/3601745b3bd54d9780436faa5f0e4f72bb46231663bb99a6bb892764917832c2
2:cpuset:/
52
Thomas Uhrig

Dockerは.dockerenvを作成し、 .dockerinit ( v1.11で削除済み )コンテナのディレクトリツリーの最上部にあるファイルなので、それらが存在するかどうかを確認できます。

このような何かが動作するはずです。

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

Procのsched(/ proc/$ PID/sched)を使用して、プロセスのPIDを抽出します。コンテナ内のプロセスの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)

これは、コンテナ内にいるかどうかを区別するのに役立ちます。たとえば、次のことができます。

if [[ ! $(cat /proc/1/sched | head -n 1 | grep init) ]]; then {
    echo in docker
} else {
    echo not in docker
} fi
19
Founder

コードとしてのトーマスのソリューション:

running_in_docker() {
  (awk -F/ '$2 == "docker"' /proc/self/cgroup | read non_empty_input)
}

注意

ダミー変数を持つreadは、の単純なイディオムです。これは出力を生成しますか?。冗長なgrepまたはawkをパターンのtestに変換するためのコンパクトな方法です。

読み取りに関する追加の注記

16
Henk Langeveld

私にとって有効なのは、「/」のiノード番号を確認することです。港湾労働者の内部では、その非常に高い数。ドッカーの外側では、「2」のような非常に低い数値です。このアプローチは、使用されているFileSystemにも依存すると考えています。

ドッカーの内部:

# ls -ALi / | sed '2!d' |awk {'print $1'}
1565265

ドッカーの外側

$ ls -ALi / | sed '2!d' |awk {'print $1'}
2

スクリプト内:

#!/bin/bash
INODE_NUM=`ls -ALi / | sed '2!d' |awk {'print $1'}`
if [ $INODE_NUM == '2' ];
then
        echo "Outside the docker"
else
        echo "Inside the docker"
fi
1
trohit

コンテナで実行されているプロセスを除外する必要がありましたが、docker cgroupだけをチェックする代わりに、/proc/<pid>/ns/pidの初期化システム/proc/1/ns/pid。例:

pid=$(ps ax | grep "[r]edis-server \*:6379" | awk '{print $1}')
if [ $(readlink "/proc/$pid/ns/pid") == $(readlink /proc/1/ns/pid) ]; then
   echo "pid $pid is the same namespace as init system"
else
   echo "pid $pid is in a different namespace as init system"
fi

または、プロセスがコンテナ内にない場合にエラーを生成する1つのライナーが必要でした。

bash -c "test -h /proc/4129/ns/pid && test $(readlink /proc/4129/ns/pid) != $(readlink /proc/1/ns/pid)"

別のプロセスから実行できます。終了コードがゼロの場合、指定されたPIDは別のネームスペースで実行されています。

1
Greg Bray

私は小さなpythonスクリプトを作成しました。誰かがそれを役立ててくれることを願っています。:-)

#!/usr/bin/env python3
#@author Jorge III Altamirano Astorga 2018
import re
import math

total = None
meminfo = open('/proc/meminfo', 'r')
for line in meminfo:
    line = line.strip()
    if "MemTotal:" in line:
        line = re.sub("[^0-9]*", "", line)
        total = int(line)
meminfo.close()
print("Total memory: %d kB"%total)

procinfo = open('/proc/self/cgroup', 'r')
for line in procinfo: 
    line = line.strip()
    if re.match('.{1,5}:name=systemd:', line):
        dockerd = "/sys/fs/cgroup/memory" + \
            re.sub("^.{1,5}:name=systemd:", "", line) + \
            "/memory.stat"
        #print(dockerd)
        memstat = open(dockerd, 'r')
        for memline in memstat:
            memline = memline.strip()
            if re.match("hierarchical_memory_limit", memline):
                memline = re.sub("[^0-9]*", \
                    "", memline)  
                total = math.floor(int(memline) / 2**10)
        memstat.close()
procinfo.close()
print("Total available memory to the container: %d kB"%total)
0