私はdockerに気付いたのですが、コンテナの中で何が起こっているのか、あるいはそこにどんなファイルがあるのかを理解する必要があります。 1つの例はdockerインデックスから画像をダウンロードすることです - あなたは画像が何を含んでいるかについての手がかりを持っていないので、アプリケーションを起動することは不可能です。
理想的なのはそれらにsshまたは同等のものにsshできることです。これを行うためのツールはありますか、それとも私がこれを行うことができるはずだと考える上で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
を使用してください。 http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/ を参照してください。
ショートバージョンは:nsenterを使えば、既存のコンテナにシェルを入れることができます。たとえそのコンテナがSSHや特殊な目的のデーモンを実行していなくても
更新 - 方法4:docker exec
Dockerバージョン1.3(最新、2014年11月の時点で最新バージョンをインストールするにはdocker apt repoを使用する必要があるかもしれません)は、exec
と同様に動作する新しいコマンドnsenter
をサポートします。このコマンドはすでに実行中のコンテナで新しいプロセスを実行できます(コンテナはすでに実行中のPID 1プロセスを持っている必要があります)。 /bin/bash
を実行してコンテナの状態を調べることができます。
docker exec -t -i mycontainer /bin/bash
アップデート:探検!
このコマンドにより、 実行中の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コンテナまたはimageを調べることができます :
docker inspect name-of-container-or-image
これを実行して、そこにbash
またはsh
があるかどうかを調べたい場合があります。 jsonの戻りでentrypointまたはcmdを探してください。
コンテナのファイルシステムをtarファイルにアーカイブすることができます。
docker export adoring_kowalevski > contents.tar
この方法は、コンテナが停止していて、/bin/bash
のようなシェルプログラムがない場合でも機能します。 Dockerドキュメンテーション からのhello-worldのような画像を意味します。
コンテナのファイルシステムは、dockerのデータフォルダ、通常は/ var/lib/dockerにあります。実行中のコンテナファイルシステムを起動して検査するには、次の手順に従います。
hash=$(docker run busybox)
cd /var/lib/docker/aufs/mnt/$hash
そして今、現在の作業ディレクトリはコンテナのルートです。
コンテナ作成前:
コンテナーの中にマウントされているイメージの構造を調べるためにあなたがすることができます
Sudo docker image save image_name > image.tar
tar -xvf image.tar
これにより、画像のすべてのレイヤーとjsonファイルに存在するその構成の可視性がわかります。
コンテナ作成後:
このためにすでに上の答えがたくさんあります。これを行うための私の好ましい方法は -
docker exec -t -i container /bin/bash
Ubuntu 14.04 running Docker 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
最も支持された答えは、コンテナが実際に起動されたときに私には有効ですが、実行することが不可能で、たとえばコンテナからファイルをコピーしたいときなどです。
docker cp <container-name>:<path/inside/container> <path/on/Host/>
Docker cp( link )のおかげで、ファイルシステムの他の部分と同じようにコンテナから直接コピーできます。たとえば、コンテナ内のすべてのファイルをリカバリするとします。
mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/
再帰的にコピーすることを指定する必要はないことに注意してください。
あなたのコンテナが実際のLinuxシステムではない場合を除いて、最も投票された答えは良いです。
多くのコンテナ(特にgoベースのコンテナ)には標準のバイナリがありません(/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
注:rootとして実行する必要があります。
私はaufs/devicemapperにとらわれないもう一つの汚いトリックを使います。
コンテナが実行しているコマンドを見てください。 docker ps
そしてそれがApacheかJava
であれば、私はただ以下をするだけです:
Sudo -s
cd /proc/$(pgrep Java)/root/
あなたはコンテナの中にいます。
基本的には、そのプロセスがコンテナによって実行されている限り、rootとして/proc/<PID>/root/
フォルダに移動できます。シンボリックリンクは、このモードでは意味がありません。
使ってみる
docker exec -it <container-name> /bin/bash
Bashが実装されていない可能性があります。そのためにあなたが使用することができます
docker exec -it <container-name> sh
私にとっては、これはうまくいきます(ディレクトリ /var/lib/docker/ を指摘するための最後のコメントのおかげで):
chroot /var/lib/docker/containers/2465790aa2c4*/root/
ここで、 2465790aa2c4 は実行中のコンテナーの短いID( docker ps で表示される)で、その後に星が付きます。
私の場合、sh
以外のシェルはコンテナでサポートされていません。だから、これは魅力のように働いた
docker exec -it <container-name> sh
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
新しいバージョンのDockerでは、コンテナ内でシェルを実行するdocker exec [container_name]
を実行できます。
コンテナ内のすべてのファイルのリストを取得するには、docker exec [container_name] ls
を実行します。
もう1つのトリックは、 atomic ツールを使用して次のようなことをすることです。
mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt
あなたがそれを調べるためにDockerイメージは /path/to/mnt にマウントされます。
すでに実行中のコンテナの場合は、次のことができます。
dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name])
cd /var/lib/docker/btrfs/subvolumes/$dockerId
そのディレクトリに移動するには、rootになる必要があります。 rootでない場合は、コマンドを実行する前に 'Sudo su'を試してください。
編集:v1.3に続いて、Jiriの答えを見てください - それはより良いです。
この答えは、コンテナーが実行されていなくてもdocker volumeファイルシステムを探索したい(私自身のような)人々を助けます。
実行中のdockerコンテナを一覧表示する:
docker ps
=>コンテナID "4c721f1985bd"
ローカルの物理マシンのdockerボリュームマウントポイントを見てください( https://docs.docker.com/engine/tutorials/dockervolumes/ )。
docker inspect -f {{.Mounts}} 4c721f1985bd
=> [{/ tmp/container-garren/tmp true rprivate}]
これは、ローカル物理マシンディレクトリ/ tmp/container-garrenが/ tmp dockerボリュームの宛先にマップされていることを示しています。
ローカルの物理マシンディレクトリ(/ tmp/container-garren)を知っているということは、dockerコンテナが実行されているかどうかにかかわらず、ファイルシステムを調べることができるということです。これは、コンテナーが稼働していなくても保持されるべきではない、いくつかの残存データがあることを私が理解するのを助けるために重要でした。
コンテナの内部で何が起こっているのかを理解するための私の好ましい方法は次のとおりです。
-p 8000を公開する
docker run -it -p 8000:8000 image
その中のサーバーを起動します
python -m SimpleHTTPServer
これでコンテナ内でbashを実行することができます:$ docker run -it ubuntu /bin/bash
実行中のコンテナーでコマンドを実行するdocker exec
コマンドは、複数の場合に役立ちます。
用法:docker exec [オプション] CONTAINER COMMAND [ARG ...] 実行中のコンテナでコマンドを実行します [.____オプション: -d、--detach分離モード:バックグラウンドでコマンドを実行 --detach-keys文字列 コンテナを分離するためのキーシーケンスを上書きします。 .e -e、--env list環境変数を設定します。[-i]、--interactiveアタッチされていなくてもSTDINを開いたままにします。 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
AUFSストレージドライバを使用している場合は、my docker-layer scriptを使用して、コンテナのファイルシステムのルート(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 に置き換えられました。
これで画像のbashセッションが始まります。
docker run --rm -it --entrypoint =/bin/bash
LINUXのみ
私が使う最も簡単な方法はproc dirを使うことでした。これはdockerコンテナファイルを調べるためにコンテナが走っていなければならないということです。
コンテナのプロセスID(PID)を見つけて、何らかの変数に格納します。
PID = $(docker inspect -f '{{.State.Pid}}'あなたのコンテナ名はこちら)
コンテナプロセスが実行されていることを確認し、変数nameを使用してコンテナフォルダに入ります。
cd/proc/$ PID/root
この長いコマンドを使用するだけでPID番号を調べずにdirを通過したい場合
cd /proc/$(docker inspect -f '{{.State.Pid}}' your-container-name-here)/root
それが役に立てば幸い
**注:このメソッドはコンテナがまだ実行中の場合にのみ機能します。それ以外の場合、コンテナが停止または削除されるとディレクトリはもう存在しません。