はじめに
タイトル長い上にわかりにくいんだけど、わかりにくいことをやっているということ。
社内サーバーでrootless dockerを展開しているのですが、VSCodeのdevcontainer機能がrootless dockerだと使えないんだよ、とエンジニアから指摘されました。
この問題を回避すべくdindを使った話です。
構築手順
rootless dockerの構築・設定は終わっている前提です。
docker psやdocker infoでdockerが動作し、rootlessで動いていることを確認します。
dindをセットアップする
リモートサーバーにアクセスして作業します。
ミソはdindコンテナの/var/runをバインドしていることです。
これによってdocker.socketがホスト上にバインドされます。
docker run -it -d --rm --privileged --name dind -v $(pwd)/my-dind:/var/run docker:20-dind
もし、dindコンテナ内でマウントしたいディレクトリがある場合は、この時点でマウントしておいてください。
docker run -it -d --rm --privileged --name dind -v $(pwd)/my-dind:/var/run -v /nfs/my-data:/work docker:20-dind
dindコンテナが動作していることを確認します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1...6 docker:20-dind "dockerd-entrypoint.…" 34 seconds ago Up 33 seconds 2375-2376/tcp dind
my-dindディレクトリが作成されていることを確認します。
$ ls -l my-dind
total 8
drwx------ 6 hoge hoge 4096 Aug 28 16:27 docker
-rw-r--r-- 1 hoge hoge 2 Aug 28 16:27 docker.pid
srw-rw---- 1 hoge hoge 0 Aug 28 16:27 docker.sock
-rw------- 1 hoge hoge 0 Aug 28 16:26 xtables.lock
contextを作成/切替してリモートサーバーがdindのdockerを掴むようにします。
docker context create --docker host=unix://$(pwd)/my-dind/docker.sock my-local-dind
docker context use my-local-dind
dockerデーモンが掴んでいるdockerが切り替わっていることを確認します。
先程はdindコンテナが動いていることが確認できたのですが、dindコンテナ内のdockerデーモンに接続しているため動いているコンテナが見えなくなります。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Macをセットアップする
Docker Desktopをインストールして動作することを確認してください。
公式URLはこちらです。
https://www.docker.com/products/docker-desktop/
リモートサーバーのdockerデーモンに接続するためのcontextを作成/切替します。
docker context create --docker host=ssh://<remote server> my-remote-docker
docker context use my-remote-docker
構築手順は以上です。
あとはVSCodeのContainer拡張機能を開けばdocker関連の機能が使えることがわかります。
devcontainer機能で作成したコンテナが表示されることも確認できます。
dindコンテナにマウントしたディレクトリをdind内のコンテナにマウントさせる場合は、マウントポイントをあわせる必要があることに注意してください。
前述の例では-v /nfs/my-data:/workとマウントしているので、dind内のコンテナからは/workをマウントする必要があります。
docker run -it -v /work:/my-data ubuntu:latest bash
dindを消したい
リモートサーバー上のdindを削除したい場合は、docker context useでコンテキストを戻し、dindコンテナを停止すれば永続化していないデータはすべて消えます。
$ docker context ls
$ docker context use rootless
$ docker stop dind
dindコンテナが作成するソケットファイルを削除するには次のコマンドで削除してください。
$ chmod -R 770 my-dind
$ rm -rf my-dind
最後に
理屈上はrootful dockerをrootless dockerでラップしているので、rootfulに見えるだけで実質はrootlessになっているはずです。
しかし、rootlessであること保証できるわけではないことをご理解ください。
同様に各種機能がrootfulかのように使えるはずですが、rootlessを間に挟む関係でデバイスのマウントやネットワーク経由のアクセスは複雑怪奇となり混乱を極めるおそれがあります。
用途や物理構成を見極め適切なアーキテクチャを選定ください。
私が試した限り、VSCodeに残っている認証キャッシュを使ってGitHubにログインでき、プライベートリポジトリをpullできました。
また、devcontainerも動作することを確認でき、VSCodeを活かせていることを確認できました。
この内容で誰かが幸せになると嬉しいです。