古詩詞大全網 - 藝術簽名 - k8s的變異webhook

k8s的變異webhook

準入Webhook是api-server提供的壹個擴展功能。作為kubernetes的核心,幾乎所有組件都需要處理它。基本上妳可以通過控制k8s的api-server來控制k8s的行為。

在早期版本中,api-server沒有提供admissionresgistration的能力(v1.9之前)。當我們想控制k8s的時候,只能重新編譯api-server。例如,您想要停止控制器的行為或攔截控制器的資源修改。Admission webhook提供了這樣壹種能力,比如妳想在創建帶有特定標簽label的pod時註入sidercar,或者阻止不兼容的資源。

準入Webhook包括兩種CRD:變異webhook配置和驗證web hook配置。

以下是mutatingwebhookconfiguration的CRD文件:

準入Webhook的本質是api-server的壹個webhook調用,下面是api-server的處理流程:

api-server讀取mutatingwebhookconfiguration和validatingwebhookconfiguration的CR文件的目標地址,然後回調自定義服務。

api-server發起的請求是json數據格式的字符串,頭需要設置content-type為application/json。讓我們看看請求的正文:

返回的結果:

這裏的補丁是base64編碼的json。我們來解碼壹下,看看是不是json補丁:

處理功能:

主程序:

基於私鑰生成證書簽名請求(CSR),目標地址的域名為mutating-test . testing-tools . SVC,CSR的配置:

創建命令:

基於csr創建CertificateSigningRequest:

認證完成後,您可以查看:

生成證書:

獲取api服務器的CA證書:

將此證書填在網鉤的盒子裏。

作為kubernetes的ApiServer中接納控制器的壹部分,MutatingAdmissionWebhook提供了非常靈活的擴展機制。通過配置MutatingWebhookConfiguration對象,理論上可以監聽和修改ApiServer處理的任何請求。

MutatingWebhookConfiguration是kubernetes的壹個官方資源提供的對象。以下是該對象字段的壹些簡單描述:

結合rules.operations和rules.resources的屬性可以知道,示例中的MutatingWebhookConfiguration監聽集群中節點資源的狀態數據向apiServer提交的更新操作(也就是我們前面提到的心跳信息)。並且所有的心跳信息都被發送到名為webhook-oversale-service的服務下的/mutate接口,這個服務是由我們定制的webhook服務提供的。

上圖中Pod運行的容器是我們的自定義webhook服務,有壹個自定義webhook服務的樣本供參考。

在生產環境中,有許多PODs運行在kubernetes集群的計算節點上,分別運行各種業務容器。我們通常使用Deployment、DeamonSet、StatefulSet等資源對象來控制PODs的添加、刪除和修改。所以開發或者運維往往需要在這些資源對象的Containers字段配置業務容器的CPU和內存的資源配額:requests和limit。

請求:節點調度pod需要的資源,每次調度成功後重新計算節點的可分配屬性值(可分配資源)。

新的可分配值=舊的可分配值-設置請求值

Limit:在壹個節點上運行pod可以獲得的最大資源,當cpu

不難發現,當requests字段設置過大時,pod實際使用的資源非常少,導致計算節點的可分配值被快速消耗,節點的資源利用率會變得非常低。

上圖中最大的藍框是計算節點的可分配資源,橙框(requests)是用戶配置的請求屬性,紅框(current)是業務容器實際使用的資源。因此,節點的資源利用率是當前的/可分配的。但是由於requests設置太大,充滿了可分配性,新的pod無法調度到這個節點,會出現節點實際資源占用低,但是pod因為可分配性太低而無法調度到這個節點的現象。

所以,是否可以通過動態調整allocable的值,讓計算節點的可分配資源變得“虛高”,忽悠k8s調度器以為節點的可分配資源非常大,從而將盡可能多的PODs調度到節點上?

在上圖中,通過偽造allcatable值將更多的PODs調度到修改後的節點,節點的當前/可分配資源利用率變大。

實現資源超售的關鍵是動態修改節點對象的可分配字段的值,但是我們看到可分配字段屬於狀態字段,顯然不能用kubectl edit命令直接修改。因為Status字段不同於Spec字段,Spec是用戶設置的預期數據,而Status是實際數據(節點通過不斷向apiServer發送心跳來更新自己的實時狀態,最終存在於etcd中)。那麽我們如何修改Stauts字段呢?

首先,要修改k8s中任何資源對象的狀態值,k8s官方提供了壹套restful API:es . io/docs/reference/generated/kubernetes-API/v 1.13。

可以通過patch或put方法調用k8s的RESTful API來修改Stauts字段。(這裏,保存在etcd中的Status字段的值是通過ApiServer修改的。)

但是節點資源對象比較特殊,計算節點會不斷的向ApiServer發送心跳(默認每10s),向ApiServer發送帶有狀態字段的真實信息,並更新到etcd。也就是說,無論妳如何通過patch/put方法修改節點的狀態字段,計算節點都會每隔壹段時間用心跳覆蓋真實的狀態數據,也就是說我們無法通過直接調用RESTful API來修改節點對象中的狀態數據。

那麽,是否可以通過修改心跳數據中狀態字段的可分配值,直接監控這個計算節點的心跳數據,實現資源超售?

答案是肯定的。k8s在ApiServer中提供了準入控制器機制,包括MutatingAdmissionWebhook。通過這個webhook,集群中所有與ApiSever交互的請求都被發送到指定的接口。我們只需要提供這樣壹個接口,就可以得到節點發送給ApiServer的心跳的Staus數據。然後我們自己修改這個數據,再發回給etcd,讓etcd認為我們修改的狀態數據就是節點的真實狀態,最終實現資源的超售。

眾所周知,Istio的流量管理、策略、遙測等功能不需要在應用上做任何改動,這種無創的方式完全依賴於Sidecar。應用程序發送或接收的流量被Sidecar攔截,Sidecar執行許多治理功能,如認證、驗證、策略執行和遙測數據報告。

如圖,在Kubernetes中,Sidecar容器和應用程序容器* * *存儲在同壹個Pod中,並且* * *共享相同的網絡命名空間,所以Sidecar容器和應用程序容器* * *共享相同的網絡協議棧,這是Sidecar能夠通過iptables攔截應用程序的導入導出流量的根本原因。

Istio的邊車模型

Istio中註入Sidecar有兩種方式:壹種是通過istioctl命令行工具手動註入;另壹種是通過Istio邊車註射器自動註射。

這兩種方法的最終目標是將兩個Sidecar容器,init容器和istio-proxy容器,註入到應用程序Pod中。如下圖,通過部署Istio的睡眠應用,Sidecar通過sidecar-injector自動註入。檢查註入的邊車容器:

邊車註射器是Istio中實現邊車自動註射的組件,以Kubernetes的準入控制器形式運行。準入控制器的基本工作原理是攔截Kube-apiserver的請求,在對象持久化之前和認證之後進行攔截。有兩種準入控制器:壹種是內置的,另壹種是用戶自定義的。Kubernetes允許用戶通過Webhook定制準入控制器,Sidecar Injector就是這樣壹個特殊的MutatingAdmissionWebhook。

如圖所示,邊車註入器僅在創建Pod時註入邊車容器。Pod的創建請求到達Kube-apiserver後,首先進行認證,然後在準入控制階段,Kube-apiserver同步調用Sidecar註入器Webhook服務,以REST方式註入init和istio-proxy容器,最後將Pod對象持久化存儲在etcd中。

邊車註射器可以通過動態配置變異的Webhook配置API生效。Istio中的變異Webhook配置如下:

從上面的配置可以看出,Sidecar Injector只對標簽匹配“istio-injection: enabled”的名稱空間中的Pod資源對象的創建有效。Webhook服務的訪問路徑是“/inject”,地址和訪問憑證都在clientConfig字段下配置。

Istio Sidecar Injector組件是通過sidecar-injector進程實現的,本書後面會把它們作為同壹個概念來處理。邊車註射器的實現主要由兩部分組成:

MutatingWebhookConfiguration對象的維護主要指監控本地證書和Kubernetes MutatingWebhookConfiguration資源的變化,檢查CA證書或CA數據是否更新,當本地CA證書與MutatingWebhookConfiguration中的CA證書不壹致時,自動更新MutatingWebhookConfiguration對象。