Jenkins流水线注入证书至YAML文件格式异常导致服务器加载失败
问题
使用Jenkins流水线构建应用时,需将Jenkins凭证管理器中的多证书内容注入YAML文件,但注入后服务器无法正常读取证书。具体情况如下:
参考YAML结构
edge: [...] certificates: ingress: name: certs key: | ------BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- [...]
原始证书格式(多证书)
-----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE-----
用于注入的Python脚本
import yaml import os with open("file.yaml") as f: y = yaml.load(f) y["edge"]["certificates"]["ingress"]["key"] = os.getenv("KEY_CERT") with open("file.yaml", "w") as f: yaml.dump(y, f)
Shell执行命令
python -c 'exec """\nimport yaml\nimport os\n\nwith open("file.yaml") as f:\n y = yaml.load(f)\n y["edge"]["certificates"]["ingress"]["key"] = os.getenv("KEY_CERT")\n\nwith open("file.yaml", "w") as f:\n yaml.dump(y, f)\n"""'
错误信息
服务器日志提示:
edge:10808: Failed to load trusted CA certificates from /etc/proxy/tls/sidecar/ca.crt
注入后服务器上的证书格式混乱(多余空格、换行异常):
-----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT TEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXTTEXT -----END CERTIFICATE-----
需解决:
- 证书格式混乱是否影响服务器加载?
- 如何修复当前注入脚本?
- 有无更可靠的证书注入YAML的方法?
注:最初证书硬编码在YAML中,生产环境出于安全考虑需从Jenkins凭证动态注入。
解决方案
1. 格式混乱确实会影响证书加载
绝大多数证书解析工具对格式要求严格,多余空格、异常换行都会导致解析失败。服务器日志明确提示加载失败,而服务器上的证书存在大量多余空格,这就是问题根源。
2. 修复Python注入脚本
问题出在yaml.dump的默认行为:它会自动处理字符串的换行和缩进,破坏证书原始格式。需调整脚本,确保证书以YAML块字符串形式写入,保留原始格式:
修复后的Python脚本
import yaml import os from yaml.representer import SafeRepresenter # 自定义字符串表示器,保留块格式 def str_presenter(dumper, data): if '\n' in data: return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|') return dumper.represent_scalar('tag:yaml.org,2002:str', data) SafeRepresenter.add_representer(str, str_presenter) with open("file.yaml") as f: # 使用safe_load替代load,避免安全风险 y = yaml.safe_load(f) cert_content = os.getenv("KEY_CERT") # 处理换行符,确保跨环境一致 cert_content = cert_content.replace('\r\n', '\n').strip() y["edge"]["certificates"]["ingress"]["key"] = cert_content with open("file.yaml", "w") as f: yaml.dump(y, f, default_flow_style=False, sort_keys=False)
关键调整点:
- 自定义
str_presenter,让含换行的字符串以|块格式写入YAML,保留原始换行 - 用
yaml.safe_load替代yaml.load,避免潜在代码注入风险 - 统一证书内容的换行符,适配不同环境的换行差异
- 添加
sort_keys=False防止YAML键被重新排序,破坏原有结构
3. 其他替代注入方法
方式一:Jenkins流水线用sed直接替换
在Jenkinsfile中用sed替换YAML中的占位符,无需解析YAML,避免格式问题:
pipeline { agent any environment { KEY_CERT = credentials('your-cert-credential-id') } stages { stage('Inject Cert') { steps { sh ''' # 先在YAML中设置占位符:key: __CERT_PLACEHOLDER__ sed -i "s/__CERT_PLACEHOLDER__/$(printf '%s' "$KEY_CERT" | sed 's/[&/]/\\\\&/g')/" file.yaml ''' } } } }
注意:需用sed 's/[&/]/\\\\&/g'转义证书中的特殊字符(如/)。
方式二:Kustomize(Kubernetes环境)
若应用部署在K8s上,可通过Kustomize的SecretGenerator管理证书,无需直接修改YAML:
- Jenkins中把证书写入临时文件:
sh 'echo "$KEY_CERT" > ca.crt'
- 创建
kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization secretGenerator: - name: ingress-certs files: - ca.crt resources: - your-deployment.yaml
- 在部署YAML中引用该Secret的内容即可。
内容的提问来源于stack exchange,提问作者Nishant
相关产品推荐
相关产品推荐

