こんにちは。 社会人になってやりたいことに対する自分の時間が圧倒的に足りなくなり謎の焦燥感に駆られています、sanposhihoです。
僕は、普段趣味の時間を使ってKubernetesにcontributeしています。昨年に MinDomains というPod Topology Spreadの新しい機能のKEPが承認され、alpha機能としてKubernetes v1.24でリリースされました。僭越ながら、KEPのAuthorは僕、実装も僕です。
KEP-3022: min domains in Pod Topology Spread
ちなみにこの機能はKubernetes v1.24の一部として、今年の5月にすでにリリースされています。ふと「なかなかないことだから、日本語で記事に残しておくことに意味ある気がするな」と思ったので筆をとっています。
KEPを含めて5ヶ月くらい取り組んでいたMinDomainsの実装が終了した👏
— さんぽし/sanposhiho (@sanpo_shiho) March 16, 2022
Kubernetes v1.24でalpha機能として追加されますhttps://t.co/s76yFiuhqThttps://t.co/LSB8TLapLS
KEPって何?
Kubernetes Enhancement Proposalの略称です。Kubernetesでは、APIへの変更が行われるなどの大きな機能や変更が入る際には、issueで議論するだけではなく、KEPを書いて、その上で十分な議論をし、実装する形をとっています。
https://github.com/kubernetes/enhancements/blob/master/keps/README.md
Pod Topology Spreadって何?
一言で超簡単に言うと「スケジュールの時に、いい感じにnode間とかzone間とかの任意のまとまりでPodを散らばらせる機能」です。
例えば、Podが10*N個あって、Nodeが10個あるとします。
「PodをNodeに均等にN個ずつ配置したい!」そういう願いを叶えてくれるのが、Pod Topology Spreadです。
詳しくは、公式のドキュメントを見てください。
https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
MinDomainsって何?
MinDomains は一言で超簡単に言うと「Podが配置されたまとまりの数の最小値を設定する機能」です。
例えば、「Podを最低でも5つのNodeに配置したい!」そういう願いを叶えてくれるのが、MinDomainsです。
Cluster Autoscalerを前提に作られているような節があり、先ほどの例でもう少しだけ詳しくユースケースを説明すると、
- 「Podを最低でも5つのNodeに配置したい!」をMinDomainsで設定しました。 (
topologyKey: kubernetes.io/hostname, minDomains: 5, whenUnsatisfiable: DoNotSchedule, maxSkew: 1
) - Nodeが4つあります
- Podを沢山作りました。
- Nodeに一つ一つ(2)で作成したPodが配置されていきます。
- Nodeそれぞれが1つずつPodを持っている状態になりました。(=合計4つのPodがスケジュールされています)
- (0)で、「Podを最低でも5つのNodeに配置したい!」といっていましたが、Nodeは4つしかないことに、Schedulerは気が付きます。
- それ以降の全ての(2)で作ったPodのスケジュールは失敗します。
- Cluster Autoscalerは「なんかPodめっちゃスケジュールに失敗してるな〜」と気が付きます。
- Cluster AutoscalerがNodeを新たに作成します。
- Nodeの数が合計で5つになったので、(0)は満たされます。
つまり「Podを最低でも5つのNodeに配置したい!」を設定することで、結果としてCluster Autoscalerに一つNodeを増やさせて、Nodeを5つにすることに成功しているわけですね。
これが例えば「Podを最低でも5つのZoneに配置したい!」ということであれば、Cluster Autoscalerは新たなZoneのNodeを増やしてくれるはずです。(Cluster Autoscalerに詳しくないので一応検証してください。もちろん事前にCluster Autoscalerが作成できるNodeの候補に5つ目のZoneのNodeが存在する必要があるはずです。)
詳しくは、公式のドキュメントを見てください。
https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
もしくは、sanposhihoさんという方のKubernetes Meetup Tokyo #48での発表は日本語なのでわかりやすいかもしれませんね。
KEP を出して、それが実装されるまでにやること
ここまではPod Topology SpreadとMinDomainsの説明でしたが、「KEPを出してからそれが実装されるまでにやったこと」を見ます。
0. KEPの元となるissueがupstream(kubernetes/kuberentes)に立つ
いきなり、KEPが書かれ始める、というよりは初めにkubernetes/kubernetesにそれの種となるようなissueが作成されることが多い気がします。
僕がいただいた種は↓こちらです。
Tuning the number of domains in PodTopologySpread · Issue #105291 · kubernetes/kubernetes
issue自体はメンテナが立てたものですが、種の種となったissueが存在します。つまり、クソでかOSSであるKubernetesでもユーザーの声を拾って新しい機能を作成しているわけですね。
1. issueが立ち、KEPを書く
よし、「KEPを書いて議論しよう」となると、IssueがKEPが置かれるkubernetes/enhancementsに立ちます。
この時点では「議論しよう」となっているだけで「実装決定!」というわけではありません。KEPで議論されたけど、結局承認されない機能も数知れず。
KEPには以下のテンプレートが用意されています。
https://github.com/kubernetes/enhancements/tree/master/keps/NNNN-kep-template
そして、レビューをSIGと呼ばれるチームメンバーからもらう必要があります。SIGはSpecial Interest Groupsの略称で、Kubernetesは領域ごとにチームに分かれて開発されています。(例えば、SchedulerはSIG-Schedulingの担当領域です。)
また、KEPはSIGのお偉いさんからのレビューだけではなく、Production Readiness Reviewsというものを受ける必要があります。
Production readiness reviews (PRRs) are intended to ensure that enhancements merging into Kubernetes are observable, scalable and supportable, can be safely operated in production environments, and can be disabled or rolled back in the event they cause increased failures in production. (中略) It is useful to have the viewpoint of a team that is not as familiar with the intimate details of the SIG, but is familiar with Kubernetes and with operating Kubernetes in production. https://github.com/kubernetes/enhancements/tree/master/keps/prod-readiness
雑に一言で言うと、「詳しい実装は知らんけど、広い目線を持ったKubernetes運用に詳しい人からのレビューもやった方がいいよね」と言うことです。
これらのレビューを通して、承認されると、KEPのPRがmergeされ、状態がimplementableになります。
2. 実装する
さて、長い議論を経て、実装に入ることができます。
- Add MinDomains API to TopologySpreadConstraints field by sanposhiho · Pull Request #107674 · kubernetes/kubernetes
- Implement MinDomains on Pod Topology Spread by sanposhiho · Pull Request #108362 · kubernetes/kubernetes
KEPで議論した実装の通りに実装を進めます。また、僕の場合は、Podの中にPodSpec.TopologySpreadConstraints.MinDomains
と言うフィールドを追加する必要があります。
フィールドの追加のためにはフィールドの追加の他に、validationやデフォルト値の処理を書く必要がある場合があります。
また、テストももちろん書くわけですが、パフォーマンスの低下がないかをチェックする必要があります。 Schedulerのパフォーマンス計測には、scheduler_perfが使用されます。
3. ドキュメント書く
KEPを必要とするような大きな変更のほとんどはドキュメント(webページ)の変更が必要となります。
4. リリースを座して待つ
Kubernetes v1.24.0でalpha機能として無事に追加されました。
Kubernetesの機能は基本的にalpha→beta→stableを辿ることになっており、alphaの機能を使用するには、feature flagで明示的に有効化する必要があります。
5. そして月日が流れ、beta, stable昇格へ…
そのまま順調にいけば、機能はいくつかのリリースの間様子を見られ、コミュニティからのフィードバックを受けながら、betaやstableへと成長していきます。
MinDomains も何事もなければ次のv1.25でbetaに昇格する予定です。
- [KEP-3022] Write the production readiness requirements to graduate to beta by sanposhiho · Pull Request #3338 · kubernetes/enhancements
- Graduate MinDomains in Pod Topology Spread to beta by sanposhiho · Pull Request #110388 · kubernetes/kubernetes
終わりに
一生のうちに恐らくそうそう無い貴重な経験でした。
KEPレベルの機能の議論や実装にはかなり時間が取られるので、学生のうちに経験できてよかったです。