cover

症狀

部署流程在 CI 裡跑 kustomize build 失敗:

error: accumulating resources: accumulation err='accumulating resources
from 'overlays/dev': yaml: line 42: mapping values are not allowed in
this context'

但 YAML validator 線上工具驗證單檔沒問題。本機 kubectl apply 也會炸:

error: error validating "kong-configmap.yaml": error validating data:
ValidationError(ConfigMap.data): invalid type for io.k8s.api.core.v1.
ConfigMap.data: got "map", expected "string"

診斷過程

排除方向 1:Kong 設定錯(誤判)

第一反應是 Kong 路由設定錯。花了 30 分鐘查 Kong 文件、對照 declarative config 格式,都正確。

排除方向 2:kustomize 版本(排除)

kustomize version
# v5.2.1

版本夠新。同事另一台 v5.0 也一樣壞。不是 kustomize bug。

排除方向 3:YAML 本身(命中)

yq 試解析:

yq eval '.' kong-configmap.yaml
# Error: bad indent

yq 直接指出 line 42 附近的縮進。

原因

Kong ConfigMap 裡要塞一個完整的 YAML 設定檔當字串。長這樣:

apiVersion: v1
kind: ConfigMap
metadata:
  name: kong-config
data:
  kong.yml: |
    _format_version: "3.0"
    services:
    - name: auth-service
     url: http://auth:3000   # ← 縮進只有 1 格,應該 2 格
      routes:
      - name: auth
        paths:
        - /api/auth

data.kong.yml:| 表示 block scalar(保留內容換行),但內部的 YAML 仍必須縮進正確。Line 42 的 url: 少了 1 個空格。

這個錯誤 hiding in plain sight:

  • GitHub diff 很難看出空格差異
  • VS Code 沒開「顯示空白字元」看不出來
  • YAML validator 驗外層覺得是合法字串(因為 | 就是字串)
  • kustomize 把字串當實際 YAML parse 時才爆

修法

  1. 明確顯示空白字元

VS Code 設定:"editor.renderWhitespace": "all"。Line 42 立刻看到異常。

  1. 修正縮進
data:
  kong.yml: |
    _format_version: "3.0"
    services:
    - name: auth-service
      url: http://auth:3000   # 改成 2 格
      routes:
      - name: auth
        paths:
        - /api/auth
  1. CI 加 YAML lint check

.gitlab-ci.yml 加:

yaml-lint:
  script:
    - yamllint kubernetes/

以後有這種問題在 CI 就攔下來,不會跑到 deploy 才爆。

Commit 參考:1367e7b fix: Kong configmap YAML 縮進修正 + kustomize build 通過

可推廣教訓

教訓 1:Block scalar 內仍是 YAML,空白規則照常

|> 只影響換行處理,不影響縮進。YAML-in-YAML 常遇到這種坑。

教訓 2:看不見的空白字元是最大的敵人

render whitespace。Git commit diff 如果看不出差異,先在編輯器裡開。

教訓 3:Schema 驗證 vs 內容驗證是兩件事

ConfigMap schema 驗證只看 data 是不是 map[string]string。不會驗 string 內容是合法 YAML。加第二層驗證yamllint 或 Kong 自己的 validate)。

教訓 4:錯誤訊息指向的檔案不一定是 root cause

kustomize build 錯誤指向 overlays/dev,但根因在 base/kong-configmap.yaml。要往上游追。


相關踩坑

回上層

Kong Gateway 踩坑集 / ops-notes