Docker コンテナ内から Docker コマンドを使う

Docker コンテナ内のアプリケーションから Docker コンテナの操作をしたかったので、やってみました。

環境

  • Docker 20.10.12

DinD と DooD

Docker コンテナ内から Docker を扱う方法としては以下の2つがあるようです。

  • DinD: Docker in Docker
    • Docker コンテナの中で Docker デーモンを動かす
    • コンテナの中にコンテナを作成したりできる
    • 非推奨
  • DooD: Docker outside of Docker
    • ホストの docker.sock をコンテナにマウントし、Docker デーモンを共有する
    • ホスト上の Docker コンテナを操作できる
    • 基本的にこちらを使う

ここらへん以下のページが分かりやすかったです。

DinD は Docker の開発用途のためのものらしく、セキュリティリスクなどもあることから非推奨で、基本的には DooD のほうを使うべきだそうです。
今回の用途的にも DooD のほうなので、DooD を試してみました。

DooD サンプル

ググってみると以下のようなサンプルが多いです。

$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock docker

確かにこれでコンテナ内で docker コマンドが使えました。
この場合では docker という Docker 一式が入ったイメージを使っているので、/var/run/docker.sock をマウントするだけで使えています。

しかし、実際にはアプリケーションのランタイムイメージをベースとすることが多いと思います。
試しに Ubuntu のイメージを使うと、以下のようにエラーになります。

$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:20.04
# docker ps
bash: docker: command not found

Docker クライアントがインストールされていないからです。

この場合、コンテナ内で docker.io をインストールすれば docker コマンドが使えるようになります。
ついでに docker-compose もインストールしています。

$ sudo apt update
$ sudo apt install -y docker.io docker-compose

というわけで、DooD では

  • /var/run/docker.sock をマウント
  • ベースイメージに Docker クライアントがインストールされていなければインストール

で、コンテナ内から Docker コマンドが使えるようになります。

参考 URL

Hugo で構築されています。
テーマ StackJimmy によって設計されています。