web-dev-qa-db-ja.com

プロセスがlxc / Docker内で実行されているかどうかを確認する方法は?

プロセス(スクリプト)がlxcコンテナー内で実行されるかどうかを判断する方法はありますか(〜Dockerランタイム)?一部のプログラムは仮想マシン内で実行されているかどうかを検出できることを知っていますが、lxc/dockerでも同様のものが利用できますか?

142
Mate Varga

最も信頼できる方法は、/proc/1/cgroupを確認することです。これは、initプロセスのコントロールグループを示し、コンテナ内でnotの場合、すべての階層で/になります。 insideコンテナの場合、アンカーポイントの名前が表示されます。 LXC/Dockerコンテナでは、それぞれ/lxc/<containerid>または/docker/<containerid>のようなものになります。

144
jpetazzo

Dockerは、コンテナ内のディレクトリツリーのルートに.dockerenvファイルを作成します。このスクリプトを実行して確認できます

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


MORE: Ubuntuには実際にbashスクリプト/bin/running-in-containerがあり、実際に起動されたコンテナーのタイプを返すことができます。役立つかもしれません。ただし、他の主要なディストリビューションについては知りません。

139
at0S

新しいubuntu 16.04システム、新しいsystemdおよびlxc 2.0

Sudo grep -qa container=lxc /proc/1/environ
17
larss

Bashスクリプトでdockerを確認する簡潔な方法は次のとおりです。

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

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()
12
JJC

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)

これは、コンテナ内にいるかどうかを区別するのに役立ちます。

9
Founder

最も簡単な方法は、環境を確認することです。 container=lxc変数がある場合、コンテナ内にいます。

それ以外の場合、rootであれば、mknodまたはmount操作の実行を試みることができます。失敗した場合は、ほとんどの場合、機能がドロップされたコンテナーにいます。

6
creack

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)
5
blakev

私の答えはNode.jsプロセスにのみ適用されますが、Node.js固有の回答を探しているこの質問につまずく訪問者に関連する場合があります。

同じ問題があり、/proc/self/cgroupに依存して、Node.jsプロセスが実行されているかどうかを検出するために、この目的だけのためにnpmパッケージを作成しましたDockerコンテナ内かどうか。

コンテナ化されたnpmモジュール はNode.jsで役立ちます。現在、Io.jsではテストされていませんが、同様に動作する可能性があります。

3
Martin Tajur

Dockerは日々進化しているので、将来.dockerenv .dockerinitを保持するかどうかはわかりません。

ほとんどのLinuxフレーバーでは、initが最初に起動するプロセスです。しかし、コンテナの場合、これは真実ではありません。

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

/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
1
shalomb

JJCの回答をRubyに翻訳しました

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
0
Souradeep Nanda

このSO Q&A: 「OSが仮想環境で実行されているかどうかを調べる」 ; OPの質問と同じではありませんが、実際にどのコンテナにいるかを見つける一般的なケースに回答します(もしあれば)。

特に、このbashスクリプトのコードをインストールして読んでみてください。

virt-what

Sudo apt install virt-what
0
kaiwan