Raspberry PiのKubernetesにDashboardを入れた話

# これは2019/09/22時点での話です

[前回](https://qiita.com/yyojiro/items/bc8c5ef9a019a9844347)はRaspberry PiにKubernetesを構築したが、せっかくなのでDashboardが欲しいと思ったので入れたというだけの記事。
いろいろ微修正が必要だがなんとかインストール成功。

# 構築手順
## 環境
最終的にうまくいった環境情報を残しておく。

| 要素 | バージョン等 |
|:-:|:-:|
| ハード | Raspberry Pi 3 Model B |
| OS | Raspbian 10 (buster) |
| kubelet | v1.15.3  |
| flannel | v0.11.0-arm |
| metallb | v0.8.1 |
| kubernetes-dashboard | v2.0.0-beta4 |

バージョン大事。世間がkubernetes-dashboardのv1.x.xの情報ばかりで、最初にkubernetes-dashboard v.1.10.1を入れたらうまく動いてくれなくていらん苦労した。
ちゃんと下記のところ見たらv1.10.1はkubernetes v1.13で動かないって書いてあるからv1.15は言わずもがなというところ。
https://github.com/kubernetes/dashboard/releases

NW環境としてはごく普通の自宅無線LAN内で構築してて、下記のようなNW。

| |  |
|:-:|:-:|
| 無線LANルータ | Buffaloの安いやつ（WCR-1166DS） |
| デフォルトGW | 192.168.11.1 |
| Raspberry Pi アクセス用 | 192.168.11.10 ～ 12  |
| MetalLB用 | 192.168.11.200 ～ 240 |

余談だが、Raspberry Pi でkubernetesクラスタを組む場合ほとんどの皆さんは有線LANでNWを組んでいらっしゃるが、無線LANだと配線ごちゃごちゃしないのできれいだし楽ちんですぞ。（パフォーマンスがいいかは別）


## 前提条件
前提条件として、下記の手順で入れたkubernetesが存在すること。
https://qiita.com/yyojiro/items/0cd7ec7e2a39610be53f

## yamlファイルいじり

まずはdashboardのyamlを拾ってくる。

```
root@k8s01:~# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta4/aio/deploy/recommended.yaml
```

このyamlの内容を多少いじる。
具体的には下記3か所。

#### ①ServiceでType:LoadBalancerを追加
世間ではNodePortを使ってexposeする手順が多いが、あれとproxy使う手順の場合URLがクソ長くなるので嫌いだ。MetalLB入れてLoadBlancerにすればらくちんで美しいURLが得られる。
ということで、32~45行目あたりにあるServiceのところ修正。

```
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
  type: LoadBalancer   ## これを追加
```

#### ②imageの変更
Raspberry Piなのでimageのところをarmにしてあげる必要がある。
191行目あたりにある image: kubernetesui/dashboard:v2.0.0-beta4のところを修正。

```
 image: kubernetesui/dashboard:v2.0.0-beta4
　↓
 image: kubernetesui/dashboard-arm:v2.0.0-beta4
```

この時点でデプロイしたら以下のようなエラーがでた。

```
The ClusterRoleBinding "kubernetes-dashboard" is invalid: roleRef: Invalid value: rbac.RoleRef{APIGroup:"rbac.authorization.k8s.io", Kind:"ClusterRole", Name:"kubernetes-dashboard"}: cannot change roleRef
```

#### ③ClusterRoleBindingの修正
kubernetes-dashboardというClusterRoleがないのでClusterRoleBindingに失敗した模様。kubernetes-dashboardというClusterRoleを作るべきだが、めんどくせーからClusterRoleをkubernetes-dashboardからcluster-adminに変更。
155～167行目あたりを修正。

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin  ### kubernetes-dashboardからcluster-adminに変更
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard
```

### デプロイ
普通にkubectl applyする。

```
root@k8s01:~# kubectl apply -f recommended.yaml 
```

うまくデプロイできれば下記のような結果が得られるはず。
※metrics-serverも見えているが、metrics-serverインストールはこちら　https://qiita.com/yyojiro/items/febfaeadabd2fe8eed08

```
root@k8s01:~# kubectl get svc,pod --all-namespaces
NAMESPACE              NAME                                TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                  AGE
default                service/kubernetes                  ClusterIP      10.96.0.1       <none>           443/TCP                  24h
kube-system            service/kube-dns                    ClusterIP      10.96.0.10      <none>           53/UDP,53/TCP,9153/TCP   24h
kube-system            service/metrics-server              ClusterIP      10.108.95.178   <none>           443/TCP                  16h
kubernetes-dashboard   service/dashboard-metrics-scraper   ClusterIP      10.105.98.44    <none>           8000/TCP                 4h35m
kubernetes-dashboard   service/kubernetes-dashboard        LoadBalancer   10.98.187.37    192.168.11.200   443:32301/TCP            4h35m

NAMESPACE              NAME                                             READY   STATUS    RESTARTS   AGE
kube-system            pod/coredns-5644d7b6d9-4kl6n                     1/1     Running   0          117m
kube-system            pod/coredns-5644d7b6d9-lgnmg                     1/1     Running   0          132m
kube-system            pod/etcd-k8s01                                   1/1     Running   7          24h
kube-system            pod/kube-apiserver-k8s01                         1/1     Running   7          24h
kube-system            pod/kube-controller-manager-k8s01                1/1     Running   11         24h
kube-system            pod/kube-flannel-ds-arm-66xs4                    1/1     Running   5          131m
kube-system            pod/kube-flannel-ds-arm-mfjgp                    1/1     Running   4          131m
kube-system            pod/kube-proxy-55s9c                             1/1     Running   7          24h
kube-system            pod/kube-proxy-c9r6d                             1/1     Running   3          23h
kube-system            pod/kube-scheduler-k8s01                         1/1     Running   9          24h
kube-system            pod/metrics-server-754b5ccfc9-bdcxw              1/1     Running   0          119m
kubernetes-dashboard   pod/dashboard-metrics-scraper-566cddb686-8s2pl   1/1     Running   0          118m
kubernetes-dashboard   pod/kubernetes-dashboard-6ffd45c47d-fwnfv        1/1     Running   0          117m
metallb-system         pod/controller-6bcfdfd677-bqqwf                  1/1     Running   0          118m
metallb-system         pod/speaker-b2vwp                                1/1     Running   2          19h
metallb-system         pod/speaker-zrbzc                                1/1     Running   4          20h
root@k8s01:~# 
```

ServiceのところでLoadBalancerのEXTERNAL-IPが192.168.11.200 になっているので、こいつにhttpsでアクセスすればダッシュボードに接続できる。

### サービスアカウント作成
ダッシュボードログイン用サービスアカウントを作る。
まずは下記の内容のyamlファイルを作る。

```yaml:service-account.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
  labels:
    k8s-app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
```

kubectl createする。

```
root@k8s01:~# kubectl create -f service-account.yaml 
```


### ログイン

先ほど作成したadmin-userのトークンを取得する。下記のような呪文で一発でゲットできる。

```
root@k8s01:~# kubectl -n kube-system get secret $(kubectl get serviceaccount -n kube-system admin-user -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode
```

ブラウザからダッシュボード画面にアクセスすると下記のようなログイン画面がでるのでトークントークンを入力して「サインイン」する。

![login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367048/82cca52d-4c77-838d-34d0-a8578e443992.png)


うまくいけば下記のような画面になる。

![k82-dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367048/d6bf5f15-5fd2-f3ea-a4a4-45f5a3f2e2e9.png)


# 残課題
dashboardのSSL証明書更新してやらんとchromeだとブロックされる。
~~SSL証明書の更新手順はまた今度。~~

下記の記事を参考に更新したら証明書更新できた。ありがたや。
https://qiita.com/esaka/items/19dbd4a0014dcbd1c130