[指令] kubectl patch === ###### tags: `K8s / commands` ###### tags: `Kubernetes`, `k8s`, `kubectl`, `kubectl patch`, `patch` <br> [TOC] <br> ## 教學範例 > by gpt-5 (2025/09/10) ### (1) `kubectl patch` 是什麼? 只修改**現有物件的一小部分欄位**,不需要覆蓋整份 YAML。適合臨時調整或自動化腳本。 **基本語法** ```bash kubectl patch <resource>/<name> \ --type=<strategic|merge|json> \ -p '<payload>' ``` > 小撇步:**`-p` 後面的 JSON 一定要整段用引號包起來**(常用單引號),避免被 shell 分割。 --- ### (2) 三種 Patch 型態(何時用?) * `strategic`(預設):K8s 內建型別才有(如 Deployment),**會聰明合併陣列**(依 `name` 等鍵)。 * `merge`(JSON Merge Patch, RFC 7386):**簡單覆蓋欄位**,但**整個陣列會被整段取代**。 * `json`(JSON Patch, RFC 6902):用 `op/add/replace/remove` 等**操作路徑**,適合**刪除欄位**、精準修改陣列。 --- ### (3) 最小可用範例 - ### A. 讓某顆 PV 刪 PVC 時「保留資料」 > 對象:**PersistentVolume**(叢集資源,不需 `-n`) > 目的:把 `reclaimPolicy` 改成 `Retain` ```bash kubectl patch pv pvc-46780abc-9e8a-417b-8b6e-f13df01af7c5 \ --type=merge \ -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' ``` 驗證: ```bash kubectl get pv pvc-46780abc-9e8a-417b-8b6e-f13df01af7c5 \ -o jsonpath='{.spec.persistentVolumeReclaimPolicy}{"\n"}' # 期待輸出:Retain ``` - ### B. 更新 Deployment 的容器映像(最常用) > 預設 `--type=strategic` ```bash kubectl patch deploy web -n app \ -p '{"spec":{"template":{"spec":{"containers":[{"name":"web","image":"nginx:1.27.2"}]}}}}' kubectl rollout status deploy/web -n app ``` - ### C. 移除 PV 上的 `claimRef`(方便「接回」已保留的 PV) > 用 **JSON Patch** 的 `remove` ```bash kubectl patch pv pvc-xxxx \ --type=json \ -p='[{"op":"remove","path":"/spec/claimRef"}]' ``` - ### D. 新增或覆蓋 Annotation(任何資源都常用) ```bash kubectl patch svc api -n app \ -p='{"metadata":{"annotations":{"example.com/owner":"tj"}}}' # 同效果也可用:kubectl annotate svc api example.com/owner=tj --overwrite -n app ``` --- ### (4) 快速小抄(Cheat Sheet) ```bash # strategic(合併陣列、K8s 內建型別) kubectl patch deploy X -p '{"spec":{"replicas":3}}' # merge(簡單覆蓋欄位;陣列會整段取代) kubectl patch pv X --type=merge -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' # json(RFC 6902,精準操作) kubectl patch pv X --type=json -p='[{"op":"remove","path":"/spec/claimRef"}]' ``` --- ### (5) 常見坑位 * **忘了用引號包住 `-p` 內容** → shell 會把 JSON 拆開,導致怪錯誤。 * **不可變欄位改不了**:例如 * PV:`spec.storageClassName`、`spec.volumeMode`(通常不可改) * Service:`spec.clusterIP`(已建立後通常不可改) * **`merge` 會整段覆蓋**陣列;要「合併」陣列請用 `strategic`(但 CRD 沒有 strategic)。 * **PV/Node 等是叢集資源**:`-n` 沒作用。 * 不確定欄位路徑?先看物件: ```bash kubectl get pv X -o yaml | less kubectl explain pv.spec.persistentVolumeReclaimPolicy ``` * 想先預覽結果: ```bash kubectl patch pv X --type=merge \ -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' \ --dry-run=server -o yaml ``` <br> --- ## 情境案例 ### 如何將 finalizer 清空 - ### 刪除 PV 時卡住 - **先看是不是卡在 finalizers**: ``` kubectl get pv <pv-name> -o jsonpath='{.metadata.finalizers}{"\n"}' kubectl get pvc -n <ns> <pvc-name> -o jsonpath='{.metadata.finalizers}{"\n"}' ``` - **正常情況**: - 先把 PVC 刪掉,PV 會自行放行。 - **PV 一直卡在 Terminating,用最後手段)** > (可能造成底層儲存資源「沒被正確回收」,請慎用 > ``` kubectl patch pv <pv-name> \ --type=merge -p '{"metadata":{"finalizers":[]}}' ``` <br> {%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up