Kustomize 设计理念与使用说明
一、设计理念
Kustomize 的设计理念是基于"基础配置 + 补丁"的模式,这里解释一下为什么需要在 base 目录下创建基础配置:
-
基础配置的重要性:
- base 目录下的配置是所有环境共享的基础配置
- 包含了服务最基本的定义和配置
- 确保了不同环境的配置一致性
-
环境差异管理:
- overlays 目录只存放与基础配置的差异部分
- 每个环境只需要关注自己特有的配置
- 避免了配置重复和维护困难
-
配置复用:
- 基础配置可以被多个环境复用
- 减少了重复配置的维护成本
- 确保了配置的一致性
-
如果只在 overlays 下创建配置的问题:
- 每个环境都需要维护完整的配置
- 配置变更需要在多个环境中同步修改
- 容易造成环境间的配置不一致
- 难以追踪配置的变化
base 中放置:
- 容器端口
- 资源限制
- 健康检查
- 基础标签
overlays 中放置:
- 环境变量
- 镜像版本
- 副本数量
- 特定注解
二、工作流
kustomization工作流方式
Kustomize 不是一个新工具,它自 2017 年以来一直在建设中,并在 1.14 版本中作为原生 kubectl 子命令引入。Kustomize 由 Google 和 Kubernetes 社区构建,符合 Kubernetes 使用 Kubernetes 对象定义配置文件和以声明方式管理这些配置的原则。Kustomize 配置对象称为 Kustomization,用于描述如何生成或转换其他 Kubernetes 对象。Kustomization 在名为 kustomization.yaml
的文件中以声明方式定义,此文件可由 Kustomize 本身生成和修改。
在 kustomize 中,可以定义常见、可重复使用的 kustomization(称为基础)并使用多个其他 kustomization(称为覆盖层)对其进行修补,这些 kustomization 可以选择性地覆盖基础中定义的设置以生成变体。然后,Kustomize 根据 kustomization 基础和覆盖层中定义的配置转换和生成资源,此过程称为融合或渲染。接下来,这些渲染资源会写入标准输出或文件,并保持原始 YAML 文件不变,以便许多不同的叠加层重复使用基础。
这种无模板方法在 Kustomization 库的易用性和可重用性方面非常强大。使用它你能够以几乎任何想要的方式自定义 Kubernetes 配置,而无需为每个单独的用例提供大量值。
二、Kustomize 支持众多的功能特性
字段 | 类型 | 解释 |
---|---|---|
namespace | string | 为所有资源添加名字空间 |
namePrefix | string | 此字段的值将被添加到所有资源名称前面 |
nameSuffix | string | 此字段的值将被添加到所有资源名称后面 |
labels | map[string]string | 要添加到所有资源和选择算符的标签 |
commonAnnotations | map[string]string | 要添加到所有资源的注解 |
resources | []string | 列表中的每个条目都必须能够解析为现有的资源配置文件 |
configMapGenerator | []configmapargs | 列表中的每个条目都会生成一个 ConfigMap |
secretGenerator | []secretargs | 列表中的每个条目都会生成一个 Secret |
generatorOptions | GeneratorOptions | 更改所有 ConfigMap 和 Secret 生成器的行为 |
bases | []string | 列表中每个条目都应能解析为一个包含 kustomization.yaml 文件的目录 |
patchesStrategicMerge | []string | 列表中每个条目都能解析为某 Kubernetes 对象的策略性合并补丁 |
patchesJson6902 | []patch | 列表中每个条目都能解析为一个 Kubernetes 对象和一个 JSON 补丁 |
vars | []var | 每个条目用来从某资源的字段来析取文字 |
images | []image | 每个条目都用来更改镜像的名称、标记与/或摘要,不必生成补丁 |
configurations | []string | 列表中每个条目都应能解析为一个包含 Kustomize 转换器配置 的文件 |
crds | []string | 列表中每个条目都应能够解析为 Kubernetes 类别的 OpenAPI 定义文件 |
二、目录结构说明
Kustomize-dc/
├── base/ # 基础配置目录
│ ├── backend/ # 后端服务基础配置
│ │ └── accounting-service/
│ ├── frontend/ # 前端服务基础配置
│ │ └── ybf-www-h5/
│ └── kustomization.yaml # 基础配置的kustomization文件
└── overlays/ # 环境特定配置目录├── prod/ # 生产环境配置│ ├── backend/│ ├── frontend/│ └── kustomization.yaml├── test/ # 测试环境配置└── dev/ # 开发环境配置
三、常用命令示例
- 查看生成的配置:
kubectl kustomize overlays/prod
- 应用配置到集群:
kubectl apply -k overlays/prod
- 删除已部署的资源:
kubectl delete -k overlays/prod
四、最佳实践建议
-
标签管理:
- 使用统一的标签体系
- 在base中定义基础标签
- 在overlays中添加环境特定标签
-
配置管理:
- 敏感配置使用Secret
- 环境变量使用ConfigMap
- 避免在base中包含环境特定的配置
-
补丁使用:
- 使用strategic merge patch进行配置覆盖
- 只在必要时使用json patch
- 保持补丁文件的简洁性
五、常见问题解答
-
Q: 如何处理不同环境的域名配置?
A: 在overlays中使用patch-ingress.yaml进行覆盖,如示例中的ybf-www-h5服务。 -
Q: 如何管理不同环境的标签?
A: 在base中定义通用标签,在overlays中使用labels字段添加环境标签。 -
Q: 如何处理配置文件的优先级?
A: Kustomize按照以下顺序应用配置:- base配置
- overlays中的补丁
- overlays中的资源
-
Q: 如何维护大型项目的配置?
A: 建议按照服务类型(前端/后端)和业务模块进行目录划分,保持清晰的层次结构。
六、配置示例
1. 基础服务配置示例
base/backend/accounting-service/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: accounting-service
spec:replicas: 1selector:matchLabels:app: accounting-servicetemplate:metadata:labels:app: accounting-servicespec:containers:- name: accounting-serviceports:- containerPort: 8080resources:limits:cpu: '1'memory: 2Girequests:cpu: 500mmemory: 1Gi
2. 环境特定配置示例
overlays/prod/backend/accounting-service/patch-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: accounting-service
spec:replicas: 3template:spec:containers:- name: accounting-serviceimage: your-registry/accounting-service:prodenv:- name: SPRING_PROFILES_ACTIVEvalue: prod
3. ConfigMap配置示例
base/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: app-config
data:application.properties: |server.port=8080spring.application.name=my-app
overlays/prod/patch-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: app-config
data:apollo_namespace: prodsw_agent_collector_backend_services: skywalking-oap.prod-ybf-mid:11800apollo_cluster: prodapollo_config_service: http://service-apollo-config-server.prod-ybf-mid:8080
4. Ingress配置示例
base/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: my-appannotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/ssl-redirect: 'false'
spec:rules:- host: example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: my-appport:number: 80
5. Kustomization文件示例
base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomizationresources:- deployment.yaml- service.yaml- ingress.yaml- configmap.yamllabels:- pairs:app.kubernetes.io/component: backendapp.kubernetes.io/name: my-appincludeSelectors: true
overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomizationresources:- ../../basenamespace: prodpatches:- path: patch-deployment.yaml- path: patch-configmap.yamllabels:- pairs:environment: prodincludeSelectors: true
这些示例展示了:
- 基础部署配置
- 环境特定的补丁
- ConfigMap的基础配置和环境特定配置
- Ingress配置
- Kustomization文件的组织方式
五、使用说明
前端项目部署
- 进入项目目录
- 执行 kustomize build overlays/prod/frontend/ybf-www-h5/ 生成 prod 环境服务的 yaml
- 执行 kustomize build overlays/prod/frontend/ 生成 prod 环境所有前端服务的 yaml
- 执行 kustomize build overlays/prod/ 生成 prod 环境所有服务的 yaml
后端项目部署
- 进入项目目录
- 执行 kustomize build overlays/prod/backend/accounting-service/ 生成 prod 环境服务的 yaml
- 执行 kustomize build overlays/prod/backend/ 生成 prod 环境所有后端服务的 yaml
- 执行 kustomize build overlays/prod/ 生成 prod 环境所有服务的 yaml
六、调试命令
使用 --load-restrictor 参数调试
kustomize build --load-restrictor LoadRestrictionsNone ./Kustomize-dc/overlays/prod
验证 yaml 语法
kustomize build ./Kustomize-dc/overlays/prod | kubectl apply --dry-run=client -f -
使用 --verbose 参数获取详细错误信息
kustomize build --verbose ./Kustomize-dc/overlays/prod
七、新服务添加说明
后端服务添加:
- 复制 base/backend/accounting-service 目录作为模板
- 复制 overlays/prod/backend/accounting-service 目录作为模板
- 修改所有文件中的服务名称
- 更新 base/backend/kustomization.yaml 添加新服务
前端服务添加:
- 复制 base/frontend/ybf-www-h5 目录作为模板
- 复制 overlays/prod/frontend/ybf-www-h5 目录作为模板
- 修改所有文件中的服务名称
- 更新 base/frontend/kustomization.yaml 添加新服务
八、优势
- 配置清晰可维护
- 环境差异一目了然
- 基础配置变更容易同步到所有环境
- 降低配置错误的风险
- 便于版本控制和审计