Kubernetes Dashboard のインストールとアクセス用Servericeの作成


## はじめに

Kubernetes Dashboardへのアクセスは、[kubectl proxy](https://github.com/kubernetes/dashboard/blob/master/docs/user/accessing-dashboard/README.md#kubectl-proxy)や[kubectl port-forward](https://github.com/kubernetes/dashboard/blob/master/docs/user/accessing-dashboard/README.md#kubectl-port-forward)を使用する方法がありますが、どちらもKubectlコマンドを実行するのが面倒です。
そこでService経由でアクセスできるようにしました。

## 環境

[RaspberryPi 4 にUbuntu20.04 をインストールして、Kubernetes を構築してコンテナを動かす](https://qiita.com/yasthon/items/c29d0b9ce34d66eab3ec) のkubernetes環境に作成しています。Metallbがインストールされて、IP Poolが作成されていることが前提です。

- Raspberry Pi 4B
- Ubuntu 20.04.1 LTS 64bit
- Kubernetes v1.19.3
- Docker 19.03.13
- metallb controller v0.9.4
- Dashboard v2.0.4

## Dashboard v2のインストール

Dashboard v2 からは、namespaceが「kube-system」から「kubernetes-dashboard」に
変わっているので要注意です。

また、localhost以外のDashboardはhttpsでの接続になります。
[dashboard/README.md at master · kubernetes/dashboard - Login not available](https://github.com/kubernetes/dashboard/blob/master/docs/user/accessing-dashboard/README.md#login-not-available)

[GitHub - kubernetes/dashboard: General-purpose web UI for Kubernetes clusters](https://github.com/kubernetes/dashboard)を参照しつつ、Dashboardをインストールします。

```bash
$ curl https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml -o dashboard.yaml
$ kubectl apply -f dashboard.yaml
namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
$ kubectl get pod -n kubernetes-dashboard    # 確認する
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-7b59f7d4df-bfgg7   1/1     Running   0          2m48s
kubernetes-dashboard-665f4c5ff-r8fcq         1/1     Running   0          2m48s
```

## Dashboard用アカウントの作成

[dashboard/creating-sample-user.md at master · kubernetes/dashboard · GitHub](https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md)を参照して、ServiceAccountとClusterRoleBindingを作成します。


```bash
$ vi dashboard-adminuser.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
$ kubectl apply -f dashboard-adminuser.yaml
serviceaccount/admin-user created
clusterrolebinding.rbac.authorization.k8s.io/admin-user created
$ kubectl get serviceaccount/admin-user -n kubernetes-dashboard    # 確認する
NAME         SECRETS   AGE
admin-user   1         14s
$ kubectl get clusterrolebinding.rbac.authorization.k8s.io/admin-user -n kubernetes-dashboard    # 確認する
NAME         ROLE                        AGE
admin-user   ClusterRole/cluster-admin   29s
```

## Service(LoadBalancer)の作成

Metallbがインストールされて、IP Poolが作成されていることが前提です。
Serviceの外部接続用IPアドレスをIP Poolから取得するためです。
※ここでは、192.168.100.211～215がIP Poolに設定されています。
Metallbのインストール・設定については、[LoadBalancer のインストール](https://qiita.com/yasthon/items/c29d0b9ce34d66eab3ec#loadbalancer-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB-master-node%E3%81%A7%E5%AE%9F%E8%A1%8C)を参照してください。

```bash
$ vi dashboard_svc.yml
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: dashboard-service-lb # service(loadbalanser) の名前
  namespace: kubernetes-dashboard # namespace の名前
spec:
  type: LoadBalancer # minikube では未サポート
  ports:
    - name: dashboard-service-lb
      protocol: TCP
      port: 443 # serviceのIPでlistenするポート
      nodePort: 30085 # nodeのIPでlistenするポート（30000-32767）
      targetPort: 8443 # 転送先でlistenしているPort番号のポート
  selector: # service のselctorは、matchLabels になる
    k8s-app: kubernetes-dashboard # 転送先の pod のラベル
$ kubectl apply -f dashboard_svc.yml
service/dashboard-service-lb created
$ kubectl get svc -n kubernetes-dashboard    # 確認する
NAME                        TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP      10.102.76.63     <none>            8000/TCP        6m10s
dashboard-service-lb        LoadBalancer   10.106.221.180   192.168.100.212   443:30085/TCP   11s
kubernetes-dashboard        ClusterIP      10.98.194.70     <none>            443/TCP         6m11s
```

```dashboard-service-lb``` が作成したServiceです。
EXTERNAL-IP(192.168.100.212)がブラウザで接続するIPアドレスです。
接続ポートは、```dashboard_svc.yml```のportの値(443)になります。

## Tokenの取得

Dashboardにログインする時に使用します。

```bash
$ kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
Name:         admin-user-token-r8rvx
Namespace:    kubernetes-dashboard
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: admin-user
              kubernetes.io/service-account.uid: ab2cbd16-4230-45be-8c80-415b529c3014

Type:  kubernetes.io/service-account-token

Data
====
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6ImczaFFpeTNzbVBIVzlad0EwUnJPdUFHOEY3THJvTzE3NVpIT2xfRFl2QVkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLXI4cnZ4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJhYjJjYmQxNi00MjMwLTQ1YmUtOGM4MC00MTViNTI5YzMwMTQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.bSNGtb5xrUS_g-HEKdCakKd9WZqSi3D2YWkrLwgRvEWfFE6J6vkmPazPdwU28lPe4gL8q1xuNLshhBC9ENgPzzSqWnzGacnndCiA3AzhhAQ3XcHFXlw50S5vo3neACsbX3m5NfaSkUAHac8CXcVdnYkqghf3CqNW2dQPnhbvGAkGt9RpYC1wOyOkT8O7NgUCuLnPgGTi5bkCeu-Xann6UpLhHMSaN5reiXXeOhXNmqOQ0dfThtEiEUcJvWewCr4MuGuOe4-gnEulZjECkldzpWrjRwPhWafjPnrtP0DV4TMQEp4Ff2ZgVTz-ZNWmm1OA55B-eDB49ewLJzrFGCAcMg
ca.crt:     1066 bytes
namespace:  20 bytes
```

tokenを記録しておきます。

## 接続

ブラウザから、```https://EXTERNAL-IP:PORT/```へアクセスします。
(この記事の例だと、```https://192.168.100.212/```)

「Tocke」をチェックして、「トークンを入力」にTokenを入力して、「サインイン」をクリックします。
![Dashboard login](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236088/27dace6f-0d29-5ba7-7ba9-40b540c43189.png)

Dashboardにログインできました。
![dashboard2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236088/242a85f2-0a7d-6072-0783-5289b6da0011.png)

## token-ttl について

Kubernetes Dashboardのarguments に```token-ttl```というものがあります。
デフォルト900なので、Tokenの有効期限が15分だと思っていました。
実際は、セッションタイムアウト時間です。最後の操作から15分経つとログイン画面に戻ります。

なお、Tokenは翌日になっても使えました。無期限?

```token-ttl``` の情報元は、下記のURLです。
[dashboard/dashboard-arguments.md at master · kubernetes/dashboard · GitHub](https://github.com/kubernetes/dashboard/blob/master/docs/common/dashboard-arguments.md)

## 最後に

kubectl proxyやkubectl port-forwardを使わないで、Dashboardにログインできるようになりました。
Tokenの取得のためにコマンド叩く必要がありますけど・・・。

コマンドに疲れた時、ポチポチしてます。