KubernetesのManifest管理

KubernetesのManifest管理 #

ここではManifestの管理をどのように実施しているかについて紹介します。 結果から言えば、Kubernetesで利用するManifestを生成するGeneratorをTypeScriptで構築しました。

どのように構築して運用しているのか説明していきます。

移行後の各Componentのファイル数の規模感 #

導入でも提示していますが改めて、フロントエンドに関係するマイクロサービスのManifestは以下の規模で存在しています。 これは簡単に管理するとは言えないコンポーネント数があり、これからも増えていきます。

Componentファイル数
v1/Deployment20
v1/Service60
v1/Config Map15
batch/v1/Job15
argoproj.io/v1alpha1/Rollout20
networking.istio.io/v1beta1/VirtualService20
networking.istio.io/v1alpha3/EnvoyFilter20

問題意識 #

移行前の段階ですでにファイル数はYAMLで保守するには困難な量が発生することはわかっており、ツールによる補完支援やテスト無しでは必ず破綻することが容易に想定されました。また、これらは最初に定めた2つの目標に反します。

  • デプロイが素早く簡単にそして安全に実施できる
  • Webフロントエンド開発者が更新に必要な最低限の設定の変更を簡単に実施できる

TypeScriptでManifestの保守面の問題を解決する #

これらを網羅的に解決する一つの方法としてTypeScriptによりKubernetesのYAMLを生成することです。 TypeScript自体の利点は各種記事に譲るとして、Kubernetesを運用するチームの背景としてTypeScriptを日常的に利用しているWebフロントエンドのエンジニアたちです。

したがって、TypeScriptでManifestを記述すること自体は非常に障壁がほとんど皆無という状態です。 またManifest自体のテストもTypeScriptからYAMLを生成するタイミングでExceptionを投げてしまえば良いだけなので、テストの方針も非常に単純になります。

仮にTypeScriptで書くのを辞めたいといった場合は生成されたYAMLを持っていけば良いので、TypeScript自体を切り捨てることも簡単になります。

以上の理由からTypeScriptで記述しない理由が移行の設計段階で存在しないため、ManifestをYAMLで書くことを初手で捨て、TypeScriptで記述するようにしました。

TypeScriptでKubernetesを書くための支援ライブラリとSchema #

KubernetesはCustomResourceDefinitionを定義する際OpenAPI Schema V3で記述できます。 これによってSchemaがApply時にValidationされています。 逆に言えば、OpenAPI SchemaをTypeScriptの型定義に書き起こしてしまえばValidationをTypeScriptの静的型付けに変換することができます。

幸いにして筆者はOpenAPI SchemaとTypeScriptの話にはちょっとだけ詳しいので、 手前味噌ですが@himenon/openapi-typescript-code-generatorを利用してKubernetesの型定義を生成しました。

もちろん他にも同じようなアプローチで型定義を提供しているものもありますが、以下の点で見送りをしています。

  • TypeScriptのObjectに対してシンプルに型定義を当てたい
    • これはライブラリ側のメンテナンスが滞っても自分たちで書き直すことができるため
  • ArgoCDやArgoRollouts、Istioなど他のCustom Resource利用時も同じライブラリの使い勝手になるようにしたい
  • 最新だけでなく任意の古いバージョンもサポートするようにする

これらを考えたときになるべくライブラリは薄く実装されているのが望ましく、型定義ライブラリをForkしたときも簡単にメンテナンスできる実装ベースが必要でした。これらの条件を満たす設計コンセプトで豊富な知見があるライブラリは@himenon/openapi-typescript-code-generatorでした。

次の節でより詳細に紹介します。

他のライブラリ #

Kubernetes向けTypeScriptのライブラリ

KubernetesのDefinitionが定義れているComponentはCustomResourceDefinitionがあります。