コンテナー内からDocker Linuxコンテナー情報を取得するにはどうすればよいですか?


135

docker containersメタデータを通じてEC2インスタンスに関する情報を取得できるのと同じ方法で、それらの構成を認識させたいと思います。

使用できます(ただしdocker、ポートでリッスンしている場合4243

curl http://172.17.42.1:4243/containers/$HOSTNAME/json

データの一部を取得しますが、少なくともコンテナの完全なIDを取得するためのより良い方法があるかどうかを知りたいのですが、HOSTNAME実際には12文字に短縮されており、Dockerはコンテナに対して「最適な一致」を実行しているようです。

また、Dockerホストの外部IPを取得するにはどうすればよいですか(AWSに固有のEC2メタデータにアクセスする以外)


2
注意:コンテナー内で/var/run/docker.sockを使用する以下のアプローチを試みる前に、このlvh.io/posts/…を読んでください
harschware

1
@harschwareのリンクが壊れた場合は、ここで要約します。コンテナーにへのアクセス権を与えることにより、docker /var/run/docker.sockによって提供されたコンテインメントから抜け出し、ホストマシンへのアクセス権を取得することができます(簡単です)。明らかにこれは潜在的に危険です。
ジョン

1
--hostname引数がrunコマンドで使用され、「hostname」を実行するだけでコンテナーIDが得られなくなった場合、Windows Dockerコンテナーで同じ情報を取得する方法を知っている人はいますか?
ティモシージョンレアード

回答:


68

コンテナーIDが/ proc / self / cgroupにあることがわかりました

だからあなたはIDを取得することができます:

cat /proc/self/cgroup | grep -o  -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"

15
少し微調整する必要があったのですが、これはDocker 1.4.1 cat /proc/self/cgroup | grep "docker" | sed s/\\//\\n/g | tail -1
ICasで

5
ドッキングウィンドウ1.6.2のために私が使用していた:cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1
ジェイ・テイラー

14
Aaaaand Docker 1.12:cat /proc/1/cgroup | grep 'docker/' | tail -1 | sed 's/^.*\///' | cut -c 1-12
smets.kevin 2016

24
私はちょっと好きだしbasename "$(cat /proc/1/cpuset)"basename "$(head /proc/1/cgroup)"
マケディは

3
将来、cgroup名前空間とcgroup v2がdockerで使用される場合、このメソッドは機能しなくなる可能性があります。
Jing Qiu

69

オーバーライドされない限り、ホスト名はDocker 1.12の短いコンテナIDのようです

root@d2258e6dec11:/project# cat /etc/hostname
d2258e6dec11

外部的に

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED                 STATUS                      PORTS               NAMES
d2258e6dec11        300518d26271        "bash"              5 minutes ago       

$ docker -v
Docker version 1.12.0, build 8eab29e, experimental

4
うん、これでnodejsの情報を簡単に取得できるようになった。const os = require('os'); console.log(os.hostname());
pulkitsinghal

2
JavaのコンテナIDと一致するホスト名を取得するには、を使用しますInetAddress.getLocalHost().getHostName()
ネイサン

2
環境変数の値を読み取る方が簡単な場合があります$HOSTNAME(たとえば、シェルスクリプトで)。
Faheel

34

Docker Remote API経由でunixソケットを使用して、コンテナー内からdockerと通信できます。

https://docs.docker.com/engine/reference/api/docker_remote_api/

コンテナーでは、$HOSTNAMEenv varを調べることで、短絡されたDocker IDを見つけることができます。資料によると、衝突の可能性はわずかですが、コンテナの数が少ない場合は、心配する必要はないと思います。完全なIDを直接取得する方法がわかりません。

バニヤンの答えで概説されているのと同じ方法でコンテナを検査できます:

GET /containers/4abbef615af7/json HTTP/1.1

応答:

HTTP/1.1 200 OK
Content-Type: application/json

{
         "Id": "4abbef615af7......  ",
         "Created": "2013.....",
         ...
}

または、docker idをファイル内のコンテナーに転送することもできます。ファイルは「マウントされたボリューム」にあるため、コンテナに転送されます。

docker run -t -i -cidfile /mydir/host1.txt -v /mydir:/mydir ubuntu /bin/bash

Docker ID(短縮)は、コンテナーのファイル/mydir/host1.txtにあります。


2
おかげで、これは私がとにかく使用しているのと同じアプローチであり、dockerを実行するときに-hでホスト名を設定すると機能しなくなります。
アレッサンドロ

@Alessandro -cidfileパラメーターに関する情報をdocker runに追加しました。$ HOSTNAMEを使用する代わりに、Docker IDをコンテナーに渡すのに役立つ場合があります。
Jiri

すごい!はい、それは私が使えるものです!ありがとうございました!
アレッサンドロ

奇妙なことに、1.11.2ではenvは表示されないようですがHOSTNAMEecho $HOSTNAME動作します。
Jesse Glick 2016年

これはまったく機能せず、URLが壊れて、間違ったドキュメントにリダイレクトされます。requests.exceptions.MissingSchema: Invalid URL '/containers/1d26a841bf07/json': No schema supplied. Perhaps you meant http:///containers/1d26a841bf07/json?
セリン

24

これは、コンテナー内から完全なコンテナーIDを取得します。

cat /proc/self/cgroup | grep "cpu:/" | sed 's/\([0-9]\):cpu:\/docker\///g'


21

警告:この方法を検討する前に、この方法のセキュリティリスクを理解する必要があります。ジョンのリスクの要約:

コンテナにへのアクセス権を与えることにより/var/run/docker.sock、Dockerによって提供されたコンテインメントを抜け出し、ホストマシンへのアクセス権を取得することは[非常に簡単]です。明らかにこれは潜在的に危険です。


コンテナ内で、dockerIdはホスト名です。したがって、次のことができます。

  • ホストと同じバージョンのコンテナーにdocker-ioパッケージをインストールします
  • で始まる --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • 最後に、実行:docker inspect $(hostname)コンテナー内

これは避けてください。リスクを理解し、リスクを明確に軽減できる場合にのみ、それを行ってください。


1
docker run --hostnameオプションが使用されている場合、これは機能しないと思います。
hairyhenderson 2015年

--hostnameが設定されている場合、この回答の組み合わせと、@ Jay Taylorのコメントを受け入れ済みの回答に使用しdocker inspect $(cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1)て、実行中のコンテナに関するすべての情報を取得できます。
マイケルK.

docker-ioへの参照を配置できますか?
Brad P.

私はそのnpmjs.com/package/docker-ioを想定していますが、それはGoogleが私に言ったことであり、おそらくあなたが意図したものではありません。
Brad P.

15

簡単にするために、

  1. コンテナIDは、Docker内のホスト名です
  2. コンテナー情報は/ proc / self / cgroup内にあります

ホスト名を取得するには、

hostname

または

uname -n

または

cat /etc/host

出力は任意のファイルにリダイレクトでき、アプリケーションから読み返すことができます。 # hostname > /usr/src//hostname.txt


10

17.09では、Dockerコンテナー内でこれを行う最も簡単な方法があることがわかりました。

$ cat /proc/self/cgroup | head -n 1 | cut -d '/' -f3
4de1c09d3f1979147cd5672571b69abec03d606afcc7bdc54ddb2b69dec3861c

または、既に伝えられているように、

$ cat /etc/hostname
4de1c09d3f19

または単に:

$ hostname
4de1c09d3f19

6

Dockerはデフォルトでホスト名をコンテナーIDに設定しますが、ユーザーはこれをでオーバーライドできます--hostname。代わりに、検査してください/proc

$ more /proc/self/cgroup
14:name=systemd:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
13:pids:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
12:hugetlb:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
11:net_prio:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
10:perf_event:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
9:net_cls:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
8:freezer:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
7:devices:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
6:memory:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
5:blkio:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
4:cpuacct:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
3:cpu:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
2:cpuset:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
1:name=openrc:/docker

コンテナIDを抽出するための便利な1行を次に示します。

$ grep "memory:/" < /proc/self/cgroup | sed 's|.*/||'
7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605

2

このコマンドラインを使用して、現在のコンテナーID(docker 1.9でテスト済み)を識別できます。

awk -F"-|/." '/1:/ {print $3}' /proc/self/cgroup

次に、Docker APIへの小さなリクエスト(/var/run/docker.sockを共有できます)ですべての情報を取得します。


1
awk -F "-| /。" '/ 1:/ {print $ 3}' / proc / self / cgroup
usil

2

の形式の変更により、投稿されたソリューションの一部が機能しなくなりました/proc/self/cgroup。以下は、変更をフォーマットするためにもう少し堅牢な単一のGNU grepコマンドです。

grep -o -P -m1 'docker.*\K[0-9a-f]{64,}' /proc/self/cgroup

参考までに、このコマンドでテストされたDockerコンテナー内からの/ proc / self / cgroupの抜粋を次に示します。

Linux 4.4:

11:pids:/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope
...
1:name=systemd:/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope

Linux 4.8-4.13:

11:hugetlb:/docker/afe96d48db6d2c19585572f986fc310c92421a3dac28310e847566fb82166013
...
1:name=systemd:/docker/afe96d48db6d2c19585572f986fc310c92421a3dac28310e847566fb82166013


0

余談ですが、コンテナーのpidがあり、そのコンテナーのdocker idを取得したい場合は、上記のsedマジックとnsenterを組み合わせて使用​​することをお勧めします。

nsenter -n -m -t pid -- cat /proc/1/cgroup | grep -o -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"


-19

を使用しdocker inspectます。

$ docker ps # get conteiner id
$ docker inspect 4abbef615af7
[{
    "ID": "4abbef615af780f24991ccdca946cd50d2422e75f53fb15f578e14167c365989",
    "Created": "2014-01-08T07:13:32.765612597Z",
    "Path": "/bin/bash",
    "Args": [
        "-c",
        "/start web"
    ],
    "Config": {
        "Hostname": "4abbef615af7",
...

次のようにipを取得できます。

$ docker inspect -format="{{ .NetworkSettings.IPAddress }}" 2a5624c52119
172.17.0.24

5
これは私が言っていることではありません。コンテナーからこの情報を取得できるようにする必要があります。基本的に、内部から実行しているコンテナーのIDを理解する方法が必要ですか。
アレッサンドロ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.