为什么Helm的tpl函数无法解析PrometheusRule中的$labels变量?
问题原因
你在PrometheusRule的annotations中定义的{{ $labels }}、{{ $value }}是Prometheus告警系统的内置运行时变量,是给Prometheus服务触发告警时解析使用的。
而你使用的Helm Chart模板中,对.Values.prometheusRule.rules整体使用了tpl函数做渲染:
rules: {{ tpl (toYaml .) $ | nindent 8 }}
helm template执行时,会把所有被{{ }}包裹的内容识别为Helm自身的模板语法尝试解析,但是Helm的渲染上下文中根本没有定义$labels、$value这两个变量,所以直接抛出了未定义变量的错误。
解决方案
只需要对Prometheus专属的模板变量做转义处理,让Helm渲染时跳过这些内容,渲染完成后保留完整的{{ }}结构留给Prometheus后续解析即可,有两种常用转义方式:
方式1:单变量转义(兼容性最好)
对每个Prometheus模板变量的大括号单独做转义,修改后的values配置如下:
prometheusRule: rules: - alert: SSLCertExpiringSoon expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 10 for: 0m labels: severity: warning annotations: summary: Blackbox SSL certificate will expire soon (instance {{ "{{" }} $labels.instance {{ "}}" }}) description: "SSL certificate expires in 30 days\n VALUE = {{ "{{" }} $value {{ "}}" }}\n LABELS = {{ "{{" }} $labels {{ "}}" }}"
方式2:整块内容转义(适合大段Prometheus模板)
如果你使用的是Helm 3.1及以上版本,可以用raw块包裹所有不需要Helm解析的Prometheus模板内容:
annotations: {{- raw -}} summary: Blackbox SSL certificate will expire soon (instance {{ $labels.instance }}) description: "SSL certificate expires in 30 days\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" {{- endraw -}}
两种方式渲染后生成的PrometheusRule配置都会保留原生的{{ $labels }}、{{ $value }}格式,Prometheus可以正常识别解析。
内容的提问来源于stack exchange,提问作者celcin
相关产品推荐
相关产品推荐

