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.3k
20,000+行のmanifestをリファクタリングして分かったKustomizeの美しきアーキテクチャと拡張性 / Kustomize deep dive
#CNDT2021 で Kustomize の話をしたときの資料です。
hhiroshell
November 04, 2021
Tweet
Share
More Decks by hhiroshell
See All by hhiroshell
Architecting Kubernetes-Based Internal Developer Platforms: Essential Patterns and Practices
hhiroshell
0
73
Discover Your Tailored Platform Strategy with Real-World Practice
hhiroshell
1
190
Kubernetesでアプリの安定稼働と高頻度のアップデートを両立するためのプラクティス / Best Practices for Applications on Kubernetesto Achieve Both Frequent Updates and Stability
hhiroshell
10
3.7k
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
670
Cloud Native Developers JP (cndjp) のご紹介 / about cndjp
hhiroshell
0
180
KustomizeのHash Suffixがあってもいい感じにdiffが見られるkubectlプラグインを作った話 / about kubectl realname-diff
hhiroshell
0
1.8k
Other Decks in Technology
See All in Technology
Amplify Gen2 Deep Dive / バックエンドの型をいかにしてフロントエンドへ伝えるか #TSKaigi #TSKaigiKansai #AWSAmplifyJP
tacck
PRO
0
370
【Startup CTO of the Year 2024 / Audience Award】アセンド取締役CTO 丹羽健
niwatakeru
0
980
rootlessコンテナのすゝめ - 研究室サーバーでもできる安全なコンテナ管理
kitsuya0828
3
380
Making your applications cross-environment - OSCG 2024 NA
salaboy
0
180
Evangelismo técnico: ¿qué, cómo y por qué?
trishagee
0
360
OCI Vault 概要
oracle4engineer
PRO
0
9.7k
SREが投資するAIOps ~ペアーズにおけるLLM for Developerへの取り組み~
takumiogawa
1
150
エンジニア人生の拡張性を高める 「探索型キャリア設計」の提案
tenshoku_draft
1
120
Application Development WG Intro at AppDeveloperCon
salaboy
0
180
The Rise of LLMOps
asei
7
1.4k
Lexical Analysis
shigashiyama
1
150
Platform Engineering for Software Developers and Architects
syntasso
1
510
Featured
See All Featured
BBQ
matthewcrist
85
9.3k
Bash Introduction
62gerente
608
210k
Imperfection Machines: The Place of Print at Facebook
scottboms
265
13k
Thoughts on Productivity
jonyablonski
67
4.3k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Scaling GitHub
holman
458
140k
A designer walks into a library…
pauljervisheath
203
24k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
31
2.7k
Building Your Own Lightsaber
phodgson
103
6.1k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Done Done
chrislema
181
16k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
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