MicroK8sとSkaffoldで開発環境を構築した際のメモ（Mac）

# 概要

MicroK8sが [native対応した](https://www.publickey1.jp/blog/20/canonicalkubernetesmicrok8swindowsmac.html) というニュースを見て、Mac上でMicroK8sにより構築したクラスタとSkaffoldを使って開発をしてみようと思ったところ、ドキュメントに（直接的には）書かれていない部分などで微妙に困ったところがあったので対処方法などを記録したメモです。

- Dockerイメージのビルド等には Docker for Mac を利用しています
- 主に MicroK8s の話で Skaffold に特有の話はあまりありません

# クラスタを構築する

基本的には https://microk8s.io/ に記載のインストール手順どおりに進めればOKです。
1点だけ、ドキュメントには特に記載されていませんがインストール時に `multipass` が必要だと言われます。

```
❯ microk8s install
Support for 'multipass' needs to be set up. Would you like to do that it now? [y/N]:
You need 'multipass' set-up to build snaps: https://multipass.run.
```

背後でmultipassを利用しているらしく、ここでインストールを拒否すると進まないので `y` を入力する必要があります。

# 標準のkubectlを利用する

インストール手順などでは `microk8s kubectl get nodes` のように microk8s のサブコマンドとして kubectl を利用する方式が記載されています。このままでは色々と問題があるため、標準の kubectl 経由でも操作できるようにします。

基本的な手順は https://microk8s.io/docs/working-with-kubectl#heading--kubectl-macos に記載されているとおりです。
ドキュメントに記載された `microk8s config` を実行すると、下記のような出力がされます。

```
❯ microk8s config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBVENDQWVtZ0F3SUJBZ... （長いので省略）
    server: https://192.168.64.2:16443
  name: microk8s-cluster
contexts:
- context:
    cluster: microk8s-cluster
    user: admin
  name: microk8s
current-context: microk8s
kind: Config
preferences: {}
users:
- name: admin
  user:
    token: T1Y2Y21mNSsyK21KbWxGNVZsNm5WSzMzcUtWNWp6ZXlvUTd0djN5RG1Ubz0K
```

これを `~/.kube/config` に記載すれば良いのですが、既存の設定がある場合は単純に上書きすることができません。

ドキュメントでは、既存設定がある場合は **最初の2行** を削除してから追加しろと書かれていますが、これを真に受けてそのまま追記しても正常に動かない状態となります。

`~/.kube/config` は概ね下記のような構造になっています（インデントは後付け）

```
apiVersion: v1
clusters:
  - cluster: ...
  - ...
contexts:
  - context: ...
  - ...
current-context: docker-desktop
kind: Config
preferences: {}
users:
  - name: ...
```

これを見ると `clusters` `contexts` `users` という3つの配列があることが分かります…ということで `microk8s config` の出力についても、既存の構造に合うように3箇所に分けて追記する必要があります。
（あと `current-context` の行は既にあるはずなので上書きする必要があります）

先ほどの出力例を貼り付けると下記のようなイメージになります。
（空白行は説明用に追加したものなので実際は不要です）

```
apiVersion: v1
clusters:
- cluster:
  ...
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBVENDQWVtZ0F3SUJBZ... （長いので省略）
    server: https://192.168.64.2:16443
  name: microk8s-cluster

contexts:
- context:
  ...
- context:
    cluster: microk8s-cluster
    user: admin
  name: microk8s

current-context: microk8s

kind: Config
preferences: {}
users:
- name:
  ...

- name: admin
  user:
    token: T1Y2Y21mNSsyK21KbWxGNVZsNm5WSzMzcUtWNWp6ZXlvUTd0djN5RG1Ubz0K
```

これで kubectx でのクラスタ切り替えや kubectl での操作が普通にできるようになります。

```
❯ kubectx microk8s
Switched to context "microk8s".
```

```
❯ kubectl get pod -n kube-system
NAME                                    READY   STATUS    RESTARTS   AGE
hostpath-provisioner-75fdc8fccd-7m2r2   1/1     Running   0          76m
metrics-server-c65c9d66-s7zkw           1/1     Running   0          77m
```

# SkaffoldでMicroK8s上のRegistryを利用する
## 問題点

MicroK8s上のRegistryを利用する方法は https://microk8s.io/docs/registry-built-in に記載されています。
まずは下記のコマンドで Registry を有効にしてみます。

```
❯ microk8s enable registry
The registry will be created with the default size of 20Gi.
You can use the "size" argument while enabling the registry, eg microk8s.enable registry:size=30Gi
Addon storage is already enabled.
Applying registry manifest
namespace/container-registry created
persistentvolumeclaim/registry-claim created
deployment.apps/registry created
service/registry created
The registry is enabled
```

ここで問題になるのが、有効にしたRegistryは `localhost:32000` でアクセスできると書かれているのですが、実際にはアクセスできない 点です。

RegistryではNodePortを利用しているらしく、恐らくLinux上では自身がKubernetesのNodeになっているので正しい説明なのだと思いますが、Macの場合は別の仮想マシンが動いているため、その仮想マシンのアドレスを利用する必要があります。

もう一つの問題として、MicroK8sのRegistryはHTTPにしか対応していないため、RegistryへのアクセスにHTTPSを使わないようにする設定を行う必要があります。

skaffoldにはこの設定を行うために下記のような [Config](https://skaffold.dev/docs/environment/image-registries/) が用意されていますが、残念ながら（Dockerビルドを利用している場合には）動かないようです。

```
skaffold config set insecure-registries 192.168.64.2:32000
```

いくつか関連のissueはあるのですが、いずれも未解決のままです。

- https://github.com/GoogleContainerTools/skaffold/issues/3890
- https://github.com/GoogleContainerTools/skaffold/issues/3951
- https://github.com/GoogleContainerTools/skaffold/issues/4310

Regression? という文字も見えたのでソースコードを調べてみたのですが、`insecure-registries` を参照するのは **Dockerビルド以外** の場合のみのようです。理由などは分からないのですが、historyを見ても昔からこの構造のため、現状はそういうもののようです。
https://github.com/GoogleContainerTools/skaffold/blob/fa2189e2405afcf7b2dba29fe62c5969a54f6cc6/pkg/skaffold/build/local/local.go#L87-L105

というわけでこの点についても別の方法が必要となります。

## 対応方法

基本的には [Working with a private registry](https://microk8s.io/docs/registry-private) の方の手順を行えばOKです。

まずは MicroK8s の Node のIPアドレスを確認します。

```
❯ multipass list
Name                    State             IPv4             Image
microk8s-vm             Running           192.168.64.2     Ubuntu 18.04 LTS
```

今回の場合は `192.168.64.2:32000` が Registry のアドレスとなります。

次に Docker Daemon の設定で `"insecure-registries": [192.168.64.2:32000"]` を追記して、該当RegistryへのアクセスにHTTPを利用するように指定します。
（ `~/.docker/config` の方にも同様の設定が記載できますが、Skaffold はデフォルトではAPI経由で操作を行うため Daemon 設定の方に書かないとダメなようです。`useDockerCLI` を有効にしている場合は該当する気がしますが未確認です）

<img width="1035" alt="Screen Shot 2020-06-25 at 23.58.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740/69aaaa70-6682-7dbe-c718-745a4d3734aa.png">

Skaffold が MicroK8s の Registry を利用するように `192.168.64.2:32000` を default-repo に設定します。

```
❯ skaffold config set default-repo 192.168.64.2:32000
```

この状態で試しに Skaffold でコンテナを起動してみると、下記のようにイメージの pull が出来ずにエラーとなってしまいます。

```
❯ skaffold dev
...
 - deployment/helloworld: waiting for rollout to finish: 0 of 1 updated replicas are available...
    - pod/helloworld-676fd78ccc-89vbx: container helloworld is waiting to start: 192.168.64.2:32000/helloworld can't be pulled
```

これを解消するため `plugins.cri.registry.mirrors` の設定を追加します。
追加先は Node 上のファイルとなるため、multipass を利用して Node にログインした後に vim 等で編集を行います。 

```
❯ multipass shell microk8s-vm
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-106-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri Jun 26 00:45:42 JST 2020

  System load:  1.41              Processes:             130
  Usage of /:   8.2% of 48.29GB   Users logged in:       0
  Memory usage: 26%               IP address for enp0s2: 192.168.64.2
  Swap usage:   0%                IP address for cni0:   10.1.84.1


0 packages can be updated.
0 updates are security updates.


Last login: Fri Jun 26 00:45:33 2020 from 192.168.64.1
ubuntu@microk8s-vm:~$ sudo vim /var/snap/microk8s/current/args/containerd-template.toml
```

末尾に下記を追記します。

```
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.64.2:32000"]
        endpoint = ["http://192.168.64.2:32000"]
```

設定追加後に microk8s を stop & start すれば設定完了です。
（start する時は先に multipass でノードを起動しないとダメなようです）

```
❯ microk8s stop
Stopped.

❯ multipass start microk8s-vm
❯ microk8s start
Started.
```