name: kustomize-generators user-invocable: false description: 当使用Kustomize为Kubernetes配置管理生成ConfigMaps和Secrets时使用。 allowed-tools: [Bash, Read]
Kustomize 生成器
掌握使用Kustomize生成器生成ConfigMap和Secret,用于管理应用程序配置、凭据和环境特定设置,无需手动创建YAML文件。
概述
Kustomize生成器可以从字面量、文件和环境文件自动创建ConfigMaps和Secrets。生成的资源在名称中包含内容哈希值,当配置更改时实现自动滚动更新。
ConfigMap 生成器基础
字面量值
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: app-config
literals:
- DATABASE_URL=postgresql://localhost:5432/mydb
- LOG_LEVEL=info
- CACHE_ENABLED=true
- MAX_CONNECTIONS=100
- TIMEOUT_SECONDS=30
生成的 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-8g2h5m9k7t
data:
DATABASE_URL: postgresql://localhost:5432/mydb
LOG_LEVEL: info
CACHE_ENABLED: "true"
MAX_CONNECTIONS: "100"
TIMEOUT_SECONDS: "30"
基于文件的生成
# kustomization.yaml
configMapGenerator:
- name: app-config
files:
- application.properties
- config/database.conf
- config/logging.yml
包含文件:
# application.properties
server.port=8080
server.host=0.0.0.0
app.name=MyApplication
app.version=1.0.0
# config/database.conf
max_connections = 100
shared_buffers = 256MB
effective_cache_size = 1GB
# config/logging.yml
level: info
format: json
outputs:
- stdout
- file: /var/log/app.log
命名文件
configMapGenerator:
- name: app-config
files:
- config.properties=application.properties
- db.conf=config/database.conf
- log.yml=config/logging.yml
生成的 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-9m4k8h2f6d
data:
config.properties: |
server.port=8080
server.host=0.0.0.0
app.name=MyApplication
app.version=1.0.0
db.conf: |
max_connections = 100
shared_buffers = 256MB
effective_cache_size = 1GB
log.yml: |
level: info
format: json
outputs:
- stdout
- file: /var/log/app.log
环境文件
configMapGenerator:
- name: app-config
envs:
- .env
- config/.env.production
包含文件:
# .env
DATABASE_URL=postgresql://localhost:5432/mydb
REDIS_URL=redis://localhost:6379
LOG_LEVEL=info
# config/.env.production
DATABASE_URL=postgresql://prod-db:5432/mydb
REDIS_URL=redis://prod-redis:6379
LOG_LEVEL=warn
MONITORING_ENABLED=true
混合源
configMapGenerator:
- name: app-config
literals:
- APP_NAME=MyApp
- APP_VERSION=1.0.0
files:
- application.properties
envs:
- .env
Secret 生成器基础
字面量值
secretGenerator:
- name: app-secrets
type: Opaque
literals:
- database-password=super-secret-password
- api-key=1234567890abcdef
- jwt-secret=my-jwt-secret-key
生成的 Secret:
apiVersion: v1
kind: Secret
metadata:
name: app-secrets-2f6h8k9m4t
type: Opaque
data:
database-password: c3VwZXItc2VjcmV0LXBhc3N3b3Jk
api-key: MTIzNDU2Nzg5MGFiY2RlZg==
jwt-secret: bXktand0LXNlY3JldC1rZXk=
基于文件的 Secrets
secretGenerator:
- name: tls-secret
type: kubernetes.io/tls
files:
- tls.crt=certs/server.crt
- tls.key=certs/server.key
Docker Registry Secret
secretGenerator:
- name: docker-registry
type: kubernetes.io/dockerconfigjson
files:
- .dockerconfigjson=docker-config.json
包含 docker-config.json:
{
"auths": {
"registry.example.com": {
"username": "myuser",
"password": "mypassword",
"email": "myemail@example.com",
"auth": "bXl1c2VyOm15cGFzc3dvcmQ="
}
}
}
SSH 密钥 Secret
secretGenerator:
- name: ssh-keys
type: Opaque
files:
- id_rsa=keys/id_rsa
- id_rsa.pub=keys/id_rsa.pub
生成器行为
创建行为(默认)
configMapGenerator:
- name: app-config
behavior: create
literals:
- KEY=value
创建新的 ConfigMap。如果已存在则失败。
替换行为
configMapGenerator:
- name: app-config
behavior: replace
literals:
- KEY=new-value
完全替换现有 ConfigMap。如果不存在则失败。
合并行为
# base/kustomization.yaml
configMapGenerator:
- name: app-config
literals:
- LOG_LEVEL=info
- CACHE_ENABLED=true
- DATABASE_URL=localhost
# overlays/production/kustomization.yaml
configMapGenerator:
- name: app-config
behavior: merge
literals:
- LOG_LEVEL=warn
- DATABASE_URL=prod-db.example.com
生成的 ConfigMap 合并值:
data:
LOG_LEVEL: warn # 被覆盖
CACHE_ENABLED: "true" # 来自 base
DATABASE_URL: prod-db.example.com # 被覆盖
高级生成器模式
多环境配置
# base/kustomization.yaml
configMapGenerator:
- name: app-config
literals:
- APP_NAME=MyApp
- CACHE_ENABLED=true
- TIMEOUT=30
files:
- application.properties
# overlays/development/kustomization.yaml
configMapGenerator:
- name: app-config
behavior: merge
literals:
- LOG_LEVEL=debug
- DEBUG_MODE=true
- DATABASE_URL=postgresql://dev-db:5432/mydb
# overlays/production/kustomization.yaml
configMapGenerator:
- name: app-config
behavior: merge
literals:
- LOG_LEVEL=error
- DEBUG_MODE=false
- DATABASE_URL=postgresql://prod-db:5432/mydb
- RATE_LIMIT_ENABLED=true
多文件配置
configMapGenerator:
- name: nginx-config
files:
- nginx.conf
- mime.types
- conf.d/default.conf
- conf.d/ssl.conf
- conf.d/upstream.conf
应用程序配置包
configMapGenerator:
- name: app-bundle
literals:
- APP_NAME=MyApp
- APP_VERSION=1.0.0
files:
- app-config.json
- feature-flags.yml
- rate-limits.json
envs:
- .env.production
包含文件:
// app-config.json
{
"server": {
"port": 8080,
"host": "0.0.0.0"
},
"database": {
"pool_size": 20,
"timeout": 5000
}
}
# feature-flags.yml
features:
new_ui: true
beta_features: false
metrics: true
// rate-limits.json
{
"global": 1000,
"per_user": 100,
"burst": 50
}
来自外部文件的 Secrets
secretGenerator:
- name: database-credentials
files:
- username=secrets/db-username.txt
- password=secrets/db-password.txt
- name: api-keys
files:
- stripe-key=secrets/stripe-api-key.txt
- sendgrid-key=secrets/sendgrid-api-key.txt
- twilio-key=secrets/twilio-api-key.txt
TLS 证书包
secretGenerator:
- name: tls-certificates
type: kubernetes.io/tls
files:
- tls.crt=certs/server.crt
- tls.key=certs/server.key
- ca.crt=certs/ca-bundle.crt
生成器选项
禁用名称后缀哈希
configMapGenerator:
- name: app-config
options:
disableNameSuffixHash: true
literals:
- KEY=value
生成的 ConfigMap 名称:app-config(无哈希)
使用场景:
- 不应触发滚动更新的静态引用
- 外部系统引用的资源
- 调试的稳定端点
不可变 ConfigMaps
configMapGenerator:
- name: app-config
options:
immutable: true
literals:
- KEY=value
生成的 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-8g2h5m9k7t
immutable: true
data:
KEY: value
标签和注解
configMapGenerator:
- name: app-config
options:
labels:
app: myapp
environment: production
version: v1.0.0
annotations:
config.kubernetes.io/description: "应用程序配置"
config.kubernetes.io/owner: "平台团队"
literals:
- KEY=value
使用生成的资源
从 ConfigMap 加载环境变量
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
spec:
containers:
- name: myapp
envFrom:
- configMapRef:
name: app-config
特定键作为环境变量
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: DATABASE_URL
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
从 ConfigMap 挂载卷
volumes:
- name: config
configMap:
name: app-config
items:
- key: application.properties
path: app.properties
- key: logging.yml
path: logging.yml
containers:
- name: myapp
volumeMounts:
- name: config
mountPath: /etc/config
readOnly: true
Secrets 作为环境变量
envFrom:
- secretRef:
name: app-secrets
env:
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: database-password
Secrets 作为卷挂载
volumes:
- name: secrets
secret:
secretName: app-secrets
items:
- key: database-password
path: db-password
mode: 0400
containers:
- name: myapp
volumeMounts:
- name: secrets
mountPath: /etc/secrets
readOnly: true
真实世界示例
Web 应用程序配置
# base/kustomization.yaml
configMapGenerator:
- name: webapp-config
literals:
- SESSION_TIMEOUT=3600
- CSRF_ENABLED=true
- CORS_ENABLED=false
files:
- nginx.conf
- app.properties
secretGenerator:
- name: webapp-secrets
literals:
- session-secret=changeme
- csrf-token-secret=changeme
resources:
- deployment.yaml
- service.yaml
# overlays/production/kustomization.yaml
resources:
- ../../base
configMapGenerator:
- name: webapp-config
behavior: merge
literals:
- SESSION_TIMEOUT=7200
- CORS_ENABLED=true
- CORS_ORIGINS=https://example.com,https://www.example.com
- RATE_LIMIT_ENABLED=true
- RATE_LIMIT_REQUESTS=1000
files:
- nginx.conf=nginx-production.conf
secretGenerator:
- name: webapp-secrets
behavior: replace
files:
- session-secret=secrets/session-secret.txt
- csrf-token-secret=secrets/csrf-secret.txt
微服务配置
configMapGenerator:
# 用户服务配置
- name: user-service-config
literals:
- SERVICE_NAME=user-service
- PORT=8080
- METRICS_PORT=9090
files:
- config/user-service.yml
# 订单服务配置
- name: order-service-config
literals:
- SERVICE_NAME=order-service
- PORT=8081
- METRICS_PORT=9091
files:
- config/order-service.yml
# 支付服务配置
- name: payment-service-config
literals:
- SERVICE_NAME=payment-service
- PORT=8082
- METRICS_PORT=9092
files:
- config/payment-service.yml
secretGenerator:
- name: user-service-secrets
literals:
- jwt-secret=user-jwt-secret
- database-password=user-db-password
- name: payment-service-secrets
literals:
- stripe-api-key=sk_test_123
- webhook-secret=whsec_123
数据库配置
configMapGenerator:
- name: postgres-config
files:
- postgresql.conf
- pg_hba.conf
literals:
- POSTGRES_DB=myapp
- POSTGRES_MAX_CONNECTIONS=200
- POSTGRES_SHARED_BUFFERS=256MB
secretGenerator:
- name: postgres-secrets
literals:
- postgres-password=super-secret-password
- replication-password=repl-password
- name: postgres-init-scripts
files:
- init.sql=scripts/init-db.sql
- create-tables.sql=scripts/schema.sql
Redis 配置
configMapGenerator:
- name: redis-config
files:
- redis.conf
literals:
- REDIS_PORT=6379
- REDIS_MAXMEMORY=2gb
- REDIS_MAXMEMORY_POLICY=allkeys-lru
secretGenerator:
- name: redis-secrets
literals:
- redis-password=redis-secure-password
监控配置
configMapGenerator:
- name: prometheus-config
files:
- prometheus.yml
- alerts/rules.yml
- alerts/recording-rules.yml
- name: grafana-config
files:
- grafana.ini
- datasources/prometheus.yml
- dashboards/app-dashboard.json
secretGenerator:
- name: grafana-secrets
literals:
- admin-password=grafana-admin-password
- smtp-password=smtp-password
应用程序功能标志
configMapGenerator:
- name: feature-flags
files:
- feature-flags.json
literals:
- FEATURE_NEW_UI=true
- FEATURE_BETA_API=false
- FEATURE_DARK_MODE=true
- FEATURE_SOCIAL_LOGIN=true
包含 feature-flags.json:
{
"features": {
"new_ui": {
"enabled": true,
"rollout_percentage": 100
},
"beta_api": {
"enabled": false,
"rollout_percentage": 0
},
"dark_mode": {
"enabled": true,
"rollout_percentage": 100
},
"social_login": {
"enabled": true,
"providers": ["google", "github"]
}
}
}
生成器与变换器
configMapGenerator:
- name: app-config
literals:
- LOG_LEVEL=info
# 应用变换器
commonLabels:
app: myapp
namePrefix: prod-
namespace: production
结果:在命名空间 production 中生成名为 prod-app-config-8g2h5m9k7t 的 ConfigMap,带有标签 app: myapp。
测试生成的资源
# 构建并查看生成的 ConfigMap
kustomize build . | grep -A 20 "kind: ConfigMap"
# 构建并保存到文件
kustomize build . > generated.yaml
# 验证生成的资源
kustomize build . | kubectl apply --dry-run=client -f -
# 与集群比较
kustomize build . | kubectl diff -f -
# 应用生成的资源
kubectl apply -k .
# 查看生成的 ConfigMap
kubectl get configmap -l app=myapp
# 描述生成的 ConfigMap
kubectl describe configmap app-config-8g2h5m9k7t
# 查看 ConfigMap 数据
kubectl get configmap app-config-8g2h5m9k7t -o yaml
何时使用此技能
使用 kustomize-generators 技能当您需要:
- 从字面量、文件或环境文件生成 ConfigMaps
- 为凭据、API 密钥或证书生成 Secrets
- 配置更改时自动触发 Pod 滚动更新
- 使用合并行为管理环境特定配置
- 为稳定配置创建不可变 ConfigMaps
- 从多个源生成配置包
- 从证书文件创建 TLS secrets
- 为私有注册表生成 Docker registry secrets
- 跨环境管理应用程序功能标志
- 创建数据库连接配置
- 生成监控和可观测性配置
- 一致管理微服务配置
- 为 Git 操作创建 SSH 密钥 secrets
- 动态生成应用程序属性文件
- 管理限速和节流配置
最佳实践
- 使用生成器替代静态 ConfigMap/Secret YAML 文件
- 利用哈希后缀实现配置更改时的自动 Pod 滚动更新
- 在覆盖层使用 behavior: merge 覆盖特定键
- 将敏感文件存储在版本控制之外,在生成器中引用
- 仅在必要时使用 disableNameSuffixHash 以确保稳定性
- 逻辑上合理时,在单个生成器中组合字面量、文件和 envs
- 对不应更改的 ConfigMaps 使用 immutable: true
- 为生成的资源应用标签和注解以便跟踪
- 在 ConfigMaps 中使用命名文件语法自定义键名
- 在生产中从文件而不是字面量生成 Secrets
- 对 TLS 证书 secrets 使用 type: kubernetes.io/tls
- 在 kustomization.yaml 的注释中记录生成器行为
- 应用前使用 kustomize build 测试生成的输出
- 使用 envFrom 加载整个 ConfigMaps 作为环境变量
- 将 ConfigMaps 挂载为卷用于基于文件的配置
- 对敏感环境变量使用特定键引用
- 挂载 secrets 为卷时使用 readOnly: true
- 在 secret 卷中为敏感文件使用 mode: 0400
- 为不同配置关注点生成单独的 ConfigMaps
- 使用一致的命名约定生成资源
- 使用 kubectl apply --dry-run 验证生成的资源
- 使用 kustomize edit add configmap 进行 CLI 更新
- 将生成器源文件与 kustomization.yaml 保存在同一目录中
- 使用 .gitignore 排除敏感生成器源文件
- 在 README 中记录所需的生成器源文件
常见陷阱
- 在字面量中硬编码敏感信息而不是使用外部文件
- 不使用哈希后缀,错过自动 Pod 滚动更新
- 将敏感生成器源文件提交到版本控制
- 使用 behavior: replace 当 merge 更合适时
- 应用前不测试生成的输出
- 更改配置时忘记更新生成器源文件
- 在文件引用中使用绝对路径而不是相对路径
- 不记录生成器需要哪些文件
- 在单个生成器中混合配置关注点
- 不使用标签跟踪生成的资源
- 忘记对稳定 ConfigMaps 设置 immutable: true
- 不必要地使用 disableNameSuffixHash
- 不验证生成资源名称在引用资源中
- 在部署中硬编码生成的资源名称
- 不使用 envFrom 加载整个 ConfigMaps
- 挂载 secrets 时不使用 readOnly: true
- 不为敏感卷挂载设置限制性文件模式
- 在覆盖层使用 create 行为导致冲突
- 不使用 type 字段用于专业 secrets(如 TLS、Docker)
- 更改生成器名称时忘记更新引用
- 未先在低环境中测试 behavior: merge
- 对大型配置块使用字面量而不是文件
- 不逻辑组织生成器源文件
- 忘记将新生成器源文件添加到版本控制
- 不在生成器中使用一致的键命名约定
- 应用生成器而不理解哈希后缀影响
- 不为团队成员记录生成器行为
- 对 secrets 使用明文文件而不是安全存储
- 不定期轮换生成的 secrets
- 忘记清理旧的生成的 ConfigMaps/Secrets