はじめに
タイトル長い上にわかりにくいんだけど、わかりにくいことをやっているということ。
社内サーバーで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を活かせていることを確認できました。
この内容で誰かが幸せになると嬉しいです。