お家k8sを改善した話と気づき


# はじめに

こんにちは。最近はお家 k8s とランニングにはまっています。
そこで今回はお家 k8s を改善してみたのでその紹介と、やってみて感じたことを書いていきます。

## お家 k8s を改善した話

私のお家 k8s 環境は様々なエコシステムをデプロイしていました。例えば以下のようなものです。

- ArgoCD
- Istio
- Prometheus
- Grafana
- Loki
- fluent-bit
- ...

ただ、デプロイ方法が全て Getting Started のコマンドを叩いていただけだったため、バージョンアップが難しかったり、可搬性の観点で良くないと感じていました。
そこで ArgoCD の App of Apps パターンへの移行を行いました。

ArgoCD とは CD ツールで、GitOps を実現するツールです。
ArgoCD に対して Git リポジトリを指定し、Application という ArgoCD のリソースをデプロイすることで、Application に指定されたリソースをデプロイしてくれます。
この Application の定義は Git リポジトリに配置されているため、常に Git リポジトリの状態と同じ状態になります。
この常に Git リポジトリの状態と同じ状態に同期するのが GitOps の一つの特徴です。

App of Apps パターンは、リソースをデプロイしたい Application を Application によってデプロイするというパターンです。
これによって、新たに Application の定義を作成すると、親の Application が自動でデプロイしてくれるようになります。

私の場合、Prometheus や Istio などインフラ寄りのリソースをデプロイする Application は全て同じディレクトリに配置し、そのディレクトリをデプロイする Application を作成したりしました。
下の画像は ArgoCD の UI で、一つの Application によって複数のインフラリソースがデプロイされている様子です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510833/397b2e81-642d-b984-e8e8-4b2b6e08d337.png)

一番上位の Application は手動でデプロイしていますが、それ以外の Application は自動でデプロイされるようになりました。

今回採用したエコシステムは全て Helm によるデプロイが用意されていたので、Application には Helm を指定し、values を少し編集するだけでデプロイできています。

このように改善したことで、別の k8s クラスターに移行する際も少ない手順で再現度高く同じ環境を構築できるようになったと思います。
また、エコシステムのバージョンアップも Application の設定を変えるだけかつ、ArgoCD にデプロイを任せれば良いので簡単に行えるようになりました。

副次効果として ArgoCD の UI 上からリソースの状態を確認できるようになったのも嬉しかったです。
リソースの状態は Grafana などの別のエコシステムで詳細を確認すべきだとは思いますが、ArgoCD だとどのリソースが壊れているのかを UI から簡単に確認できます。
下は Loki への通信が失敗しまくってエラーを起こしている fluent-bit の様子を ArgoCD の UI から確認している画面です。
![スクリーンショット 2024-10-31 22.15.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510833/3f1ed6db-7219-faf7-6561-92dd79a7c7bd.png)

概要を知るのには大変便利ですし、画面のようにコンテナが吐いているログまで見れてしまうので、Grafana などを利用せずに ArgoCD だけでデバッグをすることも可能だと思いました。

## 感じたこと

ここからは改善してみて感じたことを書いていきます。
改善したこと以外にも前から感じていたことも含めて書いていきます。

### エコシステムが便利すぎる

上ではほぼ ArgoCD の話をしていましたが、ArgoCD 含め、k8s のエコシステムが最高すぎると感じました。

Grafana + Prometheus + Loki の組み合わせで、リソースの状態やアプリケーションログを簡単に確認ができます。
![スクリーンショット 2024-10-31 21.35.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510833/234a1e93-6b13-6682-0eb7-6e349a734263.png)

Istio は導入して namespace にラベルをつけるだけで、全ての Pod に対してトラフィックの監視や mTLS の制御などたくさんのことが可能になります。

また、kiali や jaeger などを Istio と組み合わせることで、トラフィックの可視化や分析も簡単に行えます。
下の画像は kiali のトラフィック可視化の画面です。アプリケーション側では何もしていないのですが、Istio と kiali を導入するだけでこのような可視化が可能になります。
![スクリーンショット 2024-10-31 21.49.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510833/2893c783-007d-eb4c-bfb9-ca95ac577ed1.png)

falco は Node 全体を監視して、不正なアクセスやファイルの変更などを検知してくれます。falco を入れているだけでセキュリティの安心感が増します。また、下の画像のように Slack への通知も簡単にできるため、セキュリティのインシデントに対して迅速に対応できるようになります。
![スクリーンショット 2024-10-31 21.39.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510833/674fe804-858d-f157-631e-c7c9deeb7506.png)

このように導入するだけで、様々な機能が使えるのはとても魅力的です。
また、良く設計されているエコシステムは単一責務なものが多く、様々なエコシステムを柔軟に組み合わせて利用できるのも魅力的だと感じました。

### Helm が最高すぎる

上では様々なエコシステムの紹介をしましたが、エコシステムの導入を簡単にしてくれるのが Helm だと感じました。
多くのエコシステムでは Helm Chart が用意されており、helm install するだけでデプロイができます。
また ArgoCD の Application で Helm によるデプロイを指定することも可能で、私はこれを利用しています。

Helm のおかげで複雑な構成のエコシステムを複雑さを気にすることなく導入することができます。[]^1]
Helm のおかげでエコシステムを導入し、自分の k8s を成長させることができるので、とてもありがたいと感じました。

### とはいってもやはり難しい

上では散々褒めましたが、やはり難しい一面も多いです。
以下は私が感じた難しい点です。

#### エコシステムの挙動把握が難しい

- ドキュメントや Helm の定義をよく見る必要がある
- 実際にデプロイして随時挙動を確認するといった検証方法が多くなりがちで、時間がかかる
- yaml の少しのズレで何度もデプロイが失敗...[^2]
- あまり理解せずに利用すると、誤った事故を発生させることがある
  - Application で namespace を管理していたが、誤って Application を削除してしまい、全てのリソースが削除されるという事故が発生した
  - 遊びでよかったが、本番でやったと考えると怖すぎ...

#### ベストプラクティスが調査しても見つからないことが多い

- k8s やエコシステムの細かい使い方に対するベストプラクティスが調査しても見つからないことが多い
- ディレクトリ構成は？エコシステムの Helm Charts は自分のリポジトリに持つべきか、公式のリモートリポジトリを参照すべきか?

#### 一部手動による作業が必要(もしかしたら自動化できる？)

- あるべき状態に調整するのが k8s の醍醐味ではあるものの、ものによっては手動で調整する必要があることがあった
  - 特にステートを持つリソースなど
  - ただし、これは k8s やエコシステムの理解が足りていない説があるので、もっと勉強すれば自動化できるかもしれない
- ArgoCD 自体の初期デプロイは手動でやる必要がある
- App of Apps の Root の Application は手動でデプロイしている

#### エコシステムをふんだんに利用するとリソースのコストが高くなる

- エコシステムを入れていくだけで、簡単に 100 以上のコンテナが起動される
  - メモリ 8GB x 3 つ、4GB x 2 つの raspberry pi で運用しているが、ちょくちょく Node が落ちる[^3]
- Node が落ちると、復旧作業が必要になる

このように難しさも多いので、本番利用する際はしっかりとした運用体制と設計が必要だと感じました。

## おわりに

今回はお家 k8s を改善してみて、k8s の良さを感じました。
エコシステムが充実していることで、簡単に様々な機能を導入できるのはとても魅力的だと感じました。
ただ、やはり難しいことは否めないなーと感じました。

正直まだまだエコシステムをインストールしただけ感があるので、次は k8s、エコシステムともに様々な機能を使いこなしていきたいと思います。

ここまで読んでいただきありがとうございました。

[^1]: もちろんこれはエコシステムを作成している方々うまく Helm Chart を作成しているおかげでもありますが
[^2]: CI の仕組みを導入すればデプロイせずとも検証できるかもしれないです。
[^3]: 8GB の raspberry pi 3 つはマスターノードかつ Pod がスケジュールされるように利用しているため、できるだけフル活用していますが、もっとリソースが欲しいです笑