Dockerコンテナーのファイルシステムの探索


651

コンテナー内で何が起こっているのか、またはコンテナー内にどのファイルが存在するのかを理解する必要があることが、Dockerでわかりました。1つの例は、Dockerインデックスから画像をダウンロードすることです。画像に何が含まれているかがわからないため、アプリケーションを起動できません。

理想的には、sshでそれらまたは同等のものにアクセスできるようにすることです。これを行うためのツールはありますか、または私がこれを行うことができるはずであると考える私の港湾労働者の概念化は間違っていますか?


13
Dockerの最新バージョンでは、次のようなことが可能ですdocker exec <container> bash。したがって、コンテナー内のシェルを開くだけです。
dashohoxha 2016

7
コンテナー上でbashを実行できるのは、コンテナー内にbashがインストールされている場合のみです
Christopher Thomas

7
同様に、次のことができます:docker exec <container> ls <dir path>およびdocker exec <container> cat <file path>。ただし、bashの場合は-itオプションを追加します。
Noam Manos 2018


3
@ChristopherThomas、まさに。そのため、docker image save image_name > image.tar@ Gaurav24からの応答に示されているように、これを行うための唯一の堅牢な方法があることがわかりました。
Jaime Hablutzel、2018年

回答:


737

UPDATE
最も簡単な方法:docker execを使用する

Dockerバージョン1.3以降は、execと同様に動作するコマンドをサポートしていますnsenter。このコマンドは、すでに実行中のコンテナで新しいプロセスを実行できます(コンテナには、すでに実行されているPID 1プロセスが必要です)。実行/bin/bashしてコンテナの状態を調べることができます。

docker exec -t -i mycontainer /bin/bash

Dockerコマンドラインドキュメントを参照してください

代替方法1
スナップショット

この方法でコンテナファイルシステムを評価できます。

# find ID of your running container:
docker ps

# create image (snapshot) from container filesystem
docker commit 12345678904b5 mysnapshot

# explore this filesystem using bash (for example)
docker run -t -i mysnapshot /bin/bash

このようにして、実行中のコンテナのファイルシステムを正確なタイミングで評価できます。コンテナはまだ実行中で、将来の変更は含まれていません。

後でスナップショットを削除できます(実行中のコンテナーのファイルシステムは影響を受けません!):

docker rmi mysnapshot

代替方法2
ssh

継続的なアクセスが必要な場合は、sshdをコンテナーにインストールして、sshdデーモンを実行できます。

 docker run -d -p 22 mysnapshot /usr/sbin/sshd -D

 # you need to find out which port to connect:
 docker ps

このように、sshを使用してアプリを実行できます(接続して必要なものを実行します)。

更新:代替方法3
nsenter

を使用nsenterします。https://web.archive.org/web/20160305150559/http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/を参照してください

短いバージョンは次のとおりです。nsenterを使用すると、既存のコンテナーがSSHまたは任意の種類の専用デーモンを実行していない場合でも、シェルを既存のコンテナーに入れることができます。


6
ただし、ファイルにアクセスする必要がある場合は、「docker cp」コマンドを使用してください。使用法:docker cp CONTAINER:PATH HOSTPATHファイル/フォルダーをコンテナーファイルシステムからホストパスにコピーします。パスは、ファイルシステムのルートを基準にしています。#> docker cp 7bb0e258aefe:/ etc / debian_version。#> docker cp blue_frog:/ etc / hosts。
Amos Folarin 14

4
オプション4は非常に重要なので、一番上に移動して名前を変更する必要がありOption 1ます。
自己

5
@JanusTroelsenシェルがない場合はインストールできます。たとえば、アルパインLinuxのdockerfile(実際にはシェルはありません)によって:(RUN apk update && apk add bashサイズ:
〜4MB

2
私自身の経験では、Docker execの制限は、コマンドを実行中のコンテナーに追加するか、一種のエントリーポイントとして追加する必要があることです。したがって、停止したコンテナはこのメソッドの範囲外です。
Webwoman 2018

1
WindowのLinuxシェルを使用するにはdocker exec -t -i mycontainer /bin/sh
Jason Masters

266

更新:探索!

このコマンドを実行すると、実行中のDockerコンテナー探索できます。

docker exec -it name-of-container bash

docker-composeでこれに相当するものは次のようになります。

docker-compose exec web bash

(この場合、webはサービス名であり、デフォルトでttyを持っています。)

いったん中に入ると:

ls -lsa

または次のような他のbashコマンド:

cd ..

このコマンドを使用すると、Dockerイメージ探索できます。

docker run --rm -it --entrypoint=/bin/bash name-of-image

中に入ったら:

ls -lsa

または次のような他のbashコマンド:

cd ..

-it対話型とtty の略です。


このコマンドにより、実行中のDockerコンテナーまたはイメージ検査できます。

docker inspect name-of-container-or-image

あなたはこれを行うと、任意のあったかどうかを確認することがありますbashsh、そこには。json returnでentrypointまたはcmdを探します。

docker execのドキュメントを参照してください

docker-compose execのドキュメントを参照してください

docker inspectのドキュメントを参照してください


1
これは非常に便利です、ありがとう!docker imageファイル構造内に含まれているファイルをアプリケーションにドラッグアンドドロップする必要がありますが、GUI形式で開かない限り、それは不可能です。どうすればそれを回避できるでしょうか?
Arkya Chatterjee

2
これは、bashがインストールされているコンテナでのみ機能することは明らかです。
ソフトウェアエンジニア

2
Windowsコンテナ/ docker exec -ti <name> powershell
Powershellで

1
@ssell私のコンテナー/イメージは、何らかの理由でpowershellを持っていなかったので、うまくいきdocker exec -ti <name> cmdました。そして、私のような他の初心者には、docker ps割り当てた読み取り可能な名前ではなく、コンテナインスタンス名(070494393ca5など)を使用してください。
Simon_Weaver 2018

1
画像内のPowerShellに関するgithub.com/aspnet/aspnet-docker/issues/362:あなたが唯一のWindowsイメージにカールが必要な場合- blogs.technet.microsoft.com/virtualization/2017/12/19/...
Simon_Weaver

162

コンテナが停止しているか、シェルがない場合(たとえばhello-worldインストールガイドに記載されている、または以外alpine traefik)は、おそらくこれがファイルシステムを探索する唯一の可能な方法です。

コンテナのファイルシステムをtarファイルにアーカイブできます。

docker export adoring_kowalevski > contents.tar

または、ファイルを一覧表示します。

docker export adoring_kowalevski | tar t

イメージによっては、多少の時間とディスク容量が必要になる場合があることに注意してください。


12
標準のUNIXツールがインストールされていないコンテナーの内容を一覧表示したかっただけです。変動export上記の例では、スポットをヒット:docker export adoring_kowalevski | tar tf -
Bertoの

3
不注意への警告:これは大量のデータ(> GB)をエクスポートし、長い時間がかかる可能性あります。
Vince Bowdren 2017年

5
@bertoは大規模なものではありませんが、f -コマンドの最後には必要ありません。tarはデフォルトで標準入力から読み取ります。単にdocker export adoring_kowalevski | tar t動作します。
Shaun Bouckaert 2017

シンプルなほど良いです。チップ、ありがとう!🙌🏽
Bertoの

1
@ShaunBouckaertのデフォルトtar fは、ユーザーの構成によって異なります。1つはTAPE環境変数です。その他は、ビルドの一部として制御されます。正味の効果は、標準入力を読み取ったり、標準出力を書き込んだりすることを想定せず、常に明示的に述べることです。
roaima

42

コンテナーのファイルシステムは、dockerのデータフォルダーにあり、通常は/ var / lib / dockerにあります。実行中のコンテナーファイルシステムを起動して検査するには、次の手順を実行します。

hash=$(docker run busybox)
cd /var/lib/docker/aufs/mnt/$hash

そして現在、現在の作業ディレクトリはコンテナのルートです。


3
ただし、これにはマウントされたボリュームは含まれません。
hwjp 2014

34

コンテナ作成前:

コンテナー内にマウントされているイメージの構造を調べる場合は、次のことができます

sudo docker image save image_name > image.tar
tar -xvf image.tar

これにより、jsonファイルに存在する画像とその構成のすべてのレイヤーの可視性が得られます。

コンテナ作成後:

これについてはすでに上記の答えがたくさんあります。これを行うための私の好ましい方法は-

docker exec -t -i container /bin/bash


ここで、コンテナー内でbashを実行するのは、イメージと同じアーキテクチャーのマシンで実行している場合にのみ機能することに注意してください。PCでラズベリーpiのイメージファイルシステムを覗こうとしている場合、bashトリックは機能しません。
Maxim Kulkin

@MaximKulkin本当に?コンテナーがLinuxの場合、bashが使用可能であれば、ホストが何であるかは関係ありません。おそらくあなたはWindowsコンテナを考えていますか?
するThorbjörnRavnアンデルセン

26

コンテナが実際に起動したときに最も賛成された答えが私のために働いていますが、実行することができず、たとえばコンテナからファイルをコピーしたい場合、これは以前に私を救いました:

docker cp <container-name>:<path/inside/container> <path/on/host/>

docker cp(link)のおかげで、ファイルシステムの他の部分と同じように、コンテナーから直接コピーできます。たとえば、コンテナ内のすべてのファイルを回復します。

mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/

再帰的にコピーすることを指定する必要がないことに注意してください。


6
なぜこれに+1がないのですか?間違いなく最良の方法
ニコラスディピアッツァ2018年

これは、tar経由でエクスポートするよりもさらに簡単です。シンボリックリンク経由でファイルにアクセスするには、-Lを使用する必要がありました。コンテナを実行する必要はありません!
MKaama

17

のUbuntu 14.04で実行ドッカー1.3.1を、私は次のディレクトリにホストマシン上のコンテナのルートファイルシステムが見つかりました:

/var/lib/docker/devicemapper/mnt/<container id>/rootfs/

完全なDockerバージョン情報:

Client version: 1.3.1
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 4e9bbfa
OS/Arch (client): linux/amd64
Server version: 1.3.1
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 4e9bbfa

チャームのように機能します:name = <name> dockerId = $(docker inspect -f {{.Id}} $ name)/ var / lib / docker / devicemapper / mnt / $ dockerId / rootfs /
Florent

3
Ubuntu 16.10とdocker 1.12.1では、これは残念ながらもう当てはまりません(devicemapperディレクトリなし)。ファイルはの下にあり/var/lib/docker/overlay/<a sha256 apparently/<upper or merged>/...ます。そこにあるファイルにアクセスすることの携帯性/安全性がわからない
WoJ

1
1.10から、Dockerは、以前はレイヤーIDとコンテナーIDの両方であったように、ランダムに生成されたUUIDを使用しない新しいコンテンツアドレス可能なストレージモデルを導入しました。新しいモデルでは、これはレイヤーIDの安全なコンテンツハッシュに置き換えられます。したがって、このメソッドは機能しなくなります。
Artem Dolobanko 2017年

これは移植性がなく、ストレージドライバーの選択に大きく依存します。direct-lvmたとえば、ソリューションが機能するかどうかはわかりません。
rustyx 2018年

14

使ってみてください

docker exec -it <container-name> /bin/bash

bashが実装されていない可能性があります。そのために使用できます

docker exec -it <container-name> sh

12

私はaufs / devicemapperにとらわれない別の汚いトリックを使用しています。

コンテナが実行しているコマンドを確認します。たとえばdocker ps 、それがapacheであるかjava、次のようにすればよいですか。

sudo -s
cd /proc/$(pgrep java)/root/

そして、あなたはコンテナの中にいます。

基本的に/proc/<PID>/root/、そのプロセスがコンテナーによって実行されている限り、ルートcdとしてフォルダーに移動できます。シンボリックリンクはそのモードを使用しても意味がないことに注意してください。


このメソッドの詳細については、こちら:superuser.com/a/1288058/195840
Eduardo Lucio

12

コンテナが実際のLinuxシステムではない場合を除いて、最も投票された答えが適切です。

多くのコンテナ(特に、goベースのコンテナ)には、標準のバイナリ(no /bin/bashまたは/bin/sh)がありません。その場合、実際のコンテナーファイルに直接アクセスする必要があります。

魅力のように機能します:

name=<name>
dockerId=$(docker inspect -f {{.Id}} $name)
mountId=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$dockerId/mount-id)
cd /var/lib/docker/aufs/mnt/$mountId

注:ルートとして実行する必要があります。


これはもう機能しません。devicemapperフォルダーがありません。
0xcaff

時代遅れの答えを持つ人々がそれらをクリーンアップするかどうそれはいいだろう
マシュー・パードン

2
新しいdockerストレージ構造と一致するようにコマンドを更新しました。
フロラン

10

私の場合、以外のシェルはコンテナでサポートされていませんでしたsh。だから、これは魅力のように働きました

docker exec -it <container-name> sh


5

これにより、画像のbashセッションが起動します。

docker run --rm -it --entrypoint = / bin / bash


1
これは、デフォルトのエントリポイントが実行されない場合に便利です
構文解析

4

私にとって、これはうまくいきます(ディレクトリ/ var / lib / docker /を指摘するための最後のコメントに感謝します):

chroot /var/lib/docker/containers/2465790aa2c4*/root/

ここで、2465790aa2c4は実行中のコンテナーの短いID (docker psによって表示される)で、その後に星が続きます。


4

Dockerの新しいバージョンではdocker exec [container_name]、コンテナー内でシェルを実行することができます

コンテナー内のすべてのファイルのリストを取得するには、次のコマンドを実行します docker exec [container_name] ls


1
私はこれを試しましたが、うまくいきませんでした。上記のKhalil Gharbaouiの提案は機能しました。
Nick

それでうまくいきました。イメージ名の代わりにコンテナIDで試すこともできます
Diwann

4

docker aufsドライバーの場合:

スクリプトはコンテナのルートディレクトリを見つけます(docker 1.7.1および1.10.3でテスト)

if [ -z "$1" ] ; then
 echo 'docker-find-root $container_id_or_name '
 exit 1
fi
CID=$(docker inspect   --format {{.Id}} $1)
if [ -n "$CID" ] ; then
    if [ -f  /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id ] ; then
        F1=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id)
       d1=/var/lib/docker/aufs/mnt/$F1
    fi
    if [ ! -d "$d1" ] ; then
        d1=/var/lib/docker/aufs/diff/$CID
    fi
    echo $d1
fi

4

既存の回答のいずれも、終了した(そして再起動できない)コンテナのケースに対処していないか、シェルがインストールされていません(たとえば、ディストリビューションのないコンテナ)。これは、Dockerホストへのrootアクセス権があれば機能します。

実際の手動検査では、最初にレイヤーIDを調べます。

docker inspect my-container | jq '.[0].GraphDriver.Data'

出力では、次のようなものが表示されます

"MergedDir": "/var/lib/docker/overlay2/03e8df748fab9526594cfdd0b6cf9f4b5160197e98fe580df0d36f19830308d9/merged"

このフォルダーに(ルートとして)ナビゲートして、コンテナーファイルシステムの現在の表示状態を見つけます。


3

この答えは、コンテナーが実行されていない場合でも、Dockerボリュームファイルシステムを探索する(私のような)人々に役立ちます。

実行中のDockerコンテナを一覧表示します。

docker ps

=>コンテナID "4c721f1985bd"

ローカル物理マシン(https://docs.docker.com/engine/tutorials/dockervolumes/)のDockerボリュームマウントポイントを確認します。

docker inspect -f {{.Mounts}} 4c721f1985bd

=> [{/ tmp / container-garren / tmp true rprivate}]

これにより、ローカルの物理マシンディレクトリ/ tmp / container-garrenが/ tmp dockerボリュームの宛先にマップされていることがわかります。

ローカルの物理マシンディレクトリ(/ tmp / container-garren)を知っているということは、Dockerコンテナーが実行されているかどうかに関係なく、ファイルシステムを探索できることを意味します。これは、コンテナーが実行されていなくても保持されるべきではないいくつかの残余データがあったことを理解するために重要でした。


1
これは、コンテナ内のボリュームとしてマウントされているローカルディレクトリのみを検出しますが、コンテナのファイルシステム全体にアクセスすることはできません。
Bojan Komazec

3

別のトリックは、アトミックツールを使用して次のようなことを行うことです。

mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt

Dockerイメージは、検査するために/ path / to / mntにマウントされます。


しかし、これを機能させるには特別に作られたコンテナが必要ですよね?多分あなたは警告としてそれを追加するべきです、ほとんどの人々はそれを解決策として彼らのチーム/会社に売ることができないでしょう...
Angelos Pikoulas

3

LINUXのみ

私が使用する最も簡単な方法は、Dockerコンテナーファイルを検査するためにコンテナーが実行されている必要があるproc dirを使用することでした。

  1. コンテナーのプロセスID(PID)を見つけて、いくつかの変数に格納します

    PID = $(docker inspect -f '{{.State.Pid}}' your-container-name-here)

  2. コンテナープロセスが実行されていることを確認し、変数名を使用してコンテナーフォルダーに移動します

    cd / proc / $ PID / root

この長いコマンドを使用するだけでPID番号を見つけることなくディレクトリを通過したい場合

cd /proc/$(docker inspect -f '{{.State.Pid}}' your-container-name-here)/root

チップ:

コンテナーの内部に入った後、サービスの停止やポート番号の変更など、コンテナーの実際のプロセスに影響を与えます。

それが役に立てば幸い

注意:

この方法は、コンテナーがまだ実行中の場合にのみ機能します。それ以外の場合、コンテナーが停止または削除されている場合、ディレクトリはもう存在しません。


2

コンテナ内で何が起こっているかを理解するための私の好ましい方法は次のとおりです。

  1. -p 8000を公開

    docker run -it -p 8000:8000 image
    
  2. 内部でサーバーを起動

    python -m SimpleHTTPServer
    

2

すでに実行中のコンテナの場合、次のことができます。

dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name])

cd /var/lib/docker/btrfs/subvolumes/$dockerId

そのディレクトリにcdするには、rootになる必要があります。rootでない場合は、コマンドを実行する前に「sudo su」を試してください。

編集:v1.3に続いて、Jiriの回答を参照してください。


4
シェルを起動する別のsuidプログラムを起動するsuidプログラムを実行する理由はほとんどないため、「sudo su」ではなく「sudo -i」に強く抵抗しています。中間者を切り取ります。:)
dannysauer 2014

あなたの答えはとても良いです、道だけがそうではありません。piercebotのパスを使用する必要があります。
Florent

2

Docker v19.03を使用している場合は、次の手順に従います。

# find ID of your running container:

  docker ps

# create image (snapshot) from container filesystem

  docker commit 12345678904b5 mysnapshot

# explore this filesystem 

  docker run -t -i mysnapshot /bin/sh

1

AUFSストレージドライバーを使用している場合は、私のdocker-layerスクリプトを使用して、コンテナーのファイルシステムルート(mnt)とreadwriteレイヤーを見つけることができます。

# docker-layer musing_wiles
rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
mnt      : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f

2018-03-28を編集:docker
-layerはdocker -backupに置き換えられました


1

docker execコマンドが複数の場合に役立つことができます実行されているコンテナ内のコマンドを実行します。

使用法:docker exec [オプション] CONTAINER COMMAND [ARG ...]

実行中のコンテナでコマンドを実行する

オプション:
  -d、--detachデタッチモード:コマンドをバックグラウンドで実行
      --detach-keys文字列を切り離すためのキーシーケンスを上書きする
                             容器
  -e、--env list環境変数を設定します
  -i、--interactive接続されていなくてもSTDINを開いたままにします
      --privilegedコマンドに拡張特権を与える
  -t、-tty疑似TTYを割り当てる
  -u、--user stringユーザー名またはUID(形式:
                             [:])
  -w、--workdir stringコンテナ内の作業ディレクトリ

例えば ​​:

1)実行中のコンテナファイルシステムにbashでアクセスする:

docker exec -it containerId bash 

2)必要な権限を持つことができるように、rootとして実行中のコンテナファイルシステムにbashでアクセスします。

docker exec -it -u root containerId bash  

これは、コンテナーでrootとしていくつかの処理を実行できるようにする場合に特に便利です。

3)特定の作業ディレクトリを使用して、実行中のコンテナファイルシステムにbashでアクセスします。

docker exec -it -w /var/lib containerId bash 

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.