プロセス(スクリプト)が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/cgroupDocker 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-whatUbuntu 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など)では失敗します。