ZonoTools

將 JSON 轉換為 Kubernetes 的 YAML(帶有範例)

By ZonoTools11 min read

為什麼 Kubernetes 使用 YAML

Kubernetes 是圍繞聲明式配置建構的:您描述所需的狀態(副本、映像、環境、磁碟區),控制器會根據該規範協調叢集。此工作流程自然適合簽入 Git、在 PR 中審核並使用kubectl apply -f應用的 YAML 檔案。 YAML 刪除了大括號和逗號,因此大型嵌套規範保持可瀏覽狀態 - 當高級工程師在凌晨 2 點比較 Service 或 StatefulSet 時,這正是您想要的。

聲明式 GitOps 假設儲存庫是事實來源:Argo CD、Flux 或普通 CI 應用程式變更的內容。 YAML 差異在 GitHub/GitLab 中以行方式讀取; JSON 通常會崩潰成不可讀的縮小的 blob,除非您在各處強制執行清楚排版。當審閱者必須發現意外的replicas碰撞或有風險的securityContext增量時,摩擦就很重要。

這裡的可讀性並不是表面的。營運團隊對清單進行標準化; Helm 圖表和 Kustomize 覆蓋仍然編譯為 YAML 形狀的物件。即使您使用其他格式進行原型設計,JSON 到 yaml kubernetes 路徑也是大多數團隊將 API 形狀的 blob 轉變為人類長期維護的內容的方式。

Kubernetes 中的 JSON 與 YAML

控制平面端到端地講 JSON。每個kubectl get deployment nginx -o JSON回應都是JSON;准入 Webhook 和 API 伺服器交換 JSON。 YAML 對作者來說是一個便利層:kubectl接受輸入的 YAML,在底層將其轉換為 JSON,並以結構化形式將物件保存在 etcd 中。

所以這種分割是實用的:機器和偵錯追蹤公開 JSON人類編寫和審查 YAML。與 API 通訊時,客戶端程式庫(client-go、控制器執行時)將結構編組為 JSON。您的 CI 作業可能會將即時物件快照為 JSON 以便進行審核,然後工程人員會要求使用 YAML,以便平台團隊可以在不接觸 Go 結構的情況下進行分叉和修補。

當您將 API 匯出貼到格式化程式或透過轉換器傳輸樣本時,您就是在故意彌合這一差距:在自動化擁有 JSON 的地方保留 JSON,在人類簽署的地方發出 YAML。要進行更深入的格式比較,請參閱JSON vs YAML: differences and use cases-相同的邏輯物件,不同的人體工學。

範例:JSON 格式的部署清單

假設您使用客戶端程式庫對 Deployment 進行原型設計,或從審核日誌複製了縮小的 JSON blob。這是一個現實的雙副本 nginx 部署,您可能會收到 JSON 形式的:

這是有效的 Kubernetes JSON:apiVersionkind、嵌套的spec.template.spec.containers以及表示為 JSON 陣列的連接埠清單。

json
{ "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "name": "nginx-demo", "namespace": "default", "labels": { "app": "nginx-demo" } }, "spec": { "replicas": 2, "selector": { "matchLabels": { "app": "nginx-demo" } }, "template": { "metadata": { "labels": { "app": "nginx-demo" } }, "spec": { "containers": [ { "name": "nginx", "image": "nginx:1.25-alpine", "ports": [{ "name": "http", "containerPort": 80 }] } ] } } }}

範例:與 YAML 相同的清單

JSON 到 yaml kubernetes 轉換之後,您通常需要縮排主導的結構,您可以將其放在儲存庫中的其他清單旁邊。等效的 YAML 保留相同的鍵和標量值,但消除了標點符號雜訊:

在接觸即時叢集之前,您可以使用kubectl apply --dry-run=client -f -進行健全性檢查。如果轉換意外地刪除字段或重塑列表,請將其視為管道中的錯誤,而不是手動波過去的生產。

多重文件 YAML(---分隔符號)在儲存庫中很常見;您的轉換器輸出通常是每個貼上一個資源。僅在每個文檔獨立驗證後,將拆分的 JSON 匯出合併到單獨的文件中或與---連接 - 不要假設盲目合併會保留文檔邊界。

yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo namespace: default labels: app: nginx-demo spec: replicas: 2 selector: matchLabels: app: nginx-demo template: metadata: labels: app: nginx-demo spec: containers: - name: nginx image: nginx:1.25-alpine ports: - name: http containerPort: 80

在 Git 之前去除集群噪音

直接從 etcd 大量讀取中導出,會攜帶您在 Git 中永遠不需要的字段:resourceVersionuidcreationTimestamp、 ManagedFields 區塊以及控制器擁有的整個 .status 子樹。提交它們會導致毫無意義的混亂,並且偶爾會與伺服器端應用語義發生衝突。

將 JSON 轉換為 YAML 以進行 Kubernetes 簽入之前,請保留:

  • apiVersionkindmetadata由您控制(namenamespacelabelsannotations是故意的)
  • spec(以及 ConfigMap 的data、RBAC 的rules等)

刪除或替換其他所有內容,除非您的工具明確依賴它。當准入改變物件時,kubectl apply --dry-run=server捕捉了客戶端試執行未命中的一些錯誤。

如果您圍繞 CustomResourceDefinitions 進行模板化,來自 alpha API 的 JSON 轉儲有時會包含您的 YAML 從未拼寫出來的預設欄位 - 當審閱者詢問為什麼欄位「神奇地」出現時,與kubectl explain <kind> --recursive不同。轉換器並不會發明語意;而是發明語意。它們反映了結構。垃圾進來仍然意味著混淆 YAML。

舊版kubectl apply流有時會在metadata.annotations["kubectl.kubernetes.io/last-applied-configuration"]中隱藏序列化意圖。保留還是刪除該註釋取決於您是否仍然依賴客戶端應用語義; GitOps 優先的團隊通常更喜歡使用明確字段管理器的伺服器端應用 (--server-side),而不是在註釋中拖曳歷史 JSON。

常見問題:縮排和數組

縮排是 YAML 的語法。兩個空格與製表符,或containers:之前的額外空格,可能會​​將有效的 JSON 樹變成解析器錯誤或更糟糕的情況 - 有效但錯誤的子樹合併在錯誤的父樹下。始終將製表符標準化為空格,並保持深度與kubectl發出 YAML 的方式一致(kubectl get deploy nginx-demo -o yaml是一個很好的樣式參考)。將「智慧型縮排」與貼上的 JSON 衍生樹混合在一起的編輯器是兩空格錯誤的常見來源 - 在修復結構問題時停用一次儲存格式,然後重新啟用。

數組暴露了另一個不匹配。 JSON 將序列拼寫為[...]; YAML 在鍵下使用-項。轉換器必須保留某個物件是單一物件還是單元素清單-Kubernetes 關心(envvolumeMountsportsimagePullSecrets)。靜默扁平化錯誤將有效的 PodSpec 變成可以在本機驗證但無法准入或部署時缺少 sidecar 的東西。

Common JSON to YAML conversion errors中介紹了合併怪癖和標量輸入意外 - 在無需測試的情況下在 CI 中自動轉換之前請先閱讀該內容。

來自kubectl get … -o JSON的大型清單還包括 伺服器填充欄位resourceVersionuid、狀態)。在轉換和提交之前剝離您不打算應用的狀態和元資料;否則,您的 GitOps 控制器會與過時的標識符作鬥爭或重新應用過時的副本觀察。

使用 ZonoTools 立即轉換

您不需要為每次貼上都使用一次性節點腳本。開啟 JSON to YAML:貼上 JSON 部署或 CRD 形狀的片段,複製 YAML,然後透過kubectl apply --dry-run=client -f -貼上到您的儲存庫或管道中。當清單引用內部註冊表主機或您拒絕傳送給第三方 API 的佔位符機密時,處理保留在瀏覽器中,這很方便。

適合真實團隊的工作流程:

  • 如果您從日誌複製,請先清楚排版或縮小 JSON;雜散逗號會快速破壞解析器。
  • 轉換,然後修剪伺服器欄位並重新執行試執行。
  • 開設 PR;讓 CI 強制實施架構或策略(OPA、kubeconform 等)。

將這項規則與程式碼審查結合起來,JSON 到 yaml kubernetes 循環就不再是支援導出的 JSON 套件和平台儲存庫期望的可維護 YAML 之間的摩擦。