プロセス(スクリプト)がlxcコンテナー(〜Dockerランタイム)内で実行されているかどうかを確認する方法はありますか?一部のプログラムは、仮想マシン内で実行されているかどうかを検出できることを知っています。lxc/ dockerでも同様のものが利用できますか?
プロセス(スクリプト)がlxcコンテナー(〜Dockerランタイム)内で実行されているかどうかを確認する方法はありますか?一部のプログラムは、仮想マシン内で実行されているかどうかを検出できることを知っています。lxc/ dockerでも同様のものが利用できますか?
回答:
最も信頼できる方法はチェックすること/proc/1/cgroup
です。これにより、initプロセスの制御グループがわかります。コンテナー内にいない場合は/
、すべての階層が対象になります。コンテナー内にいるときは、アンカーポイントの名前が表示されます。LXC / Dockerコンテナを使用すると/lxc/<containerid>
、/docker/<containerid>
それぞれのようなものになります。
docker
なくを使用するようになりlxc
ました
/
、すべてのcgroup にプロセス1を使用することはできないようです。私のDebian 9システム(systemd 232)では、10個のcgroup(3:cpuset
、4:perf_event
および7:freezer
)の3つだけがルートにあります。残りは下/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
ファイルが削除されているため、この方法は機能しなくなります。これを書いている時点では、.dockerenv
ファイルはまだ残っているので、おそらく代わりに使用できます。
/bin/running-in-container
が提供していupstart
ます。systemdへの移行により、それはなくなるかもしれません。私はそうではないと思います-それは便利に聞こえます!
新しいUbuntu 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 / $ 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
していません)だけでなく、lxd / lxcコンテナー(チェック済み)でも機能します。
docker run alpine env
その変数のように見えるものは何も与えません
私の回答はNode.jsプロセスにのみ適用されますが、Node.js固有の回答を探してこの質問につまずく一部の訪問者に関連する可能性があります。
私は同じ問題を抱えており、Node.jsプロセスがDockerコンテナー内で実行されているかどうかを検出するためだけに、この目的のためだけにnpmパッケージ/proc/self/cgroup
を作成しました。
コンテナNPMモジュールは 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
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。こちらをご覧ください。最近のほとんどのLinuxベースのシステムはを使用しsystemd
、一部の古いシステムは新興します。最新のOS Xシステムはすべて使用しますlaunchd
このSOに関するQ&A:「OSが仮想環境で実行されているかどうかを確認してください」 ; OPの質問と同じではありませんが、実際にどのコンテナーにいるかを(あるとしても)見つける一般的なケースに答えます。
特に、このbashスクリプトのコードをインストールして読んでください。
virt-what:
sudo apt install virt-what
virt-what
Ubuntu 16.04のバージョン1.14-1では動作しません。パッチが必要です。
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
はホストの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
ホストのDockerソケットにアクセスしてアクセスできる状況(gitlab docker-in-dockerなど)では失敗します。