我正在开发一个图表,但其中有一个错误 -
imagePullSecrets
属性放置不正确。当我尝试通过安装它时
helm install ./mychart
放错位置的元素被简单地忽略了,我想知道出了什么问题。
当我这么做的时候
helm template ./mychart | kubectl apply --dry-run -f -
它改为打印:
error: error validating "STDIN": error validating data: ValidationError(Deployment.spec.template.spec.containers[0]): unknown field "imagePullSecrets" in io.k8s.api.core.v1.Container
这清楚地表明出了什么问题。我不确定它是否与耕耘机对扩展模板的实际作用相匹配。
但是如果我只是做一个
helm install --dry-run --debug ./mychart
它只是显示展开的模板,看起来还不错。
那么如何正确验证我的所有模板是否与 helm 对应的模式匹配?
您可以通过
helm lint ./mychart
对图表进行 lint,如果发现问题,应该打印以下内容:
$ helm lint ./mychart
==> Linting ./mychart
[ERROR] Chart.yaml: version is required
[INFO] Chart.yaml: icon is recommended
Error: 1 chart(s) linted, 1 chart(s) failed
参见头盔棉绒。
使用kubeconform。
helm template ./mychart | kubeconform -strict
如果您有 CRD,您可能需要使用
kubeconform -ignore-missing-schemas
。我建议提供架构版本:kubeconform -kubernetes-version 1.18
。
建议:专门化你的图表并验证它们。示例如下。
简单:
helm template --set some.key="val" | kubeconform -strict
复杂:
VALUES_FILE=$(cat << EOF
some:
key: "val"
another:
key:
another: "val"
EOF
)
# It is important to quote "$VALUES_FILE" to ensure line breaks and indentation are preserved
echo "$VALUES_FILE" | helm template -f - | kubeconform -strict
为了避免 Helm Chart 安装失败,我建议在本地或/和 CI 管道中遵循以下顺序:
如果 linter 遇到会导致图表失败的事情 安装时,它会发出[ERROR]消息。
运行helm template,测试图表是否能成功本地渲染。虽然一旦发生 helm->kubernetes api 服务器交互,安装仍然可能失败,但它仍然提供良好的质量检查。
渲染图表后,使用
kubeval
(不支持 CRD)或 kubeconform
(支持 CRD)验证图表的 Kubernetes 清单是否符合 Kubernetes 架构:
helm template [chart_name] . | kubeval
hostPath
,等等):helm unittest [chart_name] [chart_name]
我在博客中总结了如何测试 Helm Charts。
我强烈建议使用以下 2 种解决方案的组合。
使用values.schema.json在values.yaml文件上强加一个结构。
示例:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"properties": {
"image": {
"description": "Container Image",
"properties": {
"repo": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"type": "object"
},
"name": {
"description": "Service name",
"type": "string"
},
"port": {
"description": "Port",
"minimum": 0,
"type": "integer"
},
"protocol": {
"type": "string"
}
},
"required": [
"protocol",
"port"
],
"title": "Values",
"type": "object"
}
(!) 此模式将应用于值以对其进行验证。调用以下任何命令时都会发生验证:
helm install
helm upgrade
helm lint
helm template
为了向验证添加条件 - 请阅读此处。
(*) 进一步阅读:好文章。
在某些情况下,使用条件时
values.schema.json
中的代码可能可读性较差,或者我们希望在验证中使用更动态的逻辑。
在这种情况下,我们可以创建一个
validations.yaml
文件(有些供应商更喜欢使用 .tpl
文件)并使用 go templates 添加验证逻辑。
示例:
如果特定功能(启用后)需要 IP 或 DNS:
some_feature:
enabled: true
ip:
dns:
验证逻辑可以显式编写:
{{- if .Values.some_feature.enabled -}}
{{- if and (not .Values.some_feature.ip ) (not .Values.some_feature.dns ) -}}
When some_feature is enabled, ip or dns must be given.
{{- end -}}
{{- end -}}
(*) 这个逻辑也可以使用 json-schema if-else 语句 来编写,但可能可读性较差。
(**) 考虑将所有验证放在
/tests
或 /validations
文件夹下,其中所有测试都分为单独的文件(如单元测试)。