kustomize|kustomize 实践

缘起 在 kustomize 出现之前,Kubernetes 管理应用的方式主要是通过 Helm 或者上层 Paas 来完成。这些工具通常通过特定领域配置语言(DSL,如Go template、jsonnet) 来维护并管理应用,并且需要参数化模板方式(如 helm) 来自定义配置,这需要额外学习复杂的 DSL 语法及容易出错。
kustomize 是什么 kustomize 是 kubernetes 原生的配置管理,以无模板方式定制应用的配置。kustomize 使用 k8s 原生概念帮助创建并复用资源配置(YAML),允许用户以一个应用描述文件 (YAML 文件)为基础(Base YAML),然后通过 Overlay 的方式生成最终部署应用所需的描述文件。
kustomize 解决了什么痛点

  • 如何管理不同环境或不同团队的应用的 Kubernetes YAML 资源
  • 如何以某种方式管理不同环境的微小差异,使得资源配置可以复用,减少 copy and change 的工作量
  • 如何简化维护应用的流程,不需要额外学习模板语法
Kustomize 通过以下几种方式解决了上述问题:
  • kustomize 通过 Base & Overlays 方式方式维护不同环境的应用配置
  • kustomize 使用 patch 方式复用 Base 配置,并在 Overlay 描述与 Base 应用配置的差异部分来实现资源复用
  • kustomize 管理的都是 Kubernetes 原生 YAML 文件,不需要学习额外的 DSL 语法
官方示例 目标: 使用 kustomize 管理 stage、production 两个环境的 helloword 应用
前提
  • 两个不同的环境(演示、生产)
  • 一个 deployments 资源和 service 资源
  • 环境之间有不同的 replicas 或者 ConfigMap
最终文件结构
demo ├── base │├── configMap.yaml │├── deployment.yaml │├── kustomization.yaml │└── service.yaml └── overlays ├── production │├── deployment.yaml │└── kustomization.yaml └── staging ├── kustomization.yaml └── map.yaml

新建一个 Base 目录 这里使用官网的 helloWorld 的 YAML 资源文件作为示例,在 base 目录下新增几个 k8s YAML 资源文件,文件结构如下:
demo └── base ├── configMap.yaml ├── deployment.yaml ├── kustomization.yaml └── service.yaml

接下来看看 kustomization.yaml 配置文件中包含什么内容:
# filename: demo/base/kustomization.yaml commonLabels: app: helloresources: - deployment.yaml - service.yaml - configMap.yaml

这个文件声明了这些 YAML 资源(deployments、services、configmap 等)以及要应用于它们的一些自定义,如添加一个通用的标签。kustomization 还提供了namePrefix、commonAnnoations、images 等配置项
其他几个文件分别如下:
# filename: demo/base/configMap.yaml apiVersion: v1 kind: ConfigMap metadata: name: the-map data: altGreeting: "Good Morning!" enableRisky: "false"

# filename: demo/base/service.yaml kind: Service apiVersion: v1 metadata: name: the-service spec: selector: deployment: hello type: LoadBalancer ports: - protocol: TCP port: 8666 targetPort: 8080

# filename: demo/base/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: the-deployment spec: replicas: 3 selector: matchLabels: deployment: hello template: metadata: labels: deployment: hello spec: containers: - name: the-container image: monopole/hello:1 command: ["/hello", "--port=8080", "--enableRiskyFeature=$(ENABLE_RISKY)"] ports: - containerPort: 8080 env: - name: ALT_GREETING valueFrom: configMapKeyRef: name: the-map key: altGreeting - name: ENABLE_RISKY valueFrom: configMapKeyRef: name: the-map key: enableRisky

这时候,可以通过 kustomize build 命令来看完整的配置:
kustomize build demo/base

另外部署的时候可以直接使用下面的命令
# kubectl apply -k demo/base # 这种方式直接部署在集群中

build 出来的 YAML 每个资源对象上都会存在通用的标签 app: hello
下面为 build 结果:
apiVersion: v1 data: altGreeting: Good Morning! enableRisky: "false" kind: ConfigMap metadata: labels: app: hello name: the-map --- apiVersion: v1 kind: Service metadata: labels: app: hello name: the-service spec: ports: - port: 8666 protocol: TCP targetPort: 8080 selector: app: hello deployment: hello type: LoadBalancer --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: hello name: the-deployment spec: replicas: 3 selector: matchLabels: app: hello deployment: hello template: metadata: labels: app: hello deployment: hello spec: containers: - command: - /hello - --port=8080 - --enableRiskyFeature=$(ENABLE_RISKY) env: - name: ALT_GREETING valueFrom: configMapKeyRef: key: altGreeting name: the-map - name: ENABLE_RISKY valueFrom: configMapKeyRef: key: enableRisky name: the-map image: monopole/hello:1 name: the-container ports: - containerPort: 8080

创建 Overlays 创建一个 staging 和 production overlay,目录树结构如下所示:
demo ├── base │├── configMap.yaml │├── deployment.yaml │├── kustomization.yaml │└── service.yaml └── overlays ├── production └── staging

演示环境 kustomization 在 staging kustomization 文件中,定义一个新的名称前辍以及一些不同的标签
# filename: demo/overlays/staging/kustomization.yaml namePrefix: staging- commonLabels: variant: staging org: acmeCorporation commonAnnotations: note: Hello, I am staging! bases: - ../../base patchesStrategicMerge: - map.yaml

演示环境 patch 添加一个 ConfigMap 自定义把 base 中的 ConfigMap 中的 "_Good Morning!_" 变成 "Good Night!"
# 文件路径 demo/overlays/staging/map.yaml apiVersion: v1 kind: ConfigMap metadata: name: the-map data: altGreeting: "Have a pineapple!" enableRisky: "true"

生产环境 kustoimzation 在生产环境目录下,创建一个 kustomization.yaml 文件,定义不同的名称及标签
# filename: demo/overlays/production/kustomization.yaml namePrefix: production- commonLabels: variant: production org: acmeCorporation commonAnnotations: note: Hello, I am production! bases: - ../../base patchesStrategicMerge: - deployment.yaml

生产环境 patch 创建一个生产环境的 patch, 定义增加副本数量
# filename: demo/overlays/production/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: the-deployment spec: replicas: 10

部署不同环境
需要在演示环境部署应用,通过下面命令
kubectl apply -kdemo/overlays/staging

对比 base 、staging 生成的文件
kustomize build demo/base > /tmp/base.yaml kustomize build demo/overlays/staging > /tmp/staging.yaml vimdiff /tmp/base.yaml /tmp/staging.yaml

kustomize|kustomize 实践
文章图片

需要在生产环境部署应用,通过下面命令
kubectl apply -kdemo/overlays/production

对比 base 、production 生成的文件
kustomize build demo/base > /tmp/base.yaml kustomize build demo/overlays/production > /tmp/production.yaml vimdiff /tmp/base.yaml /tmp/production.yaml

kustomize|kustomize 实践
文章图片

【kustomize|kustomize 实践】参考
kustomize github 地址
kustomize 本文示例
kustomize 官方所有示例
kustomize 最简实践

    推荐阅读