Headlamp : Kubernetes ダッシュボードの選択肢

この記事は Fujitsu Advent Calendar 2024 の 16日目 の記事です。

昨日は @kazumura さんの [「varとwhenの使い方」](https://qiita.com/kazumura/items/37a5e4e1bf2aefc8e2b3)でした。Javaみたいに歴史が長い言語だと、こういった互換性担保による複雑性が生まれるんですかね。勉強になります

本記事ではネタ探し中にGithubを彷徨っていて見つけたKubernetesのダッシュボードプロジェクトである [Headlamp](https://headlamp.dev/) について簡単にご紹介したいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39615/8988a125-e4e4-f3a4-d68c-047091963397.png)

# Key takeaways

* Headlampの機能概要が分かる
* Headlampの導入方法が分かる
* Headlampへのプラグイン追加の仕組みが分かる

# Headlampが生まれた背景

[標準のKubernetes Dashboard](https://github.com/kubernetes/dashboard)や[k9s](https://github.com/derailed/k9s)等、Kubernetesのダッシュボードは各種存在します。Githubを [`kubernetes-dashboard`のトピックで検索すると他にも色々ヒットします](https://github.com/topics/kubernetes-dashboard)が、その中でも以下を満たす位置づけとして新たにCNCF Sandboxプロジェクトとして加わりました（2023/12）。

* ユーザーフレンドリーなUI
* ユーザーのニーズに基づいてカスタマイズが容易に可能な高拡張性
* K8s側のRBACと連携した認可制御

クラスタの規模などで向き不向きはあると思いますが、ダッシュボードの新たな選択肢が加わりました。ちなみに、ほんの少し使ってみた限りでは、Headlampの各種リソースのリスト表示における視認性等を見ると、現状は小中規模のクラスタ向けのようには見えます。

# Headlamp OSS概要

* https://github.com/headlamp-k8s/headlamp

Kubernetesの各種リソースを一覧表示し、フィルタリングやソート、詳細情報へのドリルダウン等は基本的な機能として持っています。デプロイ方法としても、Standaloneなデスクトップアプリとして利用する方法とin-clusterなサービスとしてデプロイしてアクセスする２パターンが存在します。ここまでは他のダッシュボードアプリでも見られる一般的な特徴です。一方で差別化ポイントとしては、プラグインによるダイナミックなダッシュボードの拡張容易性が挙げられます。Storybook のフレームワークを利用し、コンポーネント毎に独立して開発・適用が可能です。本記事でも文末で軽く触れたいと思います。

# 導入方法

利用方法には以下の２パターンあります。本記事では後者の `in-cluster` 形式での導入方法について紹介します。

* ローカルに `standalone` アプリをダウンロードして利用する方法
* Kubernetesクラスタ上に `in-cluster` な形で起動してアクセスする方法

## deployment/serviceの適用

ここではYamlファイルをダウンロードして、ターゲットのクラスタに適用していく

```
wget https://raw.githubusercontent.com/kinvolk/headlamp/main/kubernetes-headlamp.yaml
# 一旦Yamlファイルの中身を眺めた後 ...
kubectl apply -f kubernetes-headlamp.yaml
```

ここでは簡略化のため、Port-Forwardingでサービスへアクセスする

```
kubectl port-forward -n kube-system service/headlamp 8080:80
```

http://localhost:8080 にアクセスすると以下のログイン画面が表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39615/55bd45ee-800b-c6c0-2501-d3a46cc53666.png)

## 認証の設定

ログインにはサービスアカウントのトークンによる認証とDexやKeyCloak、Cognito等のIDaaSを利用したOIDCによるID認証の2パターンに対応しています。本記事では、ダッシュボードアクセス用のサービスアカウントを作成して、トークンを発行することにより認証します。サービスアカウントにRBACによる必要な設定を適宜することによって、サービスアカウントごとにダッシュボード経由での操作を制限/制御することが可能です。以下の例では `cluster-admin` のClusterRoleを新規に作成したサービスアカウント`headlamp-admin`にbindします。

```
kubectl -n kube-system create serviceaccount headlamp-admin
kubectl create clusterrolebinding headlamp-admin --serviceaccount=kube-system:headlamp-admin --clusterrole=cluster-admin
kubectl create token headlamp-admin -n kube-system
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39615/71b46e5a-1550-f2bb-e824-7481682e1c17.png)

画面左のペインから一通りのリソースにアクセスすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39615/f61d9042-01ed-6b1b-e9fe-4003cedfe04a.png)

またクラスタをネットワーク表示してドリルダウンしていくビューもあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39615/3a208cbd-5a3e-9c3e-9f91-3eabec1dd3f3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39615/a2661a39-52df-2aa8-ce06-618f883f32f7.png)

## ClusterRoleによるアクセスの制限

ちなみにPodの参照権限のみ付与したClusterRoleを定義して、これをbindしたサービスアカウントでログインするとPod以外のリソースの参照ができません。

```
kubectl -n kube-system create serviceaccount headlamp-read-only
kubectl create clusterrole example-read-only --verb get,list,watch --resource pods
kubectl create clusterrolebinding headlamp-read-only --serviceaccount=kube-system:headlamp-read-only --clusterrole=example-read-only
kubectl create token headlamp-read-only -n kube-system
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39615/b71652b3-5a84-9e75-e0f1-ca96b7eb578e.png)

参照権限がない場合、UI上はローディングのままになります。権限がない旨のメッセージ等は表示されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39615/10e1053a-971f-67e3-3646-63d0858a45c9.png)

# プラグインの開発

プラグイン開発は、HeadlampのNode.jsパッケージである `@kinvolk/headlamp-plugin` に同梱された `headlamp-plugin` CLIを利用した開発ライフサイクル（プロジェクト作成、Linting、テスト実行、ビルト＆デプロイ等）になっています。



以下にサンプルやデフォルトでビルトインされているプラグインのリポジトリがあります。

* https://github.com/headlamp-k8s/headlamp/tree/main/plugins%2Fexamples
* https://github.com/headlamp-k8s/plugins

各フォルダがプラグインの開発フォルダになっており、この配下で`npm run build` もしくは `npx @kinvolk/headlamp-plugin build ./`等を実行すると、各種コードがbundleされた`main.js`が生成され、これをしかるべきpluginフォルダに格納すると（もしくは `npx @kinvolk/headlamp-plugin extract ./[plugin name] ~/.config/Heatlamp/plugins`を実行すると）、プラグインとして動的にロードされてUIがアップデートされます。

# 最後に

プラグイン開発に関して、思ったより踏み込んだ内容にはできませんでしたが、ダッシュボード選定時におけるインプット情報の１つとなれば幸いです。個人的にはvimライクな操作性があるk9sユーザーではあります。が、プラグイン開発による高い拡張性部分については、過去に似たようなダッシュボードのOSS projectで活動していた関係上、興味がありますので、引き続き注視＆時間があればれば検証していきたいと思います。