LoginSignup
8
3

More than 1 year has passed since last update.

シェルを含まないコンテナのファイルを確認する

Last updated at Posted at 2021-12-01

はじめに

昨今、セキュリティ強化や軽量化の目的で、シェルを含まない distroless などの最小のベースイメージが使われることが増えてきました。一方、コンテナイメージに含まれるファイルをさっと確認したいと思ったときなど、シェルがなくて困ることがあります。この記事では、Docker 単体でシェルを含まないコンテナのファイルにアクセスする方法を紹介します。

シェル (busybox) をボリュームとしてマウントする (コンテナ起動時)

シェル (busybox) のバイナリをボリュームとしてマウントして利用する方法です。

事前に任意のボリュームを作成し、busybox のバイナリをコピーしておきます。この作業は一度だけで大丈夫です。ボリューム名や busybox のバージョンは適宜変更してください。

docker volume create busybox
docker run --rm -v busybox:/bb/ busybox:1.34.1 sh -c "cp /bin/* /bb/"

この busybox のボリュームをマウントして、シェルなしのコンテナイメージを起動します。コンテナ内のファイルと被らないように、別のディレクトリ (/bb) にマウントして、PATH を通しています。以下の例ではシェルの入っていないイメージ k8s.gcr.io/pause-amd64:3.3 で busybox をのシェルを起動する例です。

docker run --rm -v busybox:/bb/ --entrypoint /bb/sh -e PATH=/bb/ -it \
    k8s.gcr.io/pause-amd64:3.3

起動後は busybox のシェルでコンテナのファイルにアクセスできます。:tada:

/ # ls /
bb     dev    etc    pause  proc   sys

ホストから /proc/$PID/root でアクセスする (コンテナ起動中)

起動中のコンテナの場合は、コンテナプロセスの PID を調べて、/proc/$PID/root からコンテナのファイルシステムにアクセスできます。また、Kubernetes でも、Pod のコンテナ間でプロセス名前空間を共有 (shareProcessNamespace: true)すれば、この方法でサイドカーからシェルの無いコンテナのファイルにアクセスできます。

コンテナプロセスの PID は、docker ps でコンテナ ID を調べた後、以下のように docker inspect で確認できます。

docker inspect -f '{{.State.Pid}}' <CONTAINER_ID>

ここで確認した PID を使って /proc/$PID/root にアクセスすると、コンテナプロセスのルートファイルシステムにアクセスできます。 :tada:

$ sudo ls /proc/8032/root
dev  etc  pause  proc  sys

おわりに

distroless などの最小のベースイメージを使った場合でも、 前述の方法でコンテナのファイルシステムにアクセスが可能です。攻撃対象領域を小さくするためにも、積極的に最小のベースイメージを使っていきましょう。

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3