如何使用kubectl patch添加无重复的imagePullSecrets列表项?
避免kubectl patch重复添加imagePullSecrets条目
问题场景
当前默认ServiceAccount配置:
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 imagePullSecrets: - name: gcr-secret - name: awsecr-cred - name: dpr-secret - name: acr-secret kind: ServiceAccount metadata: creationTimestamp: "2022-11-18T20:21:13Z" name: default namespace: default resourceVersion: "10953591" uid: edcc687f-dbb5-472d-8847-b4dc29096b48
使用普通add类型的patch命令:
kubectl patch serviceaccount default --type=json -p '[{"op": "add", "path": "/imagePullSecrets/-", "value": {name: artifactory-credentials}}]'
首次执行可成功添加新密钥,但重复执行会生成重复条目:
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 imagePullSecrets: - name: gcr-secret - name: awsecr-cred - name: dpr-secret - name: acr-secret - name: artifactory-credentials - name: artifactory-credentials kind: ServiceAccount metadata: creationTimestamp: "2022-11-18T20:21:13Z" name: default namespace: default resourceVersion: "10957065" uid: edcc687f-dbb5-472d-8847-b4dc29096b48
解决方案
方案1:带条件检查的JSON Patch
利用JSON Patch的test操作作为前置验证,仅当目标密钥不存在时执行add:
kubectl patch serviceaccount default --type=json -p ' [ {"op": "test", "path": "/imagePullSecrets/[?(@.name == \"artifactory-credentials\")]", "value": null}, {"op": "add", "path": "/imagePullSecrets/-", "value": {"name": "artifactory-credentials"}} ]'
- 逻辑:
test操作尝试匹配指定名称的密钥,若匹配失败(即密钥不存在),后续add操作才会执行;若匹配成功,test通过,add不会执行。
方案2:Shell脚本前置检查(推荐)
结合kubectl和jq工具,先检查密钥是否存在,不存在再执行patch:
# 定义要添加的密钥名称 SECRET_NAME="artifactory-credentials" # 检查密钥是否已存在,不存在则执行patch if ! kubectl get serviceaccount default -o json | jq -e ".imagePullSecrets[] | select(.name == \"$SECRET_NAME\")" > /dev/null; then kubectl patch serviceaccount default --type=json -p "[{\"op\": \"add\", \"path\": \"/imagePullSecrets/-\", \"value\": {\"name\": \"$SECRET_NAME\"}}]" fi
- 依赖:Ubuntu系统可通过
sudo apt install jq安装jq工具。 - 优势:逻辑清晰,执行结果可控,适合自动化脚本场景。
方案3:Merge Patch(覆盖式更新)
直接定义完整的imagePullSecrets列表,覆盖原有配置(需包含所有需要保留的密钥):
kubectl patch serviceaccount default --type=merge -p ' { "imagePullSecrets": [ {"name": "gcr-secret"}, {"name": "awsecr-cred"}, {"name": "dpr-secret"}, {"name": "acr-secret"}, {"name": "artifactory-credentials"} ] }'
- 注意:此方式会替换原有
imagePullSecrets列表,必须包含所有需要保留的密钥,否则会丢失原有条目。
内容的提问来源于stack exchange,提问作者Geoff Alexander
相关产品推荐
相关产品推荐

