kustomize で kubernetes マニフェストを管理する
オブジェクトをカスタマイズできる Kustomize について紹介します。kustomization.yaml には専用のフィールドである secretGenerator, ConfigMapGenerator, ImageTagTransformer, LabelTransformer, NamespaceTransformer, PatchesStrategicMerge 等があり、それを直接定義しプラグインを暗黙的にトリガーする方法と、kustomization.yaml にgenerators もしくは transformers フィールドを介して 別の yaml に定義した内容を明示的にトリガーする方法があります。違いは前者はプラグインの引数のほとんどがデフォルトになる点、後者は完全なプラグインの引数の指定が可能な点です。
www.aimhighergg.com は Kubernetes で稼働していて、各オブジェクトは manifest で管理しています。 kustomize で環境ごとにカスタマイズして deploy を行っています。 www.aimhighergg.com のコンセプトはできる限り kustomization.yaml に変更箇所を集約し、環境ごとの管理を容易にすることです。
https://github.com/AbeYuki/aimhighergg-com
以下が www.aimhighergg.com の kustomization 周りの manifest の抜粋です。
コンテナイメージ、レプリカカウント、ストレージ、イングレスの設定が一目でわかるようになっており、変更も kustomization.yaml で完結します。 LabelTransformer, PrefixSuffixTransformer については transformers フィールでに yaml 明示的にトリガーし詳細な設定を記載しています。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: www-aimhighergg-com
generatorOptions:
disableNameSuffixHash: true
bases:
- ../../base
secretGenerator:
- name: kustomize-password
files:
- password=password.txt
- name: docker-registry
files:
- '.dockerconfigjson=docker-registry.json'
type: kubernetes.io/dockerconfigjson
configMapGenerator:
- name: template-config
literals:
- WORDPRESS_DB_HOST=backend-db01
- WORDPRESS_DB_NAME=wordpress
- WORDPRESS_DB_USER=wordpress
- MYSQL_DATABASE_WP=wordpress
- MYSQL_USER_WP=wordpress
- MYSQL_USER_MW=wordpress
- MYSQL_DATABASE_MW=tips_wiki
transformers:
- transformer-label.yaml
- transformer-suffixprefix.yaml
images:
- name: frontend-app01
newName: wordpress
newTag: "6.0.0-php8.1-apache"
- name: backend-db01
newName: mariadb
newTag: "10.5"
- name: frontend-app02
newName: registry.gitlab.com/aimhighergg/docker-registry/mediawiki-wiki
newTag: "1.36.3"
- name: backend-db02
newName: mariadb
newTag: "10.5"
- name: frontend-static01
newName: registry.gitlab.com/aimhighergg/docker-registry/portfolio
newTag: "1.0"
- name: frontend-static02
newName: registry.gitlab.com/aimhighergg/docker-registry/maintenance
newTag: "1.0"
replicas:
- name: frontend-app01
count: 2
- name: backend-db01
count: 1
- name: frontend-app02
count: 1
- name: backend-db02
count: 1
- name: frontend-static01
count: 2
- name: frontend-static02
count: 1
patchesStrategicMerge:
- |-
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: frontend-app01
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: longhorn
volumeMode: Filesystem
- |-
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-tls
spec:
ingressClassName: nginx
tls:
- hosts:
- www.aimhighergg.com
secretName: tls-secret
rules:
- host: www.aimhighergg.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: frontend-app01
port:
number: 80
transformers については LabelTransformer, PrefixSuffixTransformer で metadata 以外の PATH へ設定を反映しています。kind でどの種類のオブジェクトを対象にするか指定し、 path で対象の name を指定して反映するようにしています。 PrefixSuffixTransformer の留意点としては、metadata/name は kind を指定せずに全てに反映するようにしています。それにともなって、データベースの sevice 名も反映されるため、 wordpress の WORDPRESS_DB_HOST 変数にも PrefixSuffix を付与しすることで環境が変わった際もデータベースと接続できるようにしています。
apiVersion: builtin
kind: LabelTransformer
metadata:
name: label-transformer
labels:
environment: production
app.kubernetes.io/managed-by: github
app.kubernetes.io/created-by: controller-manager
fieldSpecs:
- path: metadata/labels
create: true
- path: spec/selector/matchLabels
kind: Deployment
create: true
- path: spec/template/metadata/labels
kind: Deployment
create: true
apiVersion: builtin
kind: PrefixSuffixTransformer
metadata:
name: prefixsuffix-transformer
prefix: www-aimhighergg-com-
suffix: "-001"
fieldSpecs:
- path: metadata/name
- path: spec/template/spec/containers/name
kind: Deployment
- path: spec/acme/privateKeySecretRef/name
kind: ClusterIssuer
- path: spec/tls/secretName
kind: Ingress
- path: data/WORDPRESS_DB_HOST
kind: ConfigMap
- path: metadata/annotations/cert-manager.io\/cluster-issuer
kins: Ingress
以上、 www.aimhighergg.com の Kustomize 環境の紹介でした。
一般的なウェブアプリケーション構成の場合、1つテンプレートを作成してしまえば流用できるため、最初につくりこんでしまえば非常に yaml の作成が楽になります。
是非、kustomize を活用して Kubernetes Life を楽しみましょう。
以降については kustomization.yaml に記載する場合とプラグインを利用する場合の紹介です。
PrefixSuffixTransformer
全てのリソースの prefix suffix に名前を付与する
namePrefix: alices-
nameSuffix: -v2
apiVersion: builtin
kind: PrefixSuffixTransformer
metadata:
name: not-important-to-example
prefix: baked-
suffix: -pie
fieldSpecs:
- path: metadata/name
AnnotationTransformer
全てのリソースにアノテーションを追加
commonAnnotations:
oncallPager: 800-555-1212
apiVersion: builtin
kind: AnnotationsTransformer
metadata:
name: not-important-to-example
annotations:
app: myApp
greeting/morning: a string with blanks
fieldSpecs:
- path: metadata/annotations
create: true
SecretGenerator
引数リストの各エントリにより、1つのシークレットリソースが作成される
secretGenerator:
- name: app-tls
files:
- secret/tls.cert
- secret/tls.key
type: "kubernetes.io/tls"
- name: app-tls-namespaced
# you can define a namespace to generate
# a secret in, defaults to: "default"
namespace: apps
files:
- tls.crt=catsecret/tls.cert
- tls.key=secret/tls.key
type: "kubernetes.io/tls"
- name: env_file_secret
envs:
- env.txt
type: Opaque
- name: secret-with-annotation
files:
- app-config.yaml
type: Opaque
options:
annotations:
app_config: "true"
labels:
app.kubernetes.io/name: "app2"
apiVersion: builtin
kind: SecretGenerator
metadata:
name: my-secret
namespace: whatever
behavior: merge
envs:
- a.env
- b.env
files:
- obscure=longsecret.txt
literals:
- FRUIT=apple
- VEGETABLE=carrot
ConfigMapGenerator
generatorOptions は
この option フィールドでは、生成されたインスタンスにラベルや注釈を追加したり、そのインスタンスの名前サフィックスハッシュを個別に無効化したりできる。
また、ここで追加されたラベルと注釈は、カスタマイズファイルの generatorOptions フィールドに関連付けられたグローバルオプションによって上書きされない
ただし、bool値の動作によっては、グローバルな generatorOptins フィールドが、disableNameSuffixHash: true を指定していた場合ローカルに対して上書きはされない。
behavior: [create|replace|merge] でオーバレイの既存の変更・置換ができる。
generatorOptions:
labels:
fruit: apple
configMapGenerator:
- name: my-java-server-props
behavior: merge
files:
- application.properties
- more.properties
- name: my-java-server-env-vars
literals:
- JAVA_HOME=/opt/java/jdk
- JAVA_TOOL_OPTIONS=-agentlib:hprof
options:
disableNameSuffixHash: true
labels:
pet: dog
- name: dashboards
files:
- mydashboard.json
options:
annotations:
dashboard: "1"
labels:
app.kubernetes.io/name: "app1"
apiVersion: builtin
kind: ConfigMapGenerator
metadata:
name: mymap
envs:
- devops.env
- uxteam.env
literals:
- FRUIT=apple
- VEGETABLE=carrot
ReplicaCountTransformer
レプリカ数の変更
replicas:
- name: deployment-name
count: 5
apiVersion: builtin
kind: ReplicaCountTransformer
metadata:
name: not-important-to-example
replica:
name: myapp
count: 23
fieldSpecs:
- path: spec/replicas
create: true
kind: Deployment
- path: spec/replicas
create: true
kind: ReplicationController
ImageTagTransformer
tag の変更
containers:
- name: mypostgresdb
image: postgres:8
- name: nginxapp
image: nginx:1.7.9
- name: myapp
image: my-demo-app:latest
- name: alpine-app
image: alpine:3.7
image のパスとタグを変更
images:
- name: postgres
newName: my-registry/my-postgres
newTag: v1
- name: nginx
newTag: 1.8.0
- name: my-demo-app
newName: my-app
- name: alpine
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
apiVersion: builtin
kind: ImageTagTransformer
metadata:
name: not-important-to-example
imageTag:
name: nginx
newTag: v2
LabelTransformer
すべてのリソースとセレクターにラベルを追加
commonLabels:
someName: someValue
owner: alice
app: bingo
apiVersion: builtin
kind: LabelTransformer
metadata:
name: not-important-to-example
labels:
app: myApp
env: production
fieldSpecs:
- path: metadata/labels
create: true
NamespaceTransformer
すべてのリソースに名前空間を追加
namespace: my-namespace
apiVersion: builtin
kind: LabelTransformer
metadata:
name: not-important-to-example
labels:
app: myApp
env: production
fieldSpecs:
- path: metadata/labels
create: true
PatchesJson6902
pathフィールドは、JSONパッチファイルの相対ファイルパス
- op: add
path: /some/new/path
value: value
- op: replace
path: /some/existing/path
value: new value
patchesJson6902:
- target:
version: v1
kind: Deployment
name: my-deployment
path: add_init_container.yaml
- target:
version: v1
kind: Service
name: my-service
path: add_service_annotation.yaml
インラインも可能
patchesJson6902:
- target:
version: v1
kind: Deployment
name: my-deployment
patch: |-
- op: add
path: /some/new/path
value: value
- op: replace
path: /some/existing/path
value: "new value"
plugin
apiVersion: builtin
kind: PatchJson6902Transformer
metadata:
name: not-important-to-example
target:
group: apps
version: v1
kind: Deployment
name: my-deploy
path: jsonpatch.json
PatchesStrategicMerge
このリストの各エントリは、相対ファイルパスか、部分的または完全なリソース定義に解決されるインラインコンテンツのいずれかである必要があり
kusomization.yaml
patchesStrategicMerge:
- service_port_8888.yaml
- deployment_increase_replicas.yaml
- deployment_increase_memory.yaml
インライン可能
patchesStrategicMerge:
- |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
image: nignx:latest
patches:
- path: patch.yaml
target:
group: apps
version: v1
kind: Deployment
name: deploy.*
labelSelector: "env=dev"
annotationSelector: "zone=west"
- patch: |-
- op: replace
path: /some/existing/path
value: new value
target:
kind: MyKind
labelSelector: "env=dev"
PatchTransformer
このリストの各エントリは、パッチとターゲットセレクタを含むパッチオブジェクトに解決される必要あり。
インライン可能。
patches:
- path: patch.yaml
target:
group: apps
version: v1
kind: Deployment
name: deploy.*
labelSelector: "env=dev"
annotationSelector: "zone=west"
- patch: |-
- op: replace
path: /some/existing/path
value: new value
target:
kind: MyKind
labelSelector: "env=dev"
apiVersion: builtin
kind: PatchTransformer
metadata:
name: not-important-to-example
patch: '[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "nginx:latest"}]'
target:
name: .*Deploy
kind: Deployment