🐳

シェルのないコンテナの中に入る方法

2022/04/25に公開

distrolessやDockerSlimで作成したコンテナイメージにはシェルがなく、docker exec -it <container> shができない。
そういう場合に無理やり入る方法を紹介する。

dockerの場合

ここに書いてある方法でよい。

docker run --rm -it --pid=container:<target container> --net=container:<target container> --cap-add sys_admin prom/busybox:glibc sh

ターゲットのコンテナがmuslベースならalpineでいいが、glibcベースならprom/busyboxがいいと思う。

入ったらpsしてターゲットコンテナのメインプロセスIDを特定し、/proc/<pid>/rootからターゲットコンテナのファイルシステムにアクセスしたり、strings /proc/<pid>/environして環境変数を覗いたりできる。
しかし注意点があり、メインプロセスのユーザがrootでない場合は/proc/<pid>の中を覗くことができない。その場合は--privilegedを利用する。

docker run --rm -it --pid=container:<target container> --net=container:<target container> --privileged prom/busybox:glibc sh

k8sの場合

ここに書いてある方法でよい。原理はdockerの場合と同じ。

spec:
  shareProcessNamespace: true
  containers:
  - name: nginx
    image: nginx
  - name: sidecar
    image: prom/busybox:glibc
    securityContext:
      capabilities:
        add:
        - SYS_PTRACE
    stdin: true
    tty: true

shareProcessNamespace: true--pid=container:<target container>に相当する。
Pod内ではネットワークはもともと共有されている。

例によって、メインプロセスのユーザがrootでない場合は/proc/<pid>の中を覗くことができない。--privileged相当は以下の通り。

    securityContext:
      privileged: true

これができるかどうかはk8sの設定次第。

Discussion