minikube で docker を動かす場合の注意点

## はじめに

以前の記事で Docker Desktop をやめて minikube を使うようにしました

https://qiita.com/RyoWakabayashi/items/e243be18b2db6b11400d

その際、いくつか引っ掛かった罠があったので残しておきます

## minikube の起動

当然、 docker コマンドを使う前に minikube を起動しておく必要があります

具体的には以下の３つのコマンドを実行します

```sh
$ minikube start
😄  Darwin 11.6 上の minikube v1.23.2
✨  プロフィールを元に、 hyperkit ドライバを使用します
👍  コントロールプレーンのノード minikube を minikube 上で起動しています
🔄  既存の hyperkit VM を "minikube" のために再起動しています...
🐳  Docker 20.10.8 で Kubernetes v1.22.2 を準備しています...
🔎  Kubernetes コンポーネントを検証しています...
    ▪ イメージ gcr.io/k8s-minikube/storage-provisioner:v5 を使用しています
🌟  有効なアドオン: storage-provisioner, default-storageclass
🏄  完了しました！ kubectl が「"minikube"」クラスタと「"default"」ネームスペースを使用するよう構成されました
```

```
$ minikube pause
⏸️  Pausing node minikube ...
⏯️  次のnamespaceに存在する 14 個のコンテナを停止しました: kube-system, kubernetes-dashboard, storage-gluster, istio-operator
```

```
$ eval $(minikube docker-env)
```

ちなみに、 minikube を起動していないまま docker を実行すると、以下のようなエラーになります

```sh
$ docker run hello-world
docker: Cannot connect to the Docker daemon at tcp://xxx.xxx.xxx.xxx:xxx. Is the docker daemon running?.
See 'docker run --help'.
```

[SAM](https://aws.amazon.com/jp/serverless/sam/) などの内部的に docker を使っているツールを使う際にも要注意です

minikube を起動せずに sam build を実行すると、以下のようなエラーが発生します

```sh
Starting Build inside a container
Building codeuri: functions/accounts/ runtime: python3.8 metadata: {} functions: ['XXXFunction']

Build Failed
Error: Docker is unreachable. Docker needs to be running to build inside a container.
```

## ローカルディレクトリーのマウント

こちらも先日の記事ですが、 Lambda 関数を SAM で管理していました

https://qiita.com/RyoWakabayashi/items/e1ef6cddd7f08f6e131b

minikube への乗り換え後、 Lambda 関数を変更して SAM を動かしたところ、
なぜかエラーが発生してしまいました

SAM のビルドディレクトリーを見ると、各関数のディレクトリーが空っぽになっています

エラー原因は SAM が内部で docker を動かした際、ローカルディレクトリーをマウントできていないことでした

以下のブログを参考に、 minikube 経由でローカルディレクトリーをマウントしました

https://blog.1q77.com/2021/09/replace-docker-desktop-with-minikube/

`minikube mount` でホームディレクトリー配下をマウントしておきます

minikube でのマウント済状態であれば、 docker からのマウントも可能になります

```sh
$ minikube mount $HOME:$HOME
📁  Mounting host path /Users/oec into VM as /Users/oec ...
    ▪ マウントタイプ:
    ▪ ユーザー ID:      docker
    ▪ グループ ID:     docker
    ▪ バージョン:      9p2000.L
    ▪ メッセージのサイズ: 262144
    ▪ Permissions:  755 (-rwxr-xr-x)
    ▪ Options:      map[]
    ▪ アドレスをバインドします: xx.xx.xx.xx:xxx
🚀  Userspace file server: ufs starting
✅  Successfully mounted /Users/oec to /Users/oec

📌  NOTE: This process must stay alive for the mount to be accessible ...
```

このプロセスは生きたままにしておく必要があるので、
別途新しくターミナルを開いて SAM を実行すると正常にデプロイできました

SAM のようにローカルディレクトリーを参照する仕組みのものを使う場合、
あらかじめ `minikube mount $HOME:$HOME` を実行しておきましょう

## localhost　の変更

AI　に学習させる画像にアノテーションをしようと [CVAT](https://github.com/openvinotoolkit/cvat) をローカルで動かしてみたら、
CVAT の GUI が動くはずの http://localhost:8080 が Not Found になりました

CVAT はローカルでの起動時、 `docker-compose` を使用します

minikube で docker を動かす場合、 localhost ではアクセスできず、
minikube の IP を指定する必要がありました

前回の記事で hosts に以下のようにして登録しています

```sh
echo "`minikube ip` docker.local" | sudo tee -a /etc/hosts > /dev/null
```

なので、 http://localhost:8080 ではなく、 http://docker.local:8080 でアクセスする必要があります

また、 CVAT の `docker-compose.yml` 内に、以下のように `localhost` の記載箇所があります

```yml
      - traefik.http.routers.cvat.rule=Host(`${CVAT_HOST:-localhost}`) &&
          PathPrefix(`/api/`, `/git/`, `/opencv/`, `/analytics/`, `/static/`, `/admin`, `/documentation/`, `/django-rq`)
```

このようにコンテナ定義等で `localhost` を使っている場合も `docker.local` に変更してから動かします

非常に面倒ですが、 minikube を使う以上は `localhost` -> `docker.local` の置換が必要です

## おわりに

案外あっさり minikube に乗り換えられたと思ったのですが、まだまだ罠がありそうです

マウントは常にしておきたいので、 macOS の起動時に以下の4つを実行するようにしておけば良さそうですね

```sh
minikube start
minikube pause
minikube mount $HOME:$HOME
```

また、 docker を使うターミナルでは以下を先に実行しておきます

```sh
eval $(minikube docker-env)
```

localhost の問題は厄介なので、何か画期的で楽な解決方法がないものか、、、