kubernetes-dashboardを利用する

# この記事の内容
OpenShiftにはWebコンソールがあり、リソースを目視確認できる点がとても便利です。k8sにもWeb UI（kubernetes-dashboard）がありますので、これを使えるようにし、リソースを目視確認できるようにします。

# 環境
この記事で作った環境を使います。

https://qiita.com/nonbiri-yama/items/18e57145db45d47d9fac

- AlmaLinux 9.5の3VMで、Masterノードx1、Workerノードx2でk8sクラスタを構成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468232/b1f7b612-67fe-2d62-57cc-12be8ad8d21b.png)

- 加えて、MetalLBをインストールしているため、Serviceリソースをtype: Loadbalancerにすると、IPアドレスプールに設定したIPアドレスが払い出されて、k8sクラスタ外からアクセスできるようになります。MetalLBの設定は以下にて実施。

https://qiita.com/nonbiri-yama/items/dd163945b8986efe1f9f

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468232/971b3e90-3b6a-f2bc-eb36-2ce7a90ec273.png)


# 1. helmコマンドのインストール

kubernetes-dashboardは、以前（v2.0とか）はマニフェストファイルでインストールできましたが、現在（2025/2の最新はv7.10）は、Helmでインストールする方法が唯一の方法である、と説明があります。

https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/

ということで、まずは、Masterノードで、helmコマンドを使えるようにします。Helmのインストール方法は、以下にあります。

https://helm.sh/docs/intro/install/

### (1) Helmのインストールファイルの入手

get_helm.sh のファイルを入手します。
```
mkdir ~/helm/
cd ~/helm/
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
```

### (2) Helmのインストール

実行権限をつけて、get_helm.shを実行します。
```
chmod 700 ./get_helm.sh
./get_helm.sh
```

実行例です。
gitが見つからない、と言ってますが、とりあえずスルーで。
```
[root@master1 helm]# ./get_helm.sh
[WARNING] Could not find git. It is required for plugin installation.
Downloading https://get.helm.sh/helm-v3.17.0-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
[root@master1 helm]#
```

これで、Masterノードで、helmコマンドが使えるようになりました。
```
[root@master1 helm]# helm version
version.BuildInfo{Version:"v3.17.0", GitCommit:"301108edc7ac2a8ba79e4ebf5701b0b6ce6a31e4", GitTreeState:"clean", GoVersion:"go1.23.4"}
[root@master1 helm]#
```


# 2. kubernetes-dashboardのインストール

helmコマンドを使い、kubernetes-dashboardをインストールします。手順は以下に従います。

https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/


### (1) kubernetes-dashboardのインストール

```
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
```

```
helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kubernetes-dashboard
```

実行例です。

```
[root@master1 helm]# helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
"kubernetes-dashboard" has been added to your repositories
[root@master1 helm]#
```

```
[root@master1 helm]# helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kubernetes-dashboard
Release "kubernetes-dashboard" does not exist. Installing it now.
NAME: kubernetes-dashboard
LAST DEPLOYED: Mon Feb 10 20:45:28 2025
NAMESPACE: kubernetes-dashboard
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
*************************************************************************************************
*** PLEASE BE PATIENT: Kubernetes Dashboard may need a few minutes to get up and become ready ***
*************************************************************************************************

Congratulations! You have just installed Kubernetes Dashboard in your cluster.

To access Dashboard run:
  kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard-kong-proxy 8443:443

NOTE: In case port-forward command does not work, make sure that kong service name is correct.
      Check the services in Kubernetes Dashboard namespace using:
        kubectl -n kubernetes-dashboard get svc

Dashboard will be available at:
  https://localhost:8443
[root@master1 helm]#
```

### (2) kubernetes-dashboardのNamespaceのリソースの確認

作られたものを確認すると、以下です。

```
[root@master1 helm]# kubectl get all -n kubernetes-dashboard
NAME                                                        READY   STATUS    RESTARTS   AGE
pod/kubernetes-dashboard-api-7c5cfc9bcc-9nj6h               1/1     Running   0          100s
pod/kubernetes-dashboard-auth-59d6c76bd6-cx9vx              1/1     Running   0          100s
pod/kubernetes-dashboard-kong-79867c9c48-d5tdk              1/1     Running   0          100s
pod/kubernetes-dashboard-metrics-scraper-55cc88cbcb-dc52z   1/1     Running   0          100s
pod/kubernetes-dashboard-web-8f95766b5-rv9rk                1/1     Running   0          100s

NAME                                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/kubernetes-dashboard-api               ClusterIP   10.100.193.82   <none>        8000/TCP   100s
service/kubernetes-dashboard-auth              ClusterIP   10.100.147.24   <none>        8000/TCP   100s
service/kubernetes-dashboard-kong-proxy        ClusterIP   10.105.120.60   <none>        443/TCP    100s
service/kubernetes-dashboard-metrics-scraper   ClusterIP   10.101.107.18   <none>        8000/TCP   100s
service/kubernetes-dashboard-web               ClusterIP   10.96.12.159    <none>        8000/TCP   100s

NAME                                                   READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kubernetes-dashboard-api               1/1     1            1           100s
deployment.apps/kubernetes-dashboard-auth              1/1     1            1           100s
deployment.apps/kubernetes-dashboard-kong              1/1     1            1           100s
deployment.apps/kubernetes-dashboard-metrics-scraper   1/1     1            1           100s
deployment.apps/kubernetes-dashboard-web               1/1     1            1           100s

NAME                                                              DESIRED   CURRENT   READY   AGE
replicaset.apps/kubernetes-dashboard-api-7c5cfc9bcc               1         1         1       100s
replicaset.apps/kubernetes-dashboard-auth-59d6c76bd6              1         1         1       100s
replicaset.apps/kubernetes-dashboard-kong-79867c9c48              1         1         1       100s
replicaset.apps/kubernetes-dashboard-metrics-scraper-55cc88cbcb   1         1         1       100s
replicaset.apps/kubernetes-dashboard-web-8f95766b5                1         1         1       100s
[root@master1 helm]#
```

5種類のdeployment、pod、serviceが作られていることがわかります。ブラウザからWeb UIにアクセスするときは、この内、1つだけ443番で待ち受けている、kubernetes-dashboard-kong-proxyにアクセスします。


### (3) kubernetes-dashboardのバージョン確認

以下のようにして、インストールされたバージョンを確認できます。
```
[root@master1 helm]# helm search repo kubernetes-dashboard
NAME                                            CHART VERSION   APP VERSION     DESCRIPTION
kubernetes-dashboard/kubernetes-dashboard       7.10.4                          General-purpose web UI for Kubernetes clusters
[root@master1 helm]#
```


# 3. ロードバランサによるk8sクラスタ外からのアクセス設定

アクセス先のServiceは、type: ClusterIPですが、これをtype: LoadBalancerに変え、k8sクラスタ外からアクセスできるようにします。


### (1) kubernetes-dashboard-kong-proxyのマニフェストファイルの作成

```
mkdir ~/k8s-dashboard/
cd ~/k8s-dashboard/
```

kubernetes-dashboard-kong-proxyのServiceの状態を確認します。
```
[root@master1 k8s-dashboard]# kubectl get service kubernetes-dashboard-kong-prox
y -n kubernetes-dashboard
NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes-dashboard-kong-proxy   ClusterIP   10.105.120.60   <none>        443/TCP   13m
[root@master1 k8s-dashboard]#
```

ファイル化します。
```
kubectl get service kubernetes-dashboard-kong-proxy -n kubernetes-dashboard -o yaml > kubernetes-dashboard-kong-proxy.yaml
```

中身は、以下でした。

```yaml:kubernetes-dashboard-kong-proxy.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    meta.helm.sh/release-name: kubernetes-dashboard
    meta.helm.sh/release-namespace: kubernetes-dashboard
  creationTimestamp: "2025-02-10T11:45:28Z"
  labels:
    app.kubernetes.io/instance: kubernetes-dashboard
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: kong
    app.kubernetes.io/version: "3.8"
    enable-metrics: "true"
    helm.sh/chart: kong-2.46.0
  name: kubernetes-dashboard-kong-proxy
  namespace: kubernetes-dashboard
  resourceVersion: "51741"
  uid: 308234f0-af3a-4af5-8610-d8848decbd0c
spec:
  clusterIP: 10.105.120.60
  clusterIPs:
  - 10.105.120.60
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: kong-proxy-tls
    port: 443
    protocol: TCP
    targetPort: 8443
  selector:
    app.kubernetes.io/component: app
    app.kubernetes.io/instance: kubernetes-dashboard
    app.kubernetes.io/name: kong
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
```

### (2) type: LoadBalancerへの書き換え

ファイルを複製してバックアップしつつ、type: ClusterIPを、type: LoadBalancerに書き換えます。
```
[root@master1 k8s-dashboard]# cp kubernetes-dashboard-kong-proxy.yaml kubernetes-dashboard-kong-proxy.yaml.org
[root@master1 k8s-dashboard]#
[root@master1 k8s-dashboard]# vim kubernetes-dashboard-kong-proxy.yaml
[root@master1 k8s-dashboard]#
[root@master1 k8s-dashboard]# diff kubernetes-dashboard-kong-proxy.yaml.org kubernetes-dashboard-kong-proxy.yaml
37c37
<   type: ClusterIP
---
>   type: LoadBalancer
[root@master1 k8s-dashboard]#
```

### (3) kubernetes-dashboard-kong-proxyの更新

これで、変更したマニフェストファイルを適用すると、Serviceのtypeが変わりますが、

```
[root@master1 k8s-dashboard]# kubectl apply -f ./Kubernetes-dashboard-kong-proxy.yaml
Warning: resource services/Kubernetes-dashboard-kong-proxy is missing the kubectl.Kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
service/Kubernetes-dashboard-kong-proxy configured
[root@master1 k8s-dashboard]#
```

反映されはしたものの、annotationに関するWarningが出てしまったので、ファイルに書き出して直して適用、よりも、以下でエディタを開いて、書き直して保存して反映、をした方が、良かったかもしれません。（この使い分けのさじ加減がよくわかりません）
```
kubectl edit service kubernetes-dashboard-kong-proxy -n kubernetes-dashboard
```

いずれにせよ、以下のように、TYPEがLoadBalancerになり、MetalLBより、EXTERNAL-IPが払い出されていればOKです。
```
[root@master1 k8s-dashboard]# kubectl get service kubernetes-dashboard-kong-proxy -n kubernetes-dashboard
NAME                              TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)         AGE
kubernetes-dashboard-kong-proxy   LoadBalancer   10.105.120.60   192.168.11.137   443:30171/TCP   21m
[root@master1 k8s-dashboard]#
```

### (4) ブラウザからのアクセス確認

これで、k8sクラスタ外のPCのブラウザから、EXTERNAL-IPに記載のアドレスに、PORTに記載の443番に対してアクセスします。

この場合、https://192.168.11.137 です。証明書がないため、警告が出ますが、進めると、以下のログイン画面が出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468232/0029fef8-76ff-ceda-6c61-f608cdd5cb7c.png)

いま、このような状態です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468232/bae19513-fb04-e842-e0da-a7bca0e16516.png)


# 4. アカウント設定とWeb UIのアクセス

Web UIのログイン画面は、ユーザ名/パスワードの入力ではなく、tokenを求めています。以下のサンプルのように、
- ServiceAccountのリソースを作る。
- ClusterRoleBindingのリソースを作る。
を行い、rootのアカウントを作り、tokenを作成します。

https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md


### (1) ServiceAccountの作成（name: root）

以下ファイルを作成します。

```yaml:dashboard-user-root.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: root
  namespace: kubernetes-dashboard
```

### (2) ClusterRoleBindingの作成（kind: ClusterRole）

以下ファイルを作成します。

```yaml:crb-user-root.yamldashboard-user-root.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: root
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: root
  namespace: kubernetes-dashboard
```

### (3) マニフェストファイルの適用

マニフェストファイルを適用します。
```
kubectl apply -f ./dashboard-user-root.yaml
kubectl apply -f ./crb-user-root.yaml
```

### (4) rootのServiceAccountのtoken生成

rootのアカウントに対し、tokenを生成します。
```
kubectl -n kubernetes-dashboard create token root
```

実行例です。
```
[root@master1 k8s-dashboard]# kubectl -n kubernetes-dashboard create token root
eyJhbGciOiJSUzI1NiIsImtpZCI6IjJ2SmxaYjVVaHY5dzE0UE8xY1lRLWRFTWxSWFhBT2xwaHZVdEhKdHlNU3cifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzM5MTk4Mzg5LCJpYXQiOjE3MzkxOTQ3ODksImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiZDliYTM4NTktZGJhYS00OGVmLTlmNzctMjhjMTlkZmYyNzFjIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJyb290IiwidWlkIjoiOGMxMTBmMGItNDEzZS00OTkxLTg3MjItY2VkYTA1OThhZTRjIn19LCJuYmYiOjE3MzkxOTQ3ODksInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDpyb290In0.WVOg6zxQFN90XQjNlkSaeKYWF1Fdtb2HbKuWztFJRj5UD8k5pbewtqEiRpeZPsAx-AJ9p_qHVFfLWXEMtGxylmNrOInCIvZDXPNeSgi5EbHl0y9XC7iCDpJciXSF4l__CjzpkZ1ceYTOHgaAfhVvYUlrzqdVA7MjSof1cy7A37Ak1CZB5TTFEdJsCvx9rsyQSM9Xh-nX_KKK1EylESfp9Rb9JkLJGoHLafVbOmgdIX77JkKJG022xYlfRbWrWepNIV5jEjsod7BTGRK7R-7sHWiAVf6Zy8UOklwocdS6aAE9ZdqPrtMPLAYkENYXNpHmBMfCFuyegS9MtcssfftAKQ
[root@master1 k8s-dashboard]#
```

### (5) tokenを使ったrootでのログイン

このログイン画面に、生成されたtokenを貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468232/a327d1c4-10b6-4832-1699-8fa7913ca44f.png)

貼り付けたら、「サインイン」を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468232/e570a82f-b476-8530-7af6-67ef85f84014.png)

これで、ログインできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468232/7809a2ea-c555-86db-33b9-8bbe7d29f9af.png)


# まとめ
kubernetes-dashboardを使えるようにしました。これで、k8sクラスタ内の各リソースを、管理画面で見ることができるようになります。