成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

巧用 Kubernetes Finalizers 優雅清理那些刪除失敗的 K8s 資源

系統 Linux
本文將介紹當你執行 kubectl delete 語句時,K8s 內部都執行了哪些操作。以及為何有些資源『刪除不掉』(具體表現為一直 Terminating,刪除 namespace 時很容易遇到這種情況)。

你有沒有在使用 k8s 過程中遇到過這種情況:通過 kubectl delete 指令刪除一些資源時,一直處于 Terminating 狀態。這是為什么呢?

本文將介紹當你執行 kubectl delete 語句時,K8s 內部都執行了哪些操作。以及為何有些資源『刪除不掉』(具體表現為一直 Terminating,刪除 namespace 時很容易遇到這種情況)。

接下來,我們聚焦討論以下四個方面:

  1. 資源的哪些屬性會對刪除操作產生影響?
  2. finalizers 與 owner references 屬性是如何影響刪除操作的?
  3. 如何利用 Propagation Policy(分發策略)更改刪除順序?
  4. 刪除操作的工作原理?

方便起見,以下所有示例都將使用 ConfigMaps 和基本 shell 命令來演示該過程。

詞匯表

  1. 資源 : k8s 的資源對象(如 configmap, secret, pod...)
  2. finalizers: 終結器,存放鍵的列表。列表內的鍵為空時資源才可被刪除
  3. owner references: 所有者引用(歸誰管理 / 父資源對象是誰)
  4. kubectl: K8s 客戶端工具

基本刪除操作

Kubernetes 提供了幾個不同的命令,您可以使用它們來創建、讀取、更新和刪除對象。出于本文的目的,我們將重點討論四個 kubectl 命令 :create、get、patch 和 delete。

   ?

   下面是 kubectl delete 命令的基本示例。

  • 創建名為 mymap 的 configmap 對象。
$ kubectl create configmap mymap
configmap/mymap created
  • 查看名為 mymap 的 configmap 對象。
$ kubectl get configmap/mymap
NAME DATA AGE
mymap 0 12s
  • 刪除名為 mymap 的 configmap 對象。
$ kubectl delete configmap/mymap
configmap "mymap" deleted
  • 查看名為 mymap 的 configmap 對象。
$ kubectl get configmap/mymap
Error from server (NotFound): configmaps "mymap" not found

基本 delete 命令的刪除操作狀態圖非常簡單:

刪除操作看似簡單,但是有很多因素可能會干擾刪除,包括 finalizers 與 owner references 屬性。

Finalizers 是什么?

上面我們提到了兩個屬性:finalizers 與 owner references 可能會干擾刪除操作,導致刪除阻塞或失敗。那 Finalizers 是什么?會對刪除有何影響呢?

當要理解 Kubernetes 中的資源刪除原理時,了解 finalizers(以下我們稱 finalizers 為終結器)的工作原理是很有幫助的, 可以幫助您理解為什么有些對象無法被刪除。

終結器是資源發出預刪除操作信號的屬性, 控制著資源的垃圾收集,并用于提示控制器在刪除資源之前執行哪些清理操作。

finalizers 本質是包含鍵的列表,不具有實際意義。與 annotations(注釋)類似,finalizers 是可以被操作的(增刪改)。

以下終結器您可能遇到過:

  • kubernetes.io/pv-protection
  • kubernetes.io/pvc-protection

這兩個終結器作用于卷,以防止卷被意外刪除。

   ?

類似地,一些終結器可用于防止資源被刪除,但不由任何控制器管理。下面是一個自定義的 configmap,它沒有具體值,但包含一個終結器:

$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: mymap
finalizers:
- kubernetes
EOF

終結器通常用于名稱空間 (namespace),而管理 configmap 資源的控制器不知道該如何處理 finalizers 字段。下面我們嘗試刪除這個 configmap 對象:

$ kubectl delete configmap/mymap &
configmap "mymap" deleted
$ jobs
[1]+ Running kubectl delete configmap/mymap

Kubernetes 返回該對象已被刪除,然而它并沒有真正意義上被刪除,而是在刪除的過程中。當我們試圖再次獲取該對象時,我們發現該對象多了個 deletionTimestamp(刪除時間戳) 字段。

$ kubectl get cm mymap -o yaml
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: "2021-09-29T11:04:40Z"
deletionGracePeriodSeconds: 0
deletionTimestamp: "2021-09-29T11:04:55Z"
finalizers:
- kubernetes
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:finalizers:
.: {}
v:"kubernetes": {}
manager: kubectl
operation: Update
time: "2021-09-29T11:04:40Z"
name: mymap
namespace: default
resourceVersion: "1378430"
selfLink: /api/v1/namespaces/default/configmaps/mymap
uid: 8d6ca0b1-4840-4597-8164-a63b526dbf5f

   ?

簡而言之,當我們刪除帶有 finalizers 字段的對象時,該對象僅僅是被更新了,而不是被刪除了。這是因為 Kubernetes 獲取到該對象包含終 器,通過添加 deletionTimestamp(刪除時間戳)字段將其置于只讀狀態(刪除終結器鍵更新除外)。換句話說,在刪除該對象終結器之前,刪除都不會完成。

接下來我們嘗試通過 patch 命令刪除終結器,并觀察 configmap/mymap 是否會被『真正』刪除。

$ kubectl patch configmap/mymap \
--type json \
--patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
configmap/mymap patched

再次檢索該對象。

$ kubectl get cm mymap
Error from server (NotFound): configmaps "mymap" not found

發現該對象已被真正刪除,下圖描述了帶有 finalizers 字段的對象刪除流程:

   ?

總結:當您試圖刪除一個帶有終結器的對象,它將一直處于預刪除只讀狀態, 直到控制器刪除了終結器鍵或使用 Kubectl 刪除了終結器。一旦終結器列表為空,Kubernetes 就可以回收該對象,并將其放入要從注冊表中刪除的隊列中。

帶有 finalizers 字段的對象無法刪除的原因大致如下:

  • 對象存在 finalizers,關聯的控制器故障未能執行或執行 finalizer 函數 hang 住 : 比如 namespace 控制器無法刪除完空間內所有的對象, 特別是在使用 aggregated apiserver 時,第三方 apiserver 服務故障導致無法刪除其對象。 此時,需要會恢復第三方 apiserver 服務或移除該 apiserver 的聚合,具體選擇哪種方案需根據實際情況而定。
  • 集群內安裝的控制器給一些對象增加了自定義 finalizers,未刪除完 fianlizers 就下線了該控制器,導致這些 fianlizers 沒有控制器來移除他們。此時,需要恢復該控制器會手動移除 finalizers(多出現于自定義 operator),具體選擇哪種方案根據實際情況而定。

Owner References 又是什么?

上面我們提到了兩個屬性:finalizers 與 owner references 可能會干擾刪除操作,導致刪除阻塞或失敗。并介紹了 Finalizers,接下來我們聊聊 Owner References。

Owner References(所有者引用或所有者歸屬)描述了對象組之間的關系。指定了資源彼此關聯的屬性,因此可以級聯刪除整個資源樹。

   ?

當存在所有者引用時,將處理終結器規則。所有者引用由名稱和 UID 組成。

所有者引用相同名稱空間內的鏈接資源,它還需要 UID 以使該引用生效 (確保唯一)。Pods 通常具有對所屬副本集的所有者引用。因此,當 Deloyment 或有 StatefulSet 被刪除時,子 ReplicaSet 和 Pod 將在流程中被刪除。

我們通過下面的例子,來理解 Owner References(所有者引用)的工作原理:

  1. 創建 cm/mymap-parent 對象。
$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: mymap-parent
EOF
  1. 獲取 cm/mymap-parent 的 UID。
CM_UID=$(kubectl get configmap mymap-parent -o jsonpath="{.metadata.uid}")
  1. 創建 cm/mymap-child 對象,并設置 ownerReferences 字段聲明所有者引用(通過 kind、name、uid 字段確保選擇器可以匹配到)。
$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: mymap-child
ownerReferences:
- apiVersion: v1
kind: ConfigMap
name: mymap-parent
uid: $CM_UID
EOF

即 cm/mymap-parent 為 cm/mymap-child 的父對象,此時我們刪除 cm/mymap-parent 對象并觀察 cm/mymap-child 對象狀態。

$ kubectl get cm
NAME DATA AGE
mymap-child 0 2m44s
mymap-parent 0 3m
$ kubectl delete cm mymap-parent
configmap "mymap-parent" deleted
$ kubectl get cm
No resources found in default namespace.

即我們通過刪除父對象,間接刪除了父對象下的所有子對象。這種刪除 k8s 中被稱為級聯刪除。我們可不可以只刪除父對象,而不刪除子對象呢?

   ?

 答案是 : 可以的,刪除時通過添加--cascade=false 參數實現,我們通過下面的例子來驗證:

$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: mymap-parent
EOF
$ CM_UID=$(kubectl get configmap mymap-parent -o jsonpath="{.metadata.uid}")
$ cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: mymap-child
ownerReferences:
- apiVersion: v1
kind: ConfigMap
name: mymap-parent
uid: $CM_UID
EOF
$ kubectl delete --cascade=false configmap/mymap-parent
configmap "mymap-parent" deleted
$ kubectl get cm
NAME DATA AGE
mymap-child 0 107s

   ?

   --cascade=false 參數實際改變了父-子資源的刪除順序,k8s 中關于父-子資源刪除策略有以下三種:

  • Foreground: 子資源在父資源之前被刪除 (post-order)
  • Background: 父資源在子資源之前被刪除 (pre-order)
  • Orphan: 忽略所有者引用進行刪除

下面這段內容比較晦澀,沒太理解:

Keep in mind that when you delete an object and owner references have been specified, finalizers will be honored in the process.  This can result in trees of objects persisting, and you end up with a partial deletion.  At that point, you have to look at any existing owner references on your objects, as well as any finalizers, to understand what’s happening

強制刪除命名空間

有一種情況可能需要強制刪除命名空間:

如果您已經刪除了一個命名空間,并刪除了它下面的所有對象,但名稱空間仍然存在,一般為 Terminating 狀態。則可以通過更新名稱空間的 finalize 屬性來強制刪除該名稱空間。

  • 會話 1
$ kubectl proxy
  • 會話 2
$ NAMESPACE_NAME=test
cat <<EOF | curl -X PUT \
127.0.0.1:8001/api/v1/namespaces/$NAMESPACE_NAME/finalize \
-H "Content-Type: application/json" \
--data-binary @-
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "$NAMESPACE_NAME"
},
"spec": {
"finalizers": null
}
}
EOF

我們應該謹慎思考是否強制刪除命名空間,因為這樣做可能只刪除名稱空間,命名空間下的其他資源刪不完全,最終導致留下孤兒對象。比如資源對象 A 存在于 ddd 命名空間,此時若強制刪除 ddd 命名空間 , 且對象 A 又未被刪除,那么對象 A 便成了孤兒對象。

當出現孤兒對象時,可以手動重新創建名稱空間,隨后可以手動清理和恢復該對象。

責任編輯:龐桂玉 來源: 奇妙的Linux世界
相關推薦

2022-09-05 08:26:29

Kubernetes標簽

2024-06-26 00:22:35

2025-04-01 00:06:50

JavaK8sSpring

2022-04-29 11:13:08

K8s資源Linux

2023-11-06 07:16:22

WasmK8s模塊

2022-04-22 13:32:01

K8s容器引擎架構

2023-11-07 08:23:05

2021-12-26 18:23:10

Kubernetes集群命令

2022-11-02 10:21:41

K8s pod運維

2023-12-01 15:46:01

Kubernetes容器

2023-09-11 14:21:00

2023-11-24 17:51:18

Kubernetes云原生

2022-07-11 10:51:25

Java 8OptionalNPE

2023-04-12 11:28:36

Kubernetes服務器

2024-05-10 08:00:48

K8soperatorGitHub

2024-09-26 18:04:02

2024-06-12 13:21:06

2025-01-03 09:07:51

2023-09-06 08:12:04

k8s云原生

2023-11-28 14:04:15

Kubernetes運維
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜影院 | 7777在线视频 | 欧美视频日韩 | 亚洲成人精品久久 | av黄色在线观看 | 久久婷婷国产 | 久久精品日产第一区二区三区 | 热久久免费视频 | 黄在线 | 视频一区在线观看 | 女生羞羞网站 | 欧美激情一区二区 | 亚洲天堂久久 | 亚洲精品电影网在线观看 | 在线视频日韩精品 | 国产免费一级一级 | 日韩在线观看一区 | 国产精品久久一区 | 蜜桃av一区二区三区 | 91免费福利视频 | 国产精品久久久久久婷婷天堂 | 日韩成人av在线 | 超级乱淫av片免费播放 | 毛片视频网址 | 日韩免费在线视频 | 特级毛片| www.日日干 | 8x国产精品视频一区二区 | 久久精品综合 | 国产丝袜一区二区三区免费视频 | 午夜不卡福利视频 | 亚洲国产精品人人爽夜夜爽 | 毛片入口 | 国产精品国产a | 精品无码久久久久国产 | 一区二区在线免费播放 | 免费一区二区三区 | 精品国产乱码久久久久久1区2区 | 九九精品网 | 国产精品免费一区二区 | 国产第二页 |