ConfigMap 验证
Tekton Pruner 使用 ValidatingWebhook 来确保 ConfigMap 在集群中创建或更新之前符合所需规范。本文档说明了验证的工作原理及必须满足的要求。
目录
Overview
pruner webhook 验证 ConfigMap 以:
- 强制执行必需的标签和命名规范
- 防止无效配置被应用
- 保护关键配置不被意外删除
- 确保命名空间级配置遵守全局边界
How Validation Works
验证 webhook 随 pruner 自动安装,拦截 ConfigMap 的 CREATE、UPDATE 和 DELETE 操作。它仅验证带有标签 app.kubernetes.io/part-of: tekton-pruner 的 ConfigMap,确保集群中的普通 ConfigMap 不受影响。
Validation Rules
1. 必需标签
所有 pruner ConfigMap 必须包含以下标签:
metadata:
labels:
app.kubernetes.io/part-of: tekton-pruner
pruner.tekton.dev/config-type: <global|namespace>
验证检查:
- 两个标签必须同时存在
app.kubernetes.io/part-of 必须等于 tekton-pruner
pruner.tekton.dev/config-type 必须是 global 或 namespace
错误示例:
Invalid pruner ConfigMap labels: ConfigMap must have label app.kubernetes.io/part-of=tekton-pruner
2. Selector 限制
重要: 选择器(matchLabels/matchAnnotations)仅支持命名空间级 ConfigMap(tekton-pruner-namespace-spec),不支持全局 ConfigMap。
有效示例 - 命名空间 ConfigMap 中的选择器:
apiVersion: v1
kind: ConfigMap
metadata:
name: tekton-pruner-namespace-spec
namespace: dev
labels:
app.kubernetes.io/part-of: tekton-pruner
pruner.tekton.dev/config-type: namespace
data:
ns-config: |
pipelineRuns:
- selector: # 合法 - 这是命名空间 ConfigMap
- matchLabels:
app: myapp
ttlSecondsAfterFinished: 1800
无效示例 - 全局 ConfigMap 中的选择器:
apiVersion: v1
kind: ConfigMap
metadata:
name: tekton-pruner-default-spec
namespace: tekton-pipelines
labels:
app.kubernetes.io/part-of: tekton-pruner
pruner.tekton.dev/config-type: global
data:
global-config: |
namespaces:
dev:
pipelineRuns:
- selector: # 验证失败
- matchLabels:
app: myapp
ttlSecondsAfterFinished: 1800
错误示例:
Invalid pruner configuration: global-config.namespaces.dev.pipelineRuns[0]:
selectors are NOT supported in global ConfigMap.
Use namespace-level ConfigMap (tekton-pruner-namespace-spec) instead
为何有此限制?
- 基于选择器的资源匹配需要在运行时访问资源的标签/注解
- 全局 ConfigMap 设计用于集群范围的默认配置,不适合资源特定匹配
- 命名空间 ConfigMap 提供了动态资源选择的正确作用域
另见: Resource Groups 中的选择器使用示例
3. 命名要求
全局配置:
- 名称: 必须为
tekton-pruner-default-spec(固定)
- 命名空间: 必须为
tekton-pipelines(或系统命名空间)
- 标签:
pruner.tekton.dev/config-type: global
命名空间配置:
- 名称: 必须为
tekton-pruner-namespace-spec(固定)
- 命名空间: 必须是用户命名空间(非系统或 tekton 命名空间)
- 标签:
pruner.tekton.dev/config-type: namespace
错误示例:
Global config must be named 'tekton-pruner-default-spec', got: my-custom-name
Namespace config must be named 'tekton-pruner-namespace-spec', got: pruner-config
3. 命名空间限制
禁止在以下命名空间创建命名空间级配置:
- 系统命名空间:
kube-*
- Tekton 命名空间:
tekton-pipelines、tekton-*
尝试在这些命名空间创建命名空间级配置将被拒绝。
错误示例:
Invalid pruner ConfigMap configuration: wrong config-type label or namespace combination
4. 配置内容验证
Webhook 验证配置数据,包括:
- 时间值: ttlSecondsAfterFinished 必须为非负数
- 历史限制: historyLimit、successfulHistoryLimit 和 failedHistoryLimit 必须为非负数,且若启用全局最大值限制,则不得超过全局最大值
- 选择器(仅限命名空间 ConfigMap):标签和注解选择器必须具有有效的键值对;名称选择器必须是有效的资源名称
注意: 选择器(pipelineRuns、taskRuns 数组中的 matchLabels/matchAnnotations)仅在命名空间级 ConfigMap 中处理,全局 ConfigMap 中忽略。
5. 删除保护
如果存在命名空间级配置,Webhook 会阻止删除全局配置。必须先删除所有命名空间配置后,才能删除全局配置。命名空间配置删除不受限制。
6. 全局配置强制执行
创建或更新命名空间级配置时,Webhook 会获取全局配置并验证命名空间值是否未超过全局最大值(如 maxTTLSecondsAfterFinished、maxHistoryLimit)。
常见验证错误
缺少标签错误
ConfigMap must have labels
解决方案: 为 ConfigMap 添加必需标签:
labels:
app.kubernetes.io/part-of: tekton-pruner
pruner.tekton.dev/config-type: global # 或 namespace
错误的配置类型错误
label pruner.tekton.dev/config-type must be 'global' or 'namespace', got: local
解决方案: 仅使用 global 或 namespace 作为 config-type 值。
错误的名称错误
Global config must be named 'tekton-pruner-default-spec', got: tekton-pruner-config
解决方案: 使用准确的名称:
- 全局:
tekton-pruner-default-spec
- 命名空间:
tekton-pruner-namespace-spec
超出全局限制错误
Invalid pruner configuration: namespace config ttlSecondsAfterFinished (172800) exceeds global maximum (86400)
解决方案: 将命名空间值降低至全局限制范围内,或请求管理员提高全局最大值。
删除被阻止错误
Cannot delete global config: 2 namespace config(s) still exist
解决方案: 先删除所有命名空间配置:
kubectl delete cm tekton-pruner-namespace-spec -n dev
kubectl delete cm tekton-pruner-namespace-spec -n staging
# 然后删除全局配置
kubectl delete cm tekton-pruner-default-spec -n tekton-pipelines
故障排除
验证 Webhook 状态
# 检查 webhook 配置
kubectl get validatingwebhookconfigurations tekton-pruner-validating-webhook
# 检查 webhook pod 和 service
kubectl get pods,svc -n tekton-pipelines -l app.kubernetes.io/component=webhook
# 查看 webhook 日志
kubectl logs -n tekton-pipelines -l app.kubernetes.io/component=webhook
测试验证
创建一个无效的 ConfigMap 以验证 webhook 是否正常工作:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: tekton-pruner-default-spec
namespace: tekton-pipelines
data:
global-config: |
ttlSecondsAfterFinished: 300
EOF
预期错误:admission webhook denied the request: Invalid pruner ConfigMap labels
绕过验证(不推荐)
警告: 绕过验证可能导致 pruner 行为配置错误,仅应在紧急情况下使用。
临时绕过验证步骤:
-
移除识别标签:
kubectl label cm tekton-pruner-default-spec -n tekton-pipelines \
app.kubernetes.io/part-of-
-
进行必要的更改
-
重新添加标签:
kubectl label cm tekton-pruner-default-spec -n tekton-pipelines \
app.kubernetes.io/part-of=tekton-pruner
注意: pruner 控制器不会处理没有正确标签的 ConfigMap。
最佳实践
- 从一开始就包含必需标签
- 严格遵守全局和命名空间配置的命名规范
- 先在非生产命名空间测试配置
- 仔细检查验证错误,明确需要修正的内容
- 发布新配置时监控 webhook 日志
- 删除全局配置前先删除所有命名空间配置