博客 / 詳情

返回

kubectl獲取ConfigMap導出YAML時如何忽略某些字段

前言:

當我們在使用Kubernetes時,常常需要通過kubectl命令行工具來管理資源。有時我們也想將某個資源的配置導出為YAML文件,這樣做有助於版本控制和資源的遷移。然而,默認情況下,使用kubectl get命令導出資源配置會包含一些元數據字段:
r7EUlNNKvc.png
**annotations**, **creationTimestamp**, **resourceVersion**, **uid**等,這些字段對於備份或版本控制來説並不是必需的,反而可能會造成一些問題。本文將教您如何忽略這些字段,導出一個更乾淨的YAML配置!

kubectl獲取ConfigMap導出YAML時如何忽略某些字段

一、理解kubectl get命令

在深入瞭解如何忽略特定字段之前,我們先來了解一下kubectl get命令。

kubectl get cm

image.png
以mysql-config為例:

 kubectl get cm mysql-config -o yaml

以上命令會打印出指定ConfigMap的YAML格式輸出,包括所有元數據信息。例如:

apiVersion: v1
data:
  my.cnf: "[mysqld]\nserver-id=1\ncharacter-set-server=utf8mb4 \nlower_case_table_names
    = 1\n"
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"my.cnf":"[mysqld]\nserver-id=1\ncharacter-set-server=utf8mb4 \nlower_case_table_names = 1\n"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"mysql-config","namespace":"default"}}
  creationTimestamp: "2023-07-19T07:16:34Z"
  name: mysql-config
  namespace: default
  resourceVersion: "540796275"
  uid: 19ba11c5-a803-4a1e-8800-c4f569ec092f

為了導出更乾淨的配置,我們需要去除掉其中不必要的元數據字段。

二、如何忽略特定字段

在Kubernetes中,沒有直接忽略特定字段的kubectl選項,但我們可以使用一些工具和技術來實現類似的效果。

方案一:使用kubectl結合文本處理工具

最簡單的方法是將kubectl get的輸出通過管道傳遞給文本處理命令來刪除不需要的字段。在Linux系統上,我們通常使用grepsed等工具來處理文本。

示例:簡單使用grep排除特定行。
kubectl get cm mysql-config -o yaml | grep -v '^\s*creationTimestamp:'

image.png
上述命令將ConfigMap輸出的YAML內容中的creationTimestamp行刪除了,相似地,您可以添加更多的grep -v來排除其他不需要的字段:

kubectl get cm mysql-config -o yaml | grep -v '^\s*creationTimestamp:'|grep -v '^\s*annotations:'|grep -v '^\s*resourceVersion:'|grep -v '^\s*uid:'

image.png
這裏要特別提醒一下:由於 YAML 中這些字段可能有縮進,使用 grep -v 可能不足夠靈活來處理所有情況。此外,grep 僅逐行工作,annotations字段可能是多行值,這裏並不適用!

示例:使用grep與kubeclt patch結合:
kubectl patch cm mysql-config -p '{"metadata": {"annotations": null, "creationTimestamp": null, "resourceVersion": null, "uid": null}}'
kubectl get cm mysql-config

image.png

ubectl get cm mysql-config -o yaml | grep -v "^\s*annotations:" | grep -v "^\s*creationTimestamp:" | grep -v "^\s*resourceVersion:" | grep -v "^\s*uid:"

image.png
但是,這個方法實際上修改了 ConfigMap。如果你想保持 ConfigMap 不變,這個方法並不適用!
輸出到mysql-config文件中:

ubectl get cm mysql-config -o yaml | grep -v "^\s*annotations:" | grep -v "^\s*creationTimestamp:" | grep -v "^\s*resourceVersion:" | grep -v "^\s*uid:" > mysql-config.yaml
示例:使用awk進行復雜的文本處理

如果不想使用grep,而是想繼續使用傳統的文本處理工具鏈,awk是一個比grep更強大的文本處理工具,能處理跨行的模式匹配和範圍操作。我們可以使用awk來按塊處理YAML內容。

以下是一個示例awk腳本,用於刪除annotations和其他一些字段:
注: configmap還原為path之前的內容:
image.png
起碼保留annotations字段

kubectl get cm mysql-config -o yaml | awk '
  /annotations:/{a=1} 
  /^    [a-zA-Z0-9_]+:/{a=0} 
  !a && !/creationTimestamp:/ && !/resourceVersion:/ && !/uid:/ {print}
  /name:|namespace:/{print}
' > mysql-config.yaml

image.png
在上述示例中,當awk遇到以annotations:開頭的行時,設置一個標誌位a為1,然後在遇到下一個以一些空格後跟文字字符開頭的行時,重新設置標誌位為0,完成範圍的處理。同時,我們檢查每一行是否不是要排除的字段,如果是的話,就跳過不打印。

方案二:藉助yq工具處理YAML文件

yq是一個強大的YAML處理工具,它類似於JSON的jq工具。你可以利用yq來精準地處理YAML格式的內容。

首先,您需要安裝yq。它可以通過包管理工具(如Homebrew、apt等)或直接從其GitHub頁面下載。
我的操作系統ubuntu直接使用sudo apt-get install yq 安裝:
使用yq刪除特定字段的命令如下:

kubectl get cm mysql-config -o yaml | yq eval 'del(.metadata.creationTimestamp, .metadata.resourceVersion, .metadata.uid, .metadata.annotations)' - > mysql-config.yaml

image.png
這個命令將creationTimestampresourceVersionuidannotations字段從YAML中刪除,並將結果保存到my-config.yaml文件中。

方案三:自定義Go模板

另一個更高級的解決方案是使用kubectl的自定義Go模板輸出。通過編寫一個模板,您可以精確控制輸出哪些內容。

kubectl get cm my-config -o go-template='{{printf "apiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: %s\nnamespace: %s\ndata:\n" .metadata.name .metadata.namespace}}{{range $key, $value := .data}}{{printf "  %s: |-\n    %s\n" $key $value}}{{end}}' > mysql-config.yaml

image.png
這段命令利用Go模板語法生成一個過濾掉特定Metadatas字段的ConfigMap資源的清單,並保存到mysql-config.yaml

結束語

在實踐中,以上的每種方法都有其適用的場合。如果您只是偶爾需要進行這樣的操作,簡單的文本處理可能就足夠了。如果您經常需要處理複雜的YAML文件,那麼學習和使用yq將會很有幫助。對於對性能要求較高或者更復雜的處理需求,學習一些關於Go模板的知識會是一筆不錯的投資。

希望這篇文章對你有所幫助,如果你有任何問題,歡迎在評論區留言討論。

user avatar gongzhengyang 頭像 mxzhang 頭像
2 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.