Docker for Windows を WSLで使う

Docker for Windowsをインストールする

まずは、Docker for Windowsをインストールします。
インストールが終わったら、画面右下のシステムトレイにあるDockerアイコンから設定画面を開きます。

下記項目にチェックを入れて、TLSなしでデーモンに接続できるようにします。
これにより、ローカルのWSLインスタンスが、Docker for Windows内で実行されているDockerデーモンに接続できるようになります。 デーモンはlocalhostにのみバインドされているため、ネットワーク上の他のマシンは接続できません。

## Dockerのインストール

Docker公式HPに記載のあるとおりDockerをインストールします。

$ sudo apt update
$ sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
   deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io

docker-composeもインストールします。

$ sudo curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

sudoしなくてもdockerコマンドを実行できるようにdockerグループにユーザーを追加します。

$ sudo usermod -aG docker $USER

Docker for Windowsに接続するために以下の設定を.bashrcに追加します。

$ echo export DOCKER_HOST=tcp://localhost:2375 >> ~/.bashrc && source ~/.bashrc 

dockerが動くようになっていることを確認します。

$ docker info
$ docker-compose --version

ボリュームマウントのための設定

WSL上ではドライブは /mnt/d にマウントされるのに対して、Docker for Windowsでは内部で /d にマウントされているため、そのままで空のボリュームをマウントしてしまいます。

この対策として、/etc/wsl.conf に root=/ の設定を追加することで /mnt ではなく / にマウントされるようになります。

$ vi /etc/wsl.conf
[automount]
root = /
options = metadata,umask=22,fmask=11

設定した後、一旦ログアウト/ログインするか、以下のコマンドをコマンドプロンプトで実行してWSLを再起動すると / に各ドライブがマウントされるようになります。

C:\> net stop LxssManager
LxssManager サービスを停止中です.
LxssManager サービスは正常に停止されました。
C:\> net start LxssManager
LxssManager サービスを開始します.
LxssManager サービスは正常に開始されました。 

また、別の方法として、/mnt/d を /d にマウントする方法があります。

$ sudo mkdir /d
$ sudo mount --bind /mnt/d /d

ただし、この方法だと.bashrcに以下のようにコマンドを追加しておく必要があります。

$ echo sudo mount --bind /mnt/c /c >> ~/.bashrc && source ~/.bashrc

$ # パスワードなしでマウント出来るようにしたい場合は以下の設定を追加する
$ sudo visudo
$ username ALL=(root) NOPASSWD: /bin/mount

Kubernetes 1.17にしたら起動しなくなった時

Kubernetesのパッケージを一部ホールド(apt-mark hold)し忘れて1.17にアップグレードしちゃいました。そしたら、Nodeが起動しなくなっちゃいました。

$ kubectl get node
NAME      STATUS     ROLES    AGE   VERSION
testvm1   NotReady   master   46d   v1.17.0

kubectl describeでノードの状態を調べると以下のようなログが出てました。

$ kubectl describe node testvm1
略
 Failed to initialize CSINodeInfo: error updating CSINode annotation:  timed out waiting for the condition; caused by: the server could not  find the requested resource 

調べると、1.17から追加 CSIMigration という機能が原因とのことで、これを無効にする設定を追加します。

CSIMigration: シムと変換ロジックを有効にしてボリューム操作をKubernetesリポジトリー内のプラグインから対応した事前インストール済みのCSIプラグインにルーティングします。

Kubernetesリファレンス https://kubernetes.io/ja/docs/reference/command-line-tools-reference/feature-gates/

$ sudo vi /var/lib/kubelet/config.yaml
featureGates:         ←追加
  CSIMigration: false ←追加

その後、systemctl restart kubelet.service すれば起動しました。kubeadm upgrade node を実行するとconfig.yamlを上書きしちゃうので要注意です。

$ sudo systemctl restart kubelet.service
略
$ kubectl get node
NAME      STATUS     ROLES    AGE   VERSION
testvm1   Ready      master   46d   v1.17.0