YAML转换JSON报错 did not find expected key

在提交YAML到CI/CD系统校验错误,平台提示

error converting YAML to JSON: yaml: line 47: did not find expected key

我使用 yamllint 工具进行校验:

yamllint alert.yaml

提示信息:

使用 yamllint 校验提示
  1:1       warning  missing document start "---"  (document-start)
  12:81     error    line too long (196 > 80 characters)  (line-length)
  25:81     error    line too long (90 > 80 characters)  (line-length)
  28:81     error    line too long (149 > 80 characters)  (line-length)
  33:81     error    line too long (109 > 80 characters)  (line-length)
  35:81     error    line too long (113 > 80 characters)  (line-length)
  41:81     error    line too long (90 > 80 characters)  (line-length)
  45:81     error    line too long (164 > 80 characters)  (line-length)
  48:81     error    line too long (168 > 80 characters)  (line-length)
  57:81     error    line too long (102 > 80 characters)  (line-length)
  60:81     error    line too long (104 > 80 characters)  (line-length)
  67:31     error    no new line character at the end of file  (new-line-at-end-of-file)
  48:147    error    syntax error: expected <block end>, but found '<scalar>' (syntax)

这里可以看到一些可以忽略的错误(例如行太长超过80字符),但是最后提示错误 syntax error: expected <block end>, but found '<scalar>' (syntax) 不能忽略,确实是语法错误。但是什么是 <block end> 什么又是 <scalar> ?

我这里的YAML案例是一个告警:

alert.yaml 配置语法错误
apiVersion: monitoring.sigma.alipay.com/v1
kind: MonitoringRule
metadata:
  ...
spec:
  interval: 1m
  ...
    - name: alert:TooManyPodPendingC2
      expr: sum by (cluster)(cluster:unhealthy_pod_namespace_count:sum1m{phase=~"Pending|unScheduledPending|scheduledFailedPending",namespace='c2-msearcherbs'}) > 2
      for: 1m
      annotations:
        expr: 'sum by (cluster)(cluster:unhealthy_pod_namespace_count:sum1m{phase=~"Pending|unScheduledPending|scheduledFailedPending",namespace='c2-msearcherbs'}) > 2'
        value: '{{$value}}'
        severity: 'p1'
        ...

语法错误在上述高亮行,为何提示期望的内容是 block end (块结束),而不是 scalar (纯量)

复习一下 YAML 语法: 纯量表示最基本的,不可再分的值。但是我没有看懂为何会提示是纯量

问了一下 GPT ,GPT说:

这个错误提示意思是在yaml文件中缺少了块结束符,但却找到了标量(scalar)。
解决方法是检查文件中是否有缺少大括号、中括号、冒号等符号的错误,如果有则添加正确的符号。

我仔细看了一下,原来我在上述 expr: 行中嵌套使用 单引号 和 双引号,我没有注意到:

  • 语法上是可以在单引号内部使用多个双引号的

  • 但是 不能在单引号内部再使用单引号

这导致语法断句错误:

'sum by (cluster)(cluster:unhealthy_pod_namespace_count:sum1m{phase=~"Pending|unScheduledPending|scheduledFailedPending",namespace=' ...  '}) > 2'

也就是2段字符串

解决方法是修订:

修订 alert.yaml ,在单引号内部只能使用双引号
apiVersion: monitoring.sigma.alipay.com/v1
kind: MonitoringRule
metadata:
  ...
spec:
  interval: 1m
  ...
    - name: alert:TooManyPodPendingC2
      expr: sum by (cluster)(cluster:unhealthy_pod_namespace_count:sum1m{phase=~"Pending|unScheduledPending|scheduledFailedPending",namespace="c2-msearcherbs"}) > 2
      for: 1m
      annotations:
        expr: 'sum by (cluster)(cluster:unhealthy_pod_namespace_count:sum1m{phase=~"Pending|unScheduledPending|scheduledFailedPending",namespace="c2-msearcherbs"}) > 2'
        value: '{{$value}}'
        severity: 'p1'
        ...

参考