1 背景
運維新同學在預發環境操作刪除pod的時候,不知道什么原因把kubectl delete pod命令敲成了kubectl delete ns pre把預發環境刪了,幾十個模塊,將近一個小時才恢復。幸虧是測試環境啊,如果是生產可以可以跑路了。
2?解決方案
通過kubectl操作k8s資源把數據發給apiserver,在apiserver把數據持久化到etcd之前我們可以通過MutatingWebhook修改、攔截相關資源的變更。
所以我們可以通過實現MutatingWebhook
機制,控制高危的操作。
方案一:自己實現MutatingWebhook
保護k8s資源不被刪除,這個具體實現大家參考作者之前寫的文章實現。
方案二:阿里開源的OpenKruise
已經幫我們實現相關資源的刪除保護。他的實現原理也是基于webhook
實現。
下面我們重點實踐基于OpenKruise
資源刪除保護。
2.1?OpenKruise 刪除保護實踐
2.1.1?OpenKruise架構
-
API:所有 OpenKruise 的功能都是通過 Kubernetes API 來提供
-
Manager:Kruise-manager 是一個運行 controller 和 webhook 中心組件,它通過 Deployment 部署在 kruise-system 命名空間中。資源保護主要是
kruise-controller-manager
的實現的webhook
功能。 - Daemon:DaemonSet 部署到每個 Node 節點上,提供鏡像預熱、容器重啟等功能。
2.1.2 k8s集群在線部署OpenKruise
建議采用 helm v3.5+ 來安裝 Kruise,,helm 是一個簡單的命令行工具可以從?這里?獲取。
#?Firstly?add?openkruise?charts?repository?if?you?haven't?do?this.
$?helm?repo?add?openkruise?https://openkruise.github.io/charts/#?[Optional]
$?helm?repo?update#?Install?the?latest?version.
$?helm?install?kruise?openkruise/kruise?--version?1.5.0
通過上述辦法可以在線部署OpenKruise
。
大部分同學的線上環境是沒有外網的,下面我們看看離線部署方式。
2.1.3?k8s集群離線部署OpenKruise
下載最新穩定版OpenKruise,作者沒有大家helm倉庫,這里使用gitlab管理kruise
#?Firstly?add?openkruise?charts?repository?if?you?haven't?do?this.
$?helm?repo?add?openkruise?https://openkruise.github.io/charts/#?[Optional]
$?helm?repo?update#?download?the?latest?version.
$?helm?pull?openkruise/kruise?--version?1.5.0
在當前目錄下有kruise-1.5.0.tgz
解壓縮,并修改鏡像地址為你倉庫地址
tar?kruise-1.5.0.tgz
cd?kruisevim?values.yaml
image:repository:?yourharbor.domain.com/openkruise/kruise-managertag:?v1.5.0
注意:作者這里kruise
?上傳到gitlab管理,如果你有helm倉庫可以放到自己的helm倉庫。
下載鏡像,并上傳自己的harbor倉庫
docker?pull?openkruise/kruise-manager:v1.5.0docker?tag?openkruise/kruise-manager:v1.5.0?yourharbor.domain.com/openkruise/kruise-manager:v1.5.0?docker?push?yourharbor.domain.com/openkruise/kruise-manager:v1.5.0?
在master節點上部署OpenKruise
git?clone?yourgit.domain.com/kruise.githelm?install?kruise?kruise/
至此,離線版安裝OpenKruise
就完成了。
部署完后,效果如下有kruise-controller-manager
和kruise-daemon
kubectl??get?pod?-n?kruise-system
NAME?????????????????????????????????????????READY???STATUS????RESTARTS???AGE
kruise-controller-manager-6d7bfd75wf-4s6jk???1/1?????Running???0??????????4h23m
kruise-controller-manager-6d7bfd75wf-dstl5???1/1?????Running???0??????????6h21m
kruise-daemon-tnfd8??????????????????????????1/1?????Running???0??????????6h21m
2.2 保護的資源類型
2.2.1?保護的資源都有哪些?
目前支持的資源如下:
Kind | Group | Version | Cascading judgement |
Namespace | core | v1 | namespace |
CustomResourceDefinition | apiextensions.k8s.io | v1beta1, v1 | CRD下是否還有存量的 CR |
Deployment | apps | v1 | replicas 是否為 0 |
StatefulSet | apps | v1 | replicas 是否為 0 |
ReplicaSet | apps | v1 | replicas 是否為 0 |
CloneSet | apps.kruise.io | v1alpha1 | replicas 是否為 0 |
StatefulSet | apps.kruise.io | v1alpha1, v1beta1 | replicas 是否為 0 |
UnitedDeployment | apps.kruise.io | v1alpha1 | replicas 是否為 0 |
2.2.2?怎么開啟資源保護?
在以上資源上加上標簽policy.kruise.io/delete-protection=Always
?或?policy.kruise.io/delete-protection=Cascading
,即實現了對相應資源的的保護.
Always:?這個對象禁止被刪除,除非上述?label?被去掉
Cascading:?這個對象如果還有可用的下屬資源,則禁止被刪除
2.2.3 案例實戰
2.2.3.1?Always(對象禁止被刪除)
test
?namespace 打上label?policy.kruise.io/delete-protection=Cascading
后,不管test
?namespace下是否有資源都不允許刪除test
,除非把標簽去掉。
kubectl??label?ns?nohost?policy.kruise.io/delete-protection=Always
kubectl??delete?ns?testError?from?server:?admission?webhook?"vnamespace.kb.io"?denied?the?req
2.2.4 Cascading(當刪除對象還有其他資源是不讓刪)
test
?namespace下還有一個pod,所以當設置label是policy.kruise.io/delete-protection=Cascading
,刪除test
?不允許刪除,這樣就對test
?namespace 起到保護的作用。
kubect?label?ns?test?policy.kruise.io/delete-protection=Cascading?--overwrite
kubectl??delete?ns?testError?from?server:?admission?webhook?"vnamespace.kb.io"?denied?the?request:?forbidden?by?ResourcesProtectionDeletion?for?policy.kruise.io/delete-protection=Cascading?and?active?pods?1>0
如果把test
?namespace 下的所有pod都刪掉,test
?可以被delete
掉。
2.3 OpenKruise 資源保護缺點
支持的資源有限,通過 webhook configuration 的 objectSelector 字段, Kruise webhook 只會攔截處理帶有?policy.kruise.io/delete-protection
?標簽的?Namespace/CustomResourceDefinition/Deployment/StatefulSet/ReplicaSet
?資源。