kubectl獲取名稱空間下所有configmap集合的方法

發表於2023-12-12

前言:

獲取單個configmap並忽略特定欄位的操作可參照:kubectl獲取ConfigMap匯出YAML時如何忽略某些欄位
要獲取名稱空間下所有ConfigMap並忽略特定欄位,你可以使用kubectl命令與例如yq這樣的工具結合使用來忽略或刪除不需要的欄位。以下是一個步驟和示例,展示瞭如何結合使用這些工具來實現你的目標。

方案一:使用yq處理YAML檔案

依然以default名稱空間為例:

kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      2y149d
mail               4      2y133d
mysql-config       1      138d

首先安裝yq。如你提到的,對於Ubuntu系統,可以使用以下命令安裝:

sudo apt-get install yq

匯出default namespace下所有configmap:

然後,使用查詢並刪除操作來過濾掉不需要的欄位。例如,如果你想要移除所有ConfigMap的metadata.annotationsmetadata.creationTimestampmetadata.resourceVersion,和metadata.uid欄位,可以執行如下命令:

kubectl get cm -o yaml | yq e 'del(.items[].metadata.creationTimestamp, .items[].metadata.resourceVersion, .items[].metadata.uid, .items[].metadata.annotations)' - > default-configmaps.yaml

image.png
這個命令會獲取所有名稱空間下的配置對映(ConfigMap),並輸出成一個單一的YAML檔案,其中已經刪去了所有制定的欄位。

但是這裡還有一個問題,如何忽略某一個或者多個configmap呢比如上面的kube-root-ca.crt configmap呢?

如何匯出namespace下除kube-root-ca.crt cm下的所有configmap

kubectl get cm -o yaml | yq e 'del(.items[] | select(.metadata.name == "kube-root-ca.crt")) | del(.items[].metadata.creationTimestamp, .items[].metadata.resourceVersion, .items[].metadata.uid, .items[].metadata.annotations)'

image.png
在這條命令中,首先使用 del 函式刪除名為kube-root-ca.crt的configmap。這是透過 select 函式和比較運算子實現的。當.metadata.name等於kube-root-ca.crt時,這個configmap會從列表中刪除。接著,其他的刪除操作會應用到剩餘的configmaps上。最後,改變後的YAML內容將被重定向到 default-configmaps.yaml 檔案中。
注:請確保你安裝了 yq 版本 4 或以上,因為 yq 的語法在不同版本間有較大差異。上述示例是基於 yq 版本 4 的語法。如果你的 yq 版本與此不同,請根據你的版本調整語法。

如何實現匹配遮蔽多個configmap呢?繼續遮蔽mail configmap:

kubectl get cm -o yaml | yq e 'del(.items[] | select(.metadata.name == "kube-root-ca.crt"  or .metadata.name == "mail")) | del(.items[].metadata.creationTimestamp, .items[].metadata.resourceVersion, .items[].metadata.uid, .items[].metadata.annotations)' - > default-configmaps.yaml

image.png
這裡使用or 可以匹配多個,突然覺得這裡也可以改變一下方法只匯出兩個 mail與mysql-config cm的方式是不是and 變通一下:

kubectl get cm -o yaml | yq e 'del(.items[] | select(.metadata.name != "mail" and .metadata.name != "mysql-config")) | del(.items[].metadata.creationTimestamp, .items[].metadata.resourceVersion, .items[].metadata.uid, .items[].metadata.annotations)'

image.png

方案二:自定義Go模板

此方法比較高階,你可以建立一個自定義的Go模板來精確控制哪些欄位會被展示。下面是一個例子,獲取所有名稱空間下的ConfigMap但會忽略metadata.annotationsmetadata.creationTimestampmetadata.resourceVersionmetadata.uid欄位:

kubectl get cm  -o go-template-file=template.txt

在上述命令中,template.txt是一個包含Go模板內容的檔案,可以如下編寫(確保檔案路徑和名稱與命令中的相匹配):

{{- range .items }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .metadata.name }}
  namespace: {{ .metadata.namespace }}
data:
{{- range $key, $value := .data }}
  {{ $key }}: |-
    {{ $value | indent 4 }}
{{- end }}
{{- end }}

此模板檔案迭代所有ConfigMap物件,只包含名稱、名稱空間以及資料欄位。注意,模板語法可能根據你想要顯示的確切內容和格式有所不同。
當然也可以寫成下面的樣子:

kubectl get cm -n default -o go-template='{{range .items}}{{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}}{{end}}'

image.png
這樣匯出的會有些強迫症,還是不太推薦!

方案三:結合文字處理工具

這是一個使用grep來實現的更基礎的方法,可以從kubectl輸出中篩選掉不需要的行。

kubectl get cm -n default -o yaml | grep -Ev '^\s*creationTimestamp:|^\s*annotations:|^\s*resourceVersion:|^\s*uid:' > all-configmaps.yaml

image.png
在上述命令中,grep -Ev用來排除包含特定欄位的行,然後將輸出重定向到檔案all-configmaps.yaml中。這個方法適用於簡單的過濾,但可能無法處理複雜的YAML結構。

上述方法可以根據你的具體需求進行調整,以適應特定欄位的刪除或忽略。

記住,某些欄位,特別是涉及多行值的,可能需要更復雜的處理技巧,如使用yq或者自定義Go模板,以確保正確地解析和編輯YAML。

可以發散思維的:

  1. 只匯出A and B cm
  2. 匯出A and B之外所有的cm
  3. 匯出 A and B名稱空間下所有的cm?

.......................可以各種各樣的組合,大家發散思維玩一下吧!
注:以上程式碼chatgpt輔助生成!

相關文章