Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
20,000+行のmanifestをリファクタリングして分かったKustomizeの美しきアー...
Search
hhiroshell
November 04, 2021
Technology
5
5.4k
20,000+行のmanifestをリファクタリングして分かったKustomizeの美しきアーキテクチャと拡張性 / Kustomize deep dive
#CNDT2021 で Kustomize の話をしたときの資料です。
hhiroshell
November 04, 2021
Tweet
Share
More Decks by hhiroshell
See All by hhiroshell
LINEヤフーにおける超大規模プラットフォーム実現への挑戦と学び / Challenges and Lessons in Building an Ultra-Large-Scale Platform at LY Corporation
hhiroshell
3
1.2k
Architecting Kubernetes-Based Internal Developer Platforms: Essential Patterns and Practices
hhiroshell
0
87
Discover Your Tailored Platform Strategy with Real-World Practice
hhiroshell
1
200
Kubernetesでアプリの安定稼働と高頻度のアップデートを両立するためのプラクティス / Best Practices for Applications on Kubernetesto Achieve Both Frequent Updates and Stability
hhiroshell
10
3.8k
Platform EngineeringにおけるKubernetesの活用法とLINEヤフーにおける事例のご紹介 / Platform Engineering and Kubernetes Findy Lunch LT Edition
hhiroshell
7
1.7k
大規模Webアプリケーションプラットフォームを開発して軌道に乗るまでにやったこと / How to Put Platforms on Track
hhiroshell
2
2.5k
Kubernetesとカスタムコントローラーを活用したプラットフォーム開発・運用の勘所 / Platform Engineering and Kubernetes
hhiroshell
1
1.2k
Best Practices for Applications on Kubernetesto Achieve Both Frequent Updates and Stability
hhiroshell
3
680
Cloud Native Developers JP (cndjp) のご紹介 / about cndjp
hhiroshell
0
210
Other Decks in Technology
See All in Technology
UI State設計とテスト方針
rmakiyama
2
650
ゼロから創る横断SREチーム 挑戦と進化の軌跡
rvirus0817
2
270
MLOps の現場から
asei
7
650
Opcodeを読んでいたら何故かphp-srcを読んでいた話
murashotaro
0
280
APIとはなにか
mikanichinose
0
100
複雑性の高いオブジェクト編集に向き合う: プラガブルなReactフォーム設計
righttouch
PRO
0
120
生成AIをより賢く エンジニアのための RAG入門 - Oracle AI Jam Session #20
kutsushitaneko
4
260
Microsoft Azure全冠になってみた ~アレを使い倒した者が試験を制す!?~/Obtained all Microsoft Azure certifications Those who use "that" to the full will win the exam! ?
yuj1osm
2
110
ずっと昔に Star をつけたはずの思い出せない GitHub リポジトリを見つけたい!
rokuosan
0
150
第3回Snowflake女子会_LT登壇資料(合成データ)_Taro_CCCMK
tarotaro0129
0
200
Oracle Cloudの生成AIサービスって実際どこまで使えるの? エンジニア目線で試してみた
minorun365
PRO
4
290
KubeCon NA 2024 Recap / Running WebAssembly (Wasm) Workloads Side-by-Side with Container Workloads
z63d
1
250
Featured
See All Featured
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
32
2.7k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
How STYLIGHT went responsive
nonsquared
95
5.2k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
Visualization
eitanlees
146
15k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Navigating Team Friction
lara
183
15k
Side Projects
sachag
452
42k
Being A Developer After 40
akosma
87
590k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
111
49k
Transcript
20,000+⾏のmanifestをリファクタリングして分かった Kustomizeの美しきアーキテクチャと拡張性 @hhiroshell 1
宣伝 • 感染対策をしっかりやって遊舎⼯房に⾏きましょう 2 遊舎⼯房さんの店舗はこちら→ ↓現在の@hhiroshellのキーボードたち #crkbd ⾃⼰紹介 @hhiroshell 早川
博 (はやかわ ひろし) • Cloud Nativeなインフラを開発 するエンジニア。 Yahoo Japan Corporation 所属 • エンジニアコミュニティ 「Cloud Native Developers JP」 オーガナイザー • Developers Summit 2018 Japan Container Days 12.18 CloudNative Days Tokyo 2019 / 2020 登壇 • ⾃作キーボード沼 BMEK
⽬次 1. イントロダクション 2. Kustomizeの仕組みを知ろう 3. ディレクトリ構成の考え⽅ 4. Kustomizeプラグインを活⽤しよう 5.
⼤規模manifest群をリファクタリングするコツ 6. まとめ 3
⽬次 1. イントロダクション 2. Kustomizeの仕組みを知ろう 3. ディレクトリ構成の考え⽅ 4. Kustomizeプラグインを活⽤しよう 5.
⼤規模manifest群をリファクタリングするコツ 6. まとめ 4
Kustomizeとは • manifestに差分だけを書いたパッチを当ててバリエーションを作る • 環境ごとの共通部分、差分を分けて管理するのに役⽴つ manifestをDRYに管理するためのツール 5
6 ⼀⾒わかりやすいようで、使ってみると…。 Kustomizeに関するよくある感想 なるほどなるほど。manifestの差分 だけを書いてoverlayに置けばよいの ですね。直感的でいいですね! フィールドの部分⽂字列を置き換えた りはできないんだ? テンプレートっ ぽくは使えないんだな…。
manifestが多いと overlayの中が散らかっ てくるな…。 なんかできないことが 多いような?
このセッションのゴール • Kustomizeの使いこなせるようになって 今までのイメージを払拭してほしい…!! – Kustomizeの仕組みを理解して使いこなせる – いい感じにmanifest構造の設計ができる – いままでだったら諦めてたかゆいところに⼿が届
いちゃう – Kustomize is マジ God Kustomizeと仲良くなろうー。 7 yamlエンジニア Kustomize
⽬次 1. イントロダクション 2. Kustomizeの仕組みを知ろう 3. ディレクトリ構成の考え⽅ 4. Kustomizeプラグインを活⽤しよう 5.
⼤規模manifest群をリファクタリングするコツ 6. まとめ 8
kustomize build を実⾏したときに起きること ⼊⼒となるリソースに対して、複数の加⼯を施した結果を得る 9 入力 出力 KRMリソース KRMリソース kustomization.yaml
リソースの追加・加工 ? kustomization.yaml リソースの追加・加工 ? • 複数のKRM(Kubernetes Resource Model)リソースを⼊⼒として、リ ソースの追加、加⼯(kustomization)が⾏われた結果を出⼒する – 追加、加⼯の内容はkustomization.yamlに宣⾔的に記述 – 複数のkustomization.yamlを書いて繋げられる kustomization.yaml リソースの追加・加工 ?
kustomization.yamlで指定できるkustomization処理の例 • resources – kustomization処理の⼊⼒ • KRMリソースのパス • 他のkustomization.yamlの出⼒ •
configMapGenerator – 指定した内容のConfigMapを追加 • commonAnnotations – 共通のannotationを付加 • patches – KRM形式で記述したパッチの適⽤ 1 apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml - service.yaml configMapGenerator: - name: example-properties files: - example.properties commonAnnotations: hashtag: “#CNDT2021” patches: - patch.yaml
kustomization処理の実体 • Kustomizeに標準で備わって(Builtin)いるkustomzation機能は、全て GeneratorまたはTransformerの派⽣ – コード的にはGeneratorPlugin / TransformerPluginというインターフェースの実 装になっている •
GeneratorとTransformer – Generatorはリソースの追加 – Transformerは⼊⼒されたリソースの加⼯ = GeneratorとTransformer 11 ResMap Generator/Transformer
kustomization処理の連鎖的な実⾏ • ResMap: – KRMリソースの集合体。Generator / Transformerによってリソースが追加、加 ⼯される • Generator
/ Transformer: – ResMapを加⼯する処理 複数のGenerator / Transformerによってmanifestが加⼯(kustomization)されていく 12 KRMリソース ResMap ResMap ResMap Generator/Transformer 入力 出力 KRMリソース Generator/Transformer Generator/Transformer
Generator / Transformerの実装を⾒てみる - 1/2 • GeneratorPlugin / TransformerPlugin インタフェースの定義
1 type GeneratorPlugin interface { Generator Configurable } type TransformerPlugin interface { Transformer Configurable } type Transformer interface { Transform(m ResMap) error } type Generator interface { Generate() (ResMap, error) } type Configurable interface { Config(h *PluginHelpers, config []byte) error } resmap.go
Generator / Transformerの実装を⾒てみる - 2/2 • AnnotationsTransformerPlugin(commonAttionationsに当たる部分の実装) 1 func (p
*AnnotationsTransformerPlugin) Config(_ *resmap.PluginHelpers, c []byte) (err error) { p.Annotations = nil p.FieldSpecs = nil return yaml.Unmarshal(c, p) } func (p *AnnotationsTransformerPlugin) Transform(m resmap.ResMap) error { if len(p.Annotations) == 0 { return nil } return m.ApplyFilter(annotations.Filter{ Annotations: p.Annotations, FsSlice: p.FieldSpecs, }) } AnnotationsTransformer.go
【おまけ】おなじみのKustoization機能も実は • ビルトインの機能もkustomzation.yaml上でtrasfomersフィールドに書 くことができる – 普段使っているのはtransformerに特別に与えられた記法 1 apiVersion: kustomize.config.k8s.io/v1beta1 kind:
Kustomization transformers: - |- apiVersion: builtin kind: PrefixSuffixTransformer metadata: name: myFancyNamePrefixer prefix: bob- fieldSpecs: - path: metadata/name apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namePrefix: bob-
kustomization.yamlとKustomizationディレクトリ • kustomization.yamlは⼀つのディレクトリに⼀つ配置 • リソース追加・加⼯のためのファイル(e.g., patch, resources)を同ディレクトリ に置く 複数のKustomization処理を束ねる単位 16
Generator/Transformer kustomization.yaml deployment.yaml kustomizationディレクトリ service.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml - service.yaml commonAnnotations: hashtag: “#cndt2021”
Kustomizationディレクトリの連結 • resourcesに他のKustomizationディレクトリを指定して連結 • 前段のKustomization処理の出⼒が次のKustomization処理の⼊⼒になる Kustomizeディレクトリは他のKustomize処理の結果を⼊⼒にできる 17 Generator/Transformer kustomization.yaml deployment.yaml
kustomizationディレクトリ service.yaml apiVersion: kustomize.(snip).v1beta1 kind: Kustomization resources: - path/to/another/dir Generator/Transformer kustomization.yaml deployment.yaml kustomizationディレクトリ service.yaml 参照 kustomization
Kustomizationディレクトリの連結 • 多段に連結してkustomizationの流れ(ストリーム)を作る • それぞれのkustomizationディレクトリが意味が意味のあるまとまりになる – e.g., プロダクションクラスタに適⽤する差分のセット ⼀種のストリーム処理でありつつ意味のあるまとまりに分けることもできる 18
参照 kustomization.yaml deployment.yaml service.yaml Generator/Transformer kustomization.yaml Generator/Transformer kustomization.yaml Generator/Transformer kustomization.yaml deployment.yaml service.yaml Generator/Transformer kustomization.yaml Generator/Transformer kustomization
⽬次 1. イントロダクション 2. Kustomizeの仕組みを知ろう 3. ディレクトリ構成の考え⽅ 4. Kustomizeプラグインを活⽤しよう 5.
⼤規模manifest群をリファクタリングするコツ 6. まとめ 1
• Kustomizeはkustomizationの連結(ストリーム)が実装の中⼼ • ストリームの流れを設計したあと、各々のkustomizationファイルの 意味から逆算してディレクトリ構成を当てはめると良い • ストリームの流れを決めるには以下を意識する ディレクトリ構成の考え⽅ ストリームの流れを起点に考える 20
ü 開始点 ü 分岐と合流 ü 終点 base/ overlay/ overlay/hoge
ストリームの開始点 • ストリームの開始点の選択肢 – ローカルに置いたmanifestファイル (kustomization.yamlのresourcesのファイル) – 他のリポジトリにあるmanifestファイルやkustomizationディレクトリ、Helm Chart ⼊⼒となるKRMリソースを決めるところ。複数の種類が指定できる
21 kustomization.yaml deployment.yaml kustomizationディレクトリ service.yaml resourcesでローカル ファイルを指定 kustomization.yaml kustomizationディレクトリ some-input.yaml kustomization.yaml some-input-chart resourcesでファイル、 ディレクトリを指定 HelmInfrationGeneratorで チャートを指定 • ローカル • リモート
ストリームの分岐と合流 • 分岐: prod, stgなど環境ごとの差分を作るときに、環境ごとに分岐する • 合流: 共通リソースを複数箇所に取り⼊れて利⽤する Kustomizationディレクトリを⾊々につなぎ合わせて⽬的のmanifestを得る 22
kustomization.yaml deployment.yaml 入力(アプリ) service.yaml resources kustomization.yaml kustomization.yaml kustomization.yaml rbac.yaml 入力(RBAC系) resources kustomization.yaml kustomization.yaml アプリのProduction用の差分 アプリのDevelopment用の差分 分 岐 合 流 合 流 Production用の最終出力 Development用の最終出力
ストリームの終点 • 終点ではapplyしたい単位に集約しておく – resourcesに複数のkustomizationディレクトリを指定してこれを⾏う – CDツールが持っている機能や、運⽤⽅針に沿った単位を考える CDツールでkustomize buildを実⾏してクラスタにapplyする 23
kustomization.yaml kustomization.yaml kustomization.yaml kustomization.yaml resourcesで複数のkustomization ディレクトリを指定 > kustoize build_ > kubectl apply_ CDツール Kubernetes クラスタ
2 Kustomizationディレクトリの意味を意識してディレクトリのパスを決めていく ストリームができたらディレクトリ配置を考えてみる kustomization.yaml deployment.yaml service.yaml resources kustomization.yaml rbac.yaml resources
base/ app/ rbac/ prod/ kustomization.yaml kustomization.yaml app/ rbac/ kustomization.yaml dev/ kustomization.yaml kustomization.yaml app/ rbac/ kustomization.yaml prod用パイプライン Kubernetesクラスタ (production) dev用パイプライン Kubernetesクラスタ (development)
ディレクトリ設計におけるその他のコツ • 個々のKustomizeディレクトリの意味を意識する – 途中のKustomizeディレクトリでもkustomize buildして意味があるmanifestを出 ⼒されるようにする – きれいに意味が分かれていると、分岐の枝を⾜して追加の拡張を⼊れるなど、 再利⽤性、メンテナンス性がよくなる
• 何も変更しないKustomizeディレクトリがあっても良い – resourcesを書いてストリームをつなぐだけのディレクトリ – 「Development環境向けのmanifest(何も変わってないけど)」ことを意味す るKustomizeディレクトリ 2
⽬次 1. イントロダクション 2. Kustomizeの仕組みを知ろう 3. ディレクトリ構成の考え⽅ 4. Kustomizeプラグインを活⽤しよう 5.
⼤規模manifest群をリファクタリングするコツ 6. まとめ 2
Kustomizeプラグインとは • BuiltinのGenerator/Transformerではできない加⼯を⾏える – e.g., ConfigMap内にインラインで書いた設定ファイルを加⼯したい • kustomize buildだけでmanifestを作れるというUXを壊さない –
独⾃スクリプトを被せてしまうとmanifestを出⼒するときに追加の⼿順が必要 • 加⼯処理のロジックに集中できる – ⼊出⼒や呼び出しはKustomizeの任せ、お作法に合わせてロジックを書けば良い Kustomizeプラグイン ≒ Generator/Transformerの⾃作 27 kustomization.yaml すごい 処理
Kustomizeプラグインの実装⽅法 • Containerized KRM Functions – KRMの加⼯、追加処理をGoで実装してコンテナ化しておく • Exec KRM
Functions – KRMの加⼯、追加処理を任意の実⾏バイナリに実装する 2 【参考】以下はDEPRECATEDとなっているため本セッションでは詳しくは触れません • Legacy exec plugins • Exec KRM Functionsと同様だが、実⾏バイナリの呼び出し時の⼊⼒フォーマットに違いがある。 シェルスクリプトとの相性が良く、発表者的には⼀番これが好き • Legacy Go plugins • GeneratorPlugin/TransformerPluginインターフェースを実装したロジックを、Go⾔語のプラグイン機 構を利⽤して組み込む。ビルドが壊れやすくて⾟いのなんのって
Kustomizeプラグインの作っていく流れ 1. プラグインの呼び出し⽅法を定義した設定ファイル(KRM)を⽤意 – 呼び出すプラグインやそれに与えるパラメータを指定 2. kustomization.yaml内で上の設定ファイルを指定 3. プラグインの実装を⽤意 –
実装⽅法に合わせて以下を実施 2 • Containerized KRM Functions – kyamlライブラリを使ってリソースの追 加・加⼯処理を実装 – Dockerfile出⼒などコンテナ化の⽀援も kyamlライブラリがしてくれる • Exec KRM Functions – 任意⾔語でリソースの追加・加⼯を実装 – リソースの⼊出⼒は標準⼊出⼒を利⽤
ConfigMap内のファイルを加⼯するプラグインの例 - 1/4 • まずkustomization.yamlのgeneratorまたはtransformer配下にプラグインの呼 び出し⽅法を定義したファイルを指定 3 apiVersion: kustomize.config.k8s.io/v1beta1 kind:
Kustomization configMapGenerator: - name: example-properties files: - example.properties transformers: - replace-foo-with-bar.yaml kustomization.yaml foo=@@foo@@ example.properties kustomizeはインラインのファイルを加⼯する機能がないのでプラグインでこれをやってみる
ConfigMap内のファイルを加⼯するプラグインの例 - 2/4 • replace-foo-with-bar.yamlで呼び出すプラグインと⼊⼒に与えるパラ メータを指定 – annotationで実⾏バイナリを指定 – spec配下に⼊⼒パラメータを指定
3 apiVersion: hhiroshell.github.com kind: SedTransformer metadata: name: replace-foo-with-bar annotations: config.Kubernetes.io/function: | exec: path: ../plugins/sedtransformer.sh spec: replacements: foo: bar replace-foo-with-bar.yaml
ConfigMap内のファイルを加⼯するプラグインの例 - 3/4 • プラグインを実装する – Exec KRM Functionsでは⾔語は問わない •
実⾏可能なファイルができればよい – ⼊出⼒はstdin/outを使う • ⼊⼒は加⼯元のリソースやパラメータを含む 構造化された情報(KRM) – items 以下に加⼯前のリソース – functionConfig.spec以下に⼊⼒パラメータ • 加⼯後のリソースをstdoutに出⼒する 3 apiVersion: config.kubernetes.io/v1 kind: ResourceList functionConfig: apiVersion: hhiroshell.github.com/v1 kind: sedTransformer metadata: name: replace-foo-with-bar spec: replacements foo: bar items: - apiVersion: v1 kind: ConfigMap metadata: name: example-properties-82cbkgc849 data: example.properties: |- foo=@@foo@@ プラグインに渡される入力(ResourceList)の例
ConfigMap内のファイルを加⼯するプラグインの例 - 4/4 • プラグインの実装を書く 3 #!/bin/bash # 標準入力からResourceListを読み込む。itemsに加工前のリソース、.functionConfig.specにパラメータが入っている resourceList=$(cat)
items=$(echo "$resourceList" | yq e '.items' - ) replacements=$(echo "$resourceList" | yq e '.functionConfig.spec.replacements' - ) # リソース毎にループして、sedを実行していく for i in `seq 0 $(expr $(echo "$items" | yq e ". | length" - ) - 1)`; do item=$(echo "$items" | yq e ".[$i]" - ) for key in $(echo "$replacements" | yq e ". | keys" - | yq e ".[]" - ); do item=$(echo "$item" | sed -e "s/@@$key@@/"$(echo "$replacements" | yq e ".$key" - )"/g") done # 加工したリソースは標準出力にそのまま吐き出す echo "$item" echo "---" done
kustomize buildを実⾏する • プラグインを利⽤するときはkustomize build実⾏時に所定のフラグを つける必要がある 3 $ kustomize build
--enable-alpha-plugins --enable-exec ./path/to/kustomize/dir apiVersion: v1 data: example.properties: |- foo=bar kind: ConfigMap metadata: name: example-properties-82cbkgc849 Exec KRM Functions以外のプラグインを使う場合の⼿順については、公式ドキュメントを参照 してください。 • https://kubectl.docs.kubernetes.io/guides/extending_kustomize/ ※ Exec KRM Functionsの場合のフラグ
【参考】Containerized KRM FunctionsとExec KRM Functions • 複雑なロジックを組んだり、外部システム連携など⾼度な機能を使 うならContainerized KRM Functions
• ⼿軽にKustomizeの不⾜を補うならExec KRM Functions w/ Shell Script 3 種別 実装⽅法 Pros Cons Containerized KRM Functions KRMの加⼯、追加処理 をGoで実装してコンテ ナ化しておく • Go⾔語 + kyamlライブラリ により、複雑なロジックや 外部システム連携を記述し やすい • プラグイン⾃体のビルドが必 須 • CD環境でkustomizeを実⾏する ときDocker in Dockerが必要 Exec KRM Functions KRMの加⼯、追加処理 を任意の実⾏バイナリ に実装する • 任意の⾔語で実装できる • Shell Scriptを使うなどして、 幅広い環境で動作するプラ グインが作れる • ビルド不要で動作するプラ グインが作れる • リソースの⼊出⼒に標準⼊出 ⼒を利⽤するので、リソース の取り回しの実装に慣れが要 る
おすすめのプラグインの使い所 • インラインドキュメントの加⼯ – ⽂字列置換 – ⾏挿⼊ • yamlのアンカー、エイリアスの展開 →
2021年9⽉末に標準で対応可能に • Helm Chartの取り込み → 2021年春にビルトインのプラグインに追加 • nameやnamespaceが違うが中⾝がほぼ同じリソースを複数作る – Listリソース + アンカー/エイリアス(後述)で対応できないならアリ これでかゆいところにも⼿が届く… 36
【おまけ】Listリソース + アンカー/エイリアスの利⽤例 • xxxListという名前で複数のリソースを配 列に含めて1枚のyamlにできる • 1枚のyamlになるので、アンカー/エイリ アスを使ってDRYに書ける •
Kustomizeの⼊⼒としてアンカー/エイリ アス⼊りのmanifestを使うには、 kustomize v4.4.0+ が必要 同内容のリソースを複数作るときに特に有効 37 apiVersion: v1 kind: PodList items: - apiVersion: v1 kind: Pod metadata: name: busybox-00 spec: &spec containers: - name: busybox image: busybox command: ["/bin/sh", "-c"] args: ["while true; do echo '#CNDT2021' && sleep 1; done"] - apiVersion: v1 kind: Pod metadata: name: busybox-01 spec: *spec
Kustomizeプラグインを使う上での注意点 • manifestの開発体験を損なわないように注意 – kustomize buildするためにプラグインをビルドしたり実⾏環境を⽤意したりす るのは、できればやらないほうが良い • ビルド環境や実⾏環境を⽤意した環境でしか動かない。環境によってkustomize buildに失敗
したり、動作が異なったりしかねない • CDに組み込むのが⼤変になる – Exec KRM Functions + Shell Scriptで実現できないかをまず考える • プラグインのメンテナンス性も意識しよう – プラグインが「秘伝のスクリプト」化しないように注意 やりすぎ注意…! 38
⽬次 1. イントロダクション 2. Kustomizeの仕組みを知ろう 3. ディレクトリ構成の考え⽅ 4. Kustomizeプラグインを活⽤しよう 5.
⼤規模manifest群をリファクタリングするコツ 6. まとめ 3
リファクタリングするmanifest - 1/2 • 管理対象のKubernetesクラスタ群 – 合計16クラスタ、8種のバリエーション(4環境、2クラスタ種別) – 約20コンポーネントを各クラスタにデプロイ –
バリエーション毎にデプロイするコンポーネントや各コンポーネントの設定 が異なる 4 Development Staging Production-1 Production-2 x1 x3 x1 x3 x1 x3 x1 x3 Type A Type B 全クラスタのmanifestを1リポジトリで管理
リファクタリングするmanifest - 2/2 • リファクタリング前のコードの内訳 – yamlだけで20,000+⾏ – Kustomizeではできない(と思われていた)環境差分を作るために独⾃の Pythonスクリプトを利⽤
4 language files code YAML 290 20,194 Markdown 12 1,307 Jinja 6 499 Python 2 236 Shell Script 1 59 XML 3 22 pip requirements 1 6
リファクタリング前の課題(ほんの⼀例) • ディレクトリの切り⽅が統⼀されてない – それだけでは意味をなさないリソースが単独で置かれていたり – 依存し合わないリソースが同じディレクトリにあったり • 共通部分と差分をうまく切り出せてない –
baseが複数ディレクトリに分かれている...! – overlayの⽅に同じことを全部書いてる • 独⾃の拡張 – Kustomizeの機能不⾜(と思われていた)を補うための複数の独⾃スクリプト • e.g., ⽂字列の置き換え、内容がほぼ同じだが名前が異なるリソースを複数作成 ...etc 地道な改善では追いつかないと判断し、抜本的に作り変えることに 42
manifestリファクタリングのベストプラクティス 1. 少数の開始点から終点まで完成されたストリームから始める 2. 1本のストリームを1コンポーネントに対応付ける 3. 移⾏期間の運⽤のこともあらかじめ考えておく 4. kubectl diffを使ってクラスタとの差分を確認しながらリファク
タする 5. nameとnamespaceは変えない 6. ビルトインの機能でできないことはKustomizeプラグインで 4
少数の開始点から終点まで完成されたストリームから始める • 開始点から終点まで成⽴するapply可能なストリームをまず作る – 最低限動くものから始める • リファクタリングを進める段取りに沿って数を増やしていく – プロトタイプングの時点では1, 2本
– 検証時点では1クラスタ分 4 課題の 具体化と 整理 プロトタイピング 整理の⽅ 針の共有 検証 実施
1本のストリームを1コンポーネントに対応付ける • “1コンポーネント”の例 – Ingressコントローラー、ログ収集エージェント、アプリAなど – そのコンポーネントを動かすためのすべてのリソース(workload, discovery, rbac...)⼀式を1ストリームで扱う •
1本のストリームでkustomize buildしたときに意味のある単位の manifestを出⼒できるようにする – 1本のストリームで意味をなし、かつ他のストリームと依存しない • コンポーネント単位のスコープで⽇々改善できるようになる 4
component-x/ ※ でき上がったもの 4 component-y/ component-z/ base/ Type-A/ Type-B/ component-x/
component-y/ component-z/ dev/ Type-A/ component-α/ component-z’/ Type-B/ staging/ dev/Type A クラスタ kustomization.yaml dev/Type A パイプライン kustomization.yaml dev/Type B パイプライン dev/Type B クラスタ 一部コンポーネント は外部リポジトリ から取得 component-α/ Type-A/ Type A,Bで共通のものは BからAを参照 component-z’/ 同時にapplyするため Typeごとに集約 環境ごとに分岐
移⾏期間の運⽤のこともあらかじめ考えておく • ある程度の規模になると⼀朝⼀⼣でできることではなくなってくる • リファクタ中は新旧2種類のmanifestが共存する – リファクタリングが済んだクラスタから、CDのmanifest取得先を切り替え – リファクタ中のクラスタ以外は、この取組みの期間中でも新規リリースして いた
4 base/ prod/ staging/ overlay/ dev/ base/ prod/ staging/ overlay/ new/ dev/ base/ prod/ staging/ new/ dev/ base/ prod/ staging/ dev/ base/ リファクタリング前 新旧共存期 すべて新構成に移行 new/ディレクトリを 削除して完成!
kubectl diffを使ってクラスタとの差分を確認しながら作業する • 少し⼤胆な構成変更もdiffをチェックすれば安⼼してできる – ストリーム単位(=コンポーネント単位で)で kustomize build + kubectl
diffしながらmanifestを編集していく • diffを⾒やすくするツールも活⽤するとなお良い – kubectl neat diff: diffの表⽰からmanagedFieldsを除外してくれる – colordiff: ⾊をつけてdiffを表⽰してくれる 4 $ kustomize build ./path/to/kustomize/dir | kubectl diff - | colordiff
4 kubectl neat diff + colordiff を利⽤したdiffの出⼒例 diff -uN /var/folders/7m/r1f0b69d3cjdj_hmz2t5dgchyl05r1/T/LIVE-020772465/v1.Pod.quantum-sandbox.busybox-00
/var/folders/7m/r1f0b69d3cjdj_hmz2t5dgchyl05r1/T/MERGED-814475548/v1.Pod.quantum-sandbox.busybox-00 --- /var/folders/7m/r1f0b69d3cjdj_hmz2t5dgchyl05r1/T/LIVE-020772465/v1.Pod.quantum-sandbox.busybox-00 2021-10-21 19:49:35.000000000 +0900 +++ /var/folders/7m/r1f0b69d3cjdj_hmz2t5dgchyl05r1/T/MERGED-814475548/v1.Pod.quantum-sandbox.busybox-00 2021-10-21 19:49:35.000000000 +0900 @@ -14,7 +14,7 @@ command: - /bin/sh - -c - image: busybox:stable + image: busybox:1.33.1 name: busybox resources: limits: diff -uN /var/folders/7m/r1f0b69d3cjdj_hmz2t5dgchyl05r1/T/LIVE-020772465/v1.Pod.quantum-sandbox.busybox-01 /var/folders/7m/r1f0b69d3cjdj_hmz2t5dgchyl05r1/T/MERGED-814475548/v1.Pod.quantum-sandbox.busybox-01 --- /var/folders/7m/r1f0b69d3cjdj_hmz2t5dgchyl05r1/T/LIVE-020772465/v1.Pod.quantum-sandbox.busybox-01 2021-10-21 ...(snip)...
nameとnamespaceは変えない • これを変えるとそのリソースは新規作成となるのでdiffのチェックが効か なくなる • Namespace, Nameの変更は全体の構成を変え終わってから、スコープを 絞ってやる 5 ビルトインの機能でできないことはKustomizeプラグインで
• 独⾃の加⼯をKustomizeプラグイン以外の⼿段で作らない • Exec KRM Functionsをシェルスクリプトで書くのがおすすめ – ⼤抵の環境でプラグインのビルドなどの⼿間なく kustomize build ⼀発でmanifestが出 ⼒できる – メンテナンスが属⼈化しにくい
yaml 58%減達成 • ⽬に⾒えてライン数を削減 • Pythonスクリプト依存が解消してスッキリ 5 language files code
YAML 290 20,194 Markdown 12 1,307 Jinja 6 499 Python 2 236 Shell Script 1 59 XML 3 22 pip requirements 1 6 language files code YAML 264 8,437 Markdown 6 1,164 Jinja 0 0 Python 0 0 Shell Script 0 0 XML 3 22 pip requirements 0 0 Properties 21 791 Before After
⽬次 1. イントロダクション 2. Kustomizeの仕組みを知ろう 3. ディレクトリ構成の考え⽅ 4. Kustomizeプラグインを活⽤しよう 5.
⼤規模manifest群をリファクタリングするコツ 6. まとめ 5
いかがでしたか? • こんなことを話しました… – Kustomizeはkustomizatinディレクトリの連結と Generator/Transformerを軸に設計されている – ストリームの流れを設計してからディレクトリ構 成を考えよう –
Kustomizeプラグインをうまく活⽤しよう – 実際にリファクタリングする上でのコツ x 6 Kustomizeと仲良くなれそうでしょうか 53 yamlエンジニア Kustomize Kustomize is マジ God
Fin. 5
Appendix. 参考⽂献 5
【参考⽂献】 • Kustomizeの公式ドキュメント – The Kustomization File • https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/ –
Extending Kustomize • https://kubectl.docs.kubernetes.io/guides/extending_kustomize/ – Containerized KRM Functions • https://kubectl.docs.kubernetes.io/guides/extending_kustomize/containerized_krm_functions/ – Exec KRM functions • https://kubectl.docs.kubernetes.io/guides/extending_kustomize/exec_krm_functions/ • GitHubリポジトリ – The Kubernetes Resource Model (KRM) • https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/resource- management.md – Kustomize • https://github.com/kubernetes-sigs/kustomize 5