Upgrade to Pro — share decks privately, control downloads, hide ads and more …

20,000+行のmanifestをリファクタリングして分かったKustomizeの美しきアーキテクチャと拡張性 / Kustomize deep dive

hhiroshell
November 04, 2021

20,000+行のmanifestをリファクタリングして分かったKustomizeの美しきアーキテクチャと拡張性 / Kustomize deep dive

#CNDT2021 で Kustomize の話をしたときの資料です。

hhiroshell

November 04, 2021
Tweet

More Decks by hhiroshell

Other Decks in Technology

Transcript

  1. 20,000+⾏のmanifestをリファクタリングして分かった
    Kustomizeの美しきアーキテクチャと拡張性
    @hhiroshell
    1

    View full-size slide

  2. 宣伝
    • 感染対策をしっかりやって遊舎⼯房に⾏きましょう
    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

    View full-size slide

  3. ⽬次
    1. イントロダクション
    2. Kustomizeの仕組みを知ろう
    3. ディレクトリ構成の考え⽅
    4. Kustomizeプラグインを活⽤しよう
    5. ⼤規模manifest群をリファクタリングするコツ
    6. まとめ
    3

    View full-size slide

  4. ⽬次
    1. イントロダクション
    2. Kustomizeの仕組みを知ろう
    3. ディレクトリ構成の考え⽅
    4. Kustomizeプラグインを活⽤しよう
    5. ⼤規模manifest群をリファクタリングするコツ
    6. まとめ
    4

    View full-size slide

  5. Kustomizeとは
    • manifestに差分だけを書いたパッチを当ててバリエーションを作る
    • 環境ごとの共通部分、差分を分けて管理するのに役⽴つ
    manifestをDRYに管理するためのツール
    5

    View full-size slide

  6. 6
    ⼀⾒わかりやすいようで、使ってみると…。
    Kustomizeに関するよくある感想
    なるほどなるほど。manifestの差分
    だけを書いてoverlayに置けばよいの
    ですね。直感的でいいですね!
    フィールドの部分⽂字列を置き換えた
    りはできないんだ? テンプレートっ
    ぽくは使えないんだな…。
    manifestが多いと
    overlayの中が散らかっ
    てくるな…。 なんかできないことが
    多いような?

    View full-size slide

  7. このセッションのゴール
    • Kustomizeの使いこなせるようになって
    今までのイメージを払拭してほしい…!!
    – Kustomizeの仕組みを理解して使いこなせる
    – いい感じにmanifest構造の設計ができる
    – いままでだったら諦めてたかゆいところに⼿が届
    いちゃう
    – Kustomize is マジ God
    Kustomizeと仲良くなろうー。
    7
    yamlエンジニア
    Kustomize

    View full-size slide

  8. ⽬次
    1. イントロダクション
    2. Kustomizeの仕組みを知ろう
    3. ディレクトリ構成の考え⽅
    4. Kustomizeプラグインを活⽤しよう
    5. ⼤規模manifest群をリファクタリングするコツ
    6. まとめ
    8

    View full-size slide

  9. kustomize build を実⾏したときに起きること
    ⼊⼒となるリソースに対して、複数の加⼯を施した結果を得る
    9
    入力
    出力
    KRMリソース
    KRMリソース
    kustomization.yaml
    リソースの追加・加工
    ?
    kustomization.yaml
    リソースの追加・加工
    ?
    • 複数のKRM(Kubernetes Resource Model)リソースを⼊⼒として、リ
    ソースの追加、加⼯(kustomization)が⾏われた結果を出⼒する
    – 追加、加⼯の内容はkustomization.yamlに宣⾔的に記述
    – 複数のkustomization.yamlを書いて繋げられる
    kustomization.yaml
    リソースの追加・加工
    ?

    View full-size slide

  10. 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

    View full-size slide

  11. kustomization処理の実体
    • Kustomizeに標準で備わって(Builtin)いるkustomzation機能は、全て
    GeneratorまたはTransformerの派⽣
    – コード的にはGeneratorPlugin / TransformerPluginというインターフェースの実
    装になっている
    • GeneratorとTransformer
    – Generatorはリソースの追加
    – Transformerは⼊⼒されたリソースの加⼯
    = GeneratorとTransformer
    11
    ResMap
    Generator/Transformer

    View full-size slide

  12. kustomization処理の連鎖的な実⾏
    • ResMap:
    – KRMリソースの集合体。Generator / Transformerによってリソースが追加、加
    ⼯される
    • Generator / Transformer:
    – ResMapを加⼯する処理
    複数のGenerator / Transformerによってmanifestが加⼯(kustomization)されていく
    12
    KRMリソース ResMap ResMap ResMap
    Generator/Transformer
    入力
    出力
    KRMリソース
    Generator/Transformer
    Generator/Transformer

    View full-size slide

  13. 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

    View full-size slide

  14. 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

    View full-size slide

  15. 【おまけ】おなじみの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-

    View full-size slide

  16. 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”

    View full-size slide

  17. 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

    View full-size slide

  18. 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

    View full-size slide

  19. ⽬次
    1. イントロダクション
    2. Kustomizeの仕組みを知ろう
    3. ディレクトリ構成の考え⽅
    4. Kustomizeプラグインを活⽤しよう
    5. ⼤規模manifest群をリファクタリングするコツ
    6. まとめ
    1

    View full-size slide

  20. • Kustomizeはkustomizationの連結(ストリーム)が実装の中⼼
    • ストリームの流れを設計したあと、各々のkustomizationファイルの
    意味から逆算してディレクトリ構成を当てはめると良い
    • ストリームの流れを決めるには以下を意識する
    ディレクトリ構成の考え⽅
    ストリームの流れを起点に考える
    20
    ü 開始点 ü 分岐と合流 ü 終点
    base/ overlay/ overlay/hoge

    View full-size slide

  21. ストリームの開始点
    • ストリームの開始点の選択肢
    – ローカルに置いた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で
    チャートを指定
    • ローカル • リモート

    View full-size slide

  22. ストリームの分岐と合流
    • 分岐: 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用の最終出力

    View full-size slide

  23. ストリームの終点
    • 終点では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
    クラスタ

    View full-size slide

  24. 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)

    View full-size slide

  25. ディレクトリ設計におけるその他のコツ
    • 個々のKustomizeディレクトリの意味を意識する
    – 途中のKustomizeディレクトリでもkustomize buildして意味があるmanifestを出
    ⼒されるようにする
    – きれいに意味が分かれていると、分岐の枝を⾜して追加の拡張を⼊れるなど、
    再利⽤性、メンテナンス性がよくなる
    • 何も変更しないKustomizeディレクトリがあっても良い
    – resourcesを書いてストリームをつなぐだけのディレクトリ
    – 「Development環境向けのmanifest(何も変わってないけど)」ことを意味す
    るKustomizeディレクトリ
    2

    View full-size slide

  26. ⽬次
    1. イントロダクション
    2. Kustomizeの仕組みを知ろう
    3. ディレクトリ構成の考え⽅
    4. Kustomizeプラグインを活⽤しよう
    5. ⼤規模manifest群をリファクタリングするコツ
    6. まとめ
    2

    View full-size slide

  27. Kustomizeプラグインとは
    • BuiltinのGenerator/Transformerではできない加⼯を⾏える
    – e.g., ConfigMap内にインラインで書いた設定ファイルを加⼯したい
    • kustomize buildだけでmanifestを作れるというUXを壊さない
    – 独⾃スクリプトを被せてしまうとmanifestを出⼒するときに追加の⼿順が必要
    • 加⼯処理のロジックに集中できる
    – ⼊出⼒や呼び出しはKustomizeの任せ、お作法に合わせてロジックを書けば良い
    Kustomizeプラグイン ≒ Generator/Transformerの⾃作
    27
    kustomization.yaml すごい
    処理

    View full-size slide

  28. Kustomizeプラグインの実装⽅法
    • Containerized KRM Functions
    – KRMの加⼯、追加処理をGoで実装してコンテナ化しておく
    • Exec KRM Functions
    – KRMの加⼯、追加処理を任意の実⾏バイナリに実装する
    2
    【参考】以下はDEPRECATEDとなっているため本セッションでは詳しくは触れません
    • Legacy exec plugins
    • Exec KRM Functionsと同様だが、実⾏バイナリの呼び出し時の⼊⼒フォーマットに違いがある。
    シェルスクリプトとの相性が良く、発表者的には⼀番これが好き
    • Legacy Go plugins
    • GeneratorPlugin/TransformerPluginインターフェースを実装したロジックを、Go⾔語のプラグイン機
    構を利⽤して組み込む。ビルドが壊れやすくて⾟いのなんのって

    View full-size slide

  29. Kustomizeプラグインの作っていく流れ
    1. プラグインの呼び出し⽅法を定義した設定ファイル(KRM)を⽤意
    – 呼び出すプラグインやそれに与えるパラメータを指定
    2. kustomization.yaml内で上の設定ファイルを指定
    3. プラグインの実装を⽤意
    – 実装⽅法に合わせて以下を実施
    2
    • Containerized KRM Functions
    – kyamlライブラリを使ってリソースの追
    加・加⼯処理を実装
    – Dockerfile出⼒などコンテナ化の⽀援も
    kyamlライブラリがしてくれる
    • Exec KRM Functions
    – 任意⾔語でリソースの追加・加⼯を実装
    – リソースの⼊出⼒は標準⼊出⼒を利⽤

    View full-size slide

  30. 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はインラインのファイルを加⼯する機能がないのでプラグインでこれをやってみる

    View full-size slide

  31. 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

    View full-size slide

  32. 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)の例

    View full-size slide

  33. 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

    View full-size slide

  34. 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の場合のフラグ

    View full-size slide

  35. 【参考】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を使うなどして、
    幅広い環境で動作するプラ
    グインが作れる
    • ビルド不要で動作するプラ
    グインが作れる
    • リソースの⼊出⼒に標準⼊出
    ⼒を利⽤するので、リソース
    の取り回しの実装に慣れが要

    View full-size slide

  36. おすすめのプラグインの使い所
    • インラインドキュメントの加⼯
    – ⽂字列置換
    – ⾏挿⼊
    • yamlのアンカー、エイリアスの展開 → 2021年9⽉末に標準で対応可能に
    • Helm Chartの取り込み → 2021年春にビルトインのプラグインに追加
    • nameやnamespaceが違うが中⾝がほぼ同じリソースを複数作る
    – Listリソース + アンカー/エイリアス(後述)で対応できないならアリ
    これでかゆいところにも⼿が届く…
    36

    View full-size slide

  37. 【おまけ】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

    View full-size slide

  38. Kustomizeプラグインを使う上での注意点
    • manifestの開発体験を損なわないように注意
    – kustomize buildするためにプラグインをビルドしたり実⾏環境を⽤意したりす
    るのは、できればやらないほうが良い
    • ビルド環境や実⾏環境を⽤意した環境でしか動かない。環境によってkustomize buildに失敗
    したり、動作が異なったりしかねない
    • CDに組み込むのが⼤変になる
    – Exec KRM Functions + Shell Scriptで実現できないかをまず考える
    • プラグインのメンテナンス性も意識しよう
    – プラグインが「秘伝のスクリプト」化しないように注意
    やりすぎ注意…!
    38

    View full-size slide

  39. ⽬次
    1. イントロダクション
    2. Kustomizeの仕組みを知ろう
    3. ディレクトリ構成の考え⽅
    4. Kustomizeプラグインを活⽤しよう
    5. ⼤規模manifest群をリファクタリングするコツ
    6. まとめ
    3

    View full-size slide

  40. リファクタリングする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リポジトリで管理

    View full-size slide

  41. リファクタリングする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

    View full-size slide

  42. リファクタリング前の課題(ほんの⼀例)
    • ディレクトリの切り⽅が統⼀されてない
    – それだけでは意味をなさないリソースが単独で置かれていたり
    – 依存し合わないリソースが同じディレクトリにあったり
    • 共通部分と差分をうまく切り出せてない
    – baseが複数ディレクトリに分かれている...!
    – overlayの⽅に同じことを全部書いてる
    • 独⾃の拡張
    – Kustomizeの機能不⾜(と思われていた)を補うための複数の独⾃スクリプト
    • e.g., ⽂字列の置き換え、内容がほぼ同じだが名前が異なるリソースを複数作成 ...etc
    地道な改善では追いつかないと判断し、抜本的に作り変えることに
    42

    View full-size slide

  43. manifestリファクタリングのベストプラクティス
    1. 少数の開始点から終点まで完成されたストリームから始める
    2. 1本のストリームを1コンポーネントに対応付ける
    3. 移⾏期間の運⽤のこともあらかじめ考えておく
    4. kubectl diffを使ってクラスタとの差分を確認しながらリファク
    タする
    5. nameとnamespaceは変えない
    6. ビルトインの機能でできないことはKustomizeプラグインで
    4

    View full-size slide

  44. 少数の開始点から終点まで完成されたストリームから始める
    • 開始点から終点まで成⽴するapply可能なストリームをまず作る
    – 最低限動くものから始める
    • リファクタリングを進める段取りに沿って数を増やしていく
    – プロトタイプングの時点では1, 2本
    – 検証時点では1クラスタ分
    4
    課題の
    具体化と
    整理
    プロトタイピング
    整理の⽅
    針の共有
    検証 実施

    View full-size slide

  45. 1本のストリームを1コンポーネントに対応付ける
    • “1コンポーネント”の例
    – Ingressコントローラー、ログ収集エージェント、アプリAなど
    – そのコンポーネントを動かすためのすべてのリソース(workload, discovery,
    rbac...)⼀式を1ストリームで扱う
    • 1本のストリームでkustomize buildしたときに意味のある単位の
    manifestを出⼒できるようにする
    – 1本のストリームで意味をなし、かつ他のストリームと依存しない
    • コンポーネント単位のスコープで⽇々改善できるようになる
    4

    View full-size slide

  46. 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ごとに集約
    環境ごとに分岐

    View full-size slide

  47. 移⾏期間の運⽤のこともあらかじめ考えておく
    • ある程度の規模になると⼀朝⼀⼣でできることではなくなってくる
    • リファクタ中は新旧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/ディレクトリを
    削除して完成!

    View full-size slide

  48. 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

    View full-size slide

  49. 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)...

    View full-size slide

  50. nameとnamespaceは変えない
    • これを変えるとそのリソースは新規作成となるのでdiffのチェックが効か
    なくなる
    • Namespace, Nameの変更は全体の構成を変え終わってから、スコープを
    絞ってやる
    5
    ビルトインの機能でできないことはKustomizeプラグインで
    • 独⾃の加⼯をKustomizeプラグイン以外の⼿段で作らない
    • Exec KRM Functionsをシェルスクリプトで書くのがおすすめ
    – ⼤抵の環境でプラグインのビルドなどの⼿間なく kustomize build ⼀発でmanifestが出
    ⼒できる
    – メンテナンスが属⼈化しにくい

    View full-size slide

  51. 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

    View full-size slide

  52. ⽬次
    1. イントロダクション
    2. Kustomizeの仕組みを知ろう
    3. ディレクトリ構成の考え⽅
    4. Kustomizeプラグインを活⽤しよう
    5. ⼤規模manifest群をリファクタリングするコツ
    6. まとめ
    5

    View full-size slide

  53. いかがでしたか?
    • こんなことを話しました…
    – Kustomizeはkustomizatinディレクトリの連結と
    Generator/Transformerを軸に設計されている
    – ストリームの流れを設計してからディレクトリ構
    成を考えよう
    – Kustomizeプラグインをうまく活⽤しよう
    – 実際にリファクタリングする上でのコツ x 6
    Kustomizeと仲良くなれそうでしょうか
    53
    yamlエンジニア
    Kustomize
    Kustomize is マジ God

    View full-size slide

  54. Appendix.
    参考⽂献
    5

    View full-size slide

  55. 【参考⽂献】
    • 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

    View full-size slide