
症狀
部署流程在 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 indentyq 直接指出 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/authdata.kong.yml: 用 | 表示 block scalar(保留內容換行),但內部的 YAML 仍必須縮進正確。Line 42 的 url: 少了 1 個空格。
這個錯誤 hiding in plain sight:
- GitHub diff 很難看出空格差異
- VS Code 沒開「顯示空白字元」看不出來
- YAML validator 驗外層覺得是合法字串(因為
|就是字串) - kustomize 把字串當實際 YAML parse 時才爆
修法
- 明確顯示空白字元
VS Code 設定:"editor.renderWhitespace": "all"。Line 42 立刻看到異常。
- 修正縮進
data:
kong.yml: |
_format_version: "3.0"
services:
- name: auth-service
url: http://auth:3000 # 改成 2 格
routes:
- name: auth
paths:
- /api/auth- 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 RSA Key 縮排 + YAML block scalar — 同類坑的變形
- ConfigMap 被 kustomize 覆蓋為 placeholder — 另一種 ConfigMap 問題
