MicroK8sリモートクラスタで快適Kubernetes生活

# 概要
以前までminikubeをkubenetesの検証環境として使用していたのですが...

- NATネットワークのため別端末での検証時にポートフォワードが必要
- 作業用マシンが貧弱なのでPodがずっとPendingのまま
- minikubeアプデの度にどんどん重くなってる気がする

みたいなことが増えてきたので見直すことにしました。

ちょうどUbuntu 20.04がリリースされたタイミングでしたのでsnapで、
サクっとインストール、メンテが出来るmicrok8sを使ってみます。

# 構成

### Before
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56893/91ad9e1d-25fb-d037-73f8-cab130a4b771.png)


### After
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56893/1570cd83-cda9-9b9a-c262-086b3346f44e.png)

- 作業用マシン
  - MBP(2017)
  - Core i5 7360U(2.3GHz 2core)
  - Memory 8GB

- コンピュート用マシン
  - Windows10
  - Core i7 3770(3.4GHz 4core)
  - Memory 16GB

# 作業メモ
## VirtualBoxにUbuntu 20.04をインストール
- OSイメージダウンロード
  - https://jp.ubuntu.com/download
  - Ubuntu Server 20.04を選択
- 仮想マシン作成
  - CPU: 4core
  - Memory: 8GB
  - Storage: 64GB(VDI)
  - Network: Bridge adapter
- OSインストール
  - 言語設定、キーボード設定、ネットワーク設定、ユーザー設定、インストール先指定
  - 追加機能一覧
    - 普通にmicrok8sがあるのでチェックを入れておく
    ![SnapCrab_Ubuntu 2004 [実行中] - Oracle VM VirtualBox_2020-6-22_16-20-50_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56893/417dc164-0127-2236-c7d2-b1e0e23f2469.png)

もうmicrok8sもインストール完了しました...
snapでのパッケージインストールは至れり尽せりを感じて好きです。

再起動後、IPアドレスの固定などを実施。
(参考)
https://qiita.com/zen3/items/757f96cbe522a9ad397d

## microk8sをインストール

```bash
$ snap list
Name      Version   Rev    Tracking         Publisher   Notes
core      16-2.45   9289   latest/stable    canonical✓  core
core18    20200311  1705   latest/stable    canonical✓  base
lxd       4.0.1     14804  latest/stable/…  canonical✓  -
microk8s  v1.18.3   1422   1.18/stable      canonical✓  classic
snapd     2.44.3    7264   latest/stable    canonical✓  snapd
```
既にインストール完了していますが、Kubernetesはv1.15を使いたいのでsnapのchannelを変更します。

### channelを選択してkubernetesのバージョンを指定

``` bash
$ snap info microk8s
name:      microk8s
summary:   Kubernetes for workstations and appliances
  :
  :
  :
channels:
  1.15/stable:      v1.15.11        2020-03-27 (1301) 171MB classic
  1.15/candidate:   v1.15.11        2020-03-27 (1301) 171MB classic
  1.15/beta:        v1.15.11        2020-03-27 (1301) 171MB classic
  1.15/edge:        v1.15.11        2020-03-26 (1301) 171MB classic
```

通常、snapではchannelを切り替えるには`snap refresh`コマンドを使用します。

microk8sでは異なるバージョンに切り替える場合は再インストールを推奨しているため一度`snap remove`してから再度`snap install`します。

(参考)
https://microk8s.io/docs/setting-snap-channel
> Caution: Changing the channel to a different series will almost certainly cause problems, as the configuration from the current version will be retained. If at all possible, it is recommended to re-install MicroK8s rather than refresh to a different channel, as it is not guaranteed to work.

```
$ sudo snap remove microk8s
microk8s removed

$ sudo snap install --channel=1.15/stable --classic microk8s
microk8s (1.15/stable) v1.15.11 from Canonical✓ installed

$ microk8s.status --wait-ready
microk8s is running
```

### アップデートについて
snapでインストールしたパッケージは定期的にアップデートされます。
バージョンを固定したい場合などは`latest`以外のchannelを指定しておく必要があります。

尚、デフォルトだと1日4回バージョンチェックする設定となっています...
ちょっと頻度が高いので1日1回に変更しておきます。

```bash
$ snap refresh --time
timer: 00:00~24:00/4
last: n/a
hold: today at 09:30 UTC
next: today at 07:31 UTC (but held)

$ sudo snap set system refresh.timer=00:00~24:00/1

$ snap refresh --time
timer: 00:00~24:00/1
last: n/a
hold: today at 09:30 UTC
next: today at 08:01 UTC (but held)
```

(参考)
https://snapcraft.io/docs/keeping-snaps-up-to-date

## 作業用マシンのkubectlにリモートクラスタを登録
clusterとcontextとuserを作業用マシンの`~/.kube/config`へ追記します。
(参考)
https://qiita.com/ytyng/items/0d9cbfda8ecb985d5858

```bash
$ microk8s.kubectl config view --raw

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: ...
    server: https://127.0.0.1:16443
  name: microk8s-cluster
contexts:
- context:
    cluster: microk8s-cluster
    user: admin
  name: microk8s
  :
  :
  :
users:
- name: admin
  user:
    password: ...
    username: admin
```

```~/.kube/config
上記の、
- cluster:
- context:
- name: admin
を追記。

clusterはIPを 127.0.0.1 から仮想マシンBridge Networkの固定IPに変更。
```

```bash
$ kubectl config get-contexts
CURRENT   NAME       CLUSTER            AUTHINFO   NAMESPACE
          microk8s   microk8s-cluster   admin
*         minikube   minikube           minikube

$ kubectl config set-context microk8s
```

## 作業用マシンからコンテナimageをpush
microk8sではregistry-built-inプラグインを有効にすることでコンテナイメージをpush出来るようになります。

(参考)
https://microk8s.io/docs/registry-built-in

### microk8sのregistry-built-inを有効にする

```bash
$ microk8s enable registry
```
`32000`ポートにアクセスすればコンテナイメージをpush出来るようなりました。

### 作業マシンでコンテナイメージをPushする

今回は試しにkubernetesのHelloWorldに該当する`k8s.gcr.io/echoserver`をPushしてみます。

```bash
$ docker pull k8s.gcr.io/echoserver:1.4
  :

$ docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
k8s.gcr.io/echoserver             1.4                 a90209bb39e3        4 years ago         140MB

$ docker tag a90209bb39e3 IPADDR:32000/echoserver
  :

$ docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
IPADDR:32000/echoserver           latest              a90209bb39e3        4 years ago         140MB
k8s.gcr.io/echoserver             1.4                 a90209bb39e3        4 years ago         140MB
```

microk8sのコンテナレジストリはhttpで動作しているため作業マシンのdocker deamonの設定を変更してやる必要があります。

```~/.docker/deamon.json
{
  "insecure-registries" : ["IPADDR:32000"]
}
```

設定変更後はMacなのでDocker for Macのアイコンからdocker deamonをrestartしました。

```bash
$ docker push IPADDR:32000/echoserver
The push refers to repository [IPADDR:32000/echoserver]
67639a8a7916: Pushed
1787713d6d5d: Pushed
5f70bf18a086: Pushed
e2615e4925e2: Pushed
4cc84b7b3aba: Pushed
9f9b8efa9a34: Pushed
e105cd217163: Pushed
6cc9890d69b6: Pushed
latest: digest: sha256:6eb2f60a3ca84e3c6c17c9a5a34dbd4f75ff1a1088011d118f5e53626db1ddb7 size: 2602
```

Pushが完了しました。

### Pushしたコンテナイメージの確認(2020/06/22)

microk8s関連コマンドでPushしたイメージの確認や削除が出来れば一番ですが...現在開発中みたいです。
https://discuss.kubernetes.io/t/registry-add-on-possible-to-list-pushed-images/11480/2
https://github.com/ubuntu/microk8s/pull/453

REST経由での取得は可能です。

```bash
curl -X GET http://localhost:32000/v2/_catalog
{"repositories":["echoserver"]}
```

# 動作確認
Pushしたコンテナイメージをデプロイしてみます。

```deploy.yaml
cat deploy.yaml                                                                                                     ⎈ (microk8s/default)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
spec:
  replicas: 1
  selector:
    matchLabels:
      name: echo
  template:
    metadata:
      labels:
        name: echo
    spec:
      containers:
      - name: echo
        image: localhost:32000/echoserver
        ports:
        - containerPort: 8080

---

apiVersion: v1
kind: Service
metadata:
  name: echo
spec:
  type: NodePort
  ports:
  - port: 8080
    protocol: TCP
  selector:
    name: echo
```

NodePortで公開しました。
適当なマシンでcurlを叩いてみます。

```bash
$ curl IPADDR:NodePort
CLIENT VALUES:
client_address=10.1.1.1
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://IPADDR:8080/

SERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001

HEADERS RECEIVED:
accept=*/*
host=IPADDR:31009
user-agent=curl/7.64.1
BODY:
-no body in request-⏎
```

## クリーンアップ

`microk8s.reset`を実行するだけで以下を実施してくれました。

1. コンテナRegistryを全削除
2. kubernetesリソースを全削除
3. kubectlを再起動

尚、pluginも削除されるため再度`microk8s.enable`が必要です。

# 所感
普段ゲーム用に使っている、まだまともなスペックのマシンをちょっと間借りすることにしました。

Docker for WindowsのWSL2 based engineなども検討しましたがあまりWindows環境を汚したくなかったので...

VMで構築したので中断しておけば、ゲームする時に影響もないのでいい感じかなって印象です。