天天看點

kubebuilder實戰之七:webhook

https://github.com/zq2599/blog_demos

内容:所有原創文章分類彙總及配套源碼,涉及java、docker、kubernetes、devops等;

本文是《kubebuilder實戰》系列的第七篇,之前的文章咱們完成了一個operator的設計、開發、部署、驗證過程,為了讓整個過程保持簡潔并且篇幅不膨脹,實戰中刻意跳過了一個重要的知識點:webhook,如今是時候學習它了,這是個很重要的功能;

本篇由以下部分構成:

介紹webhook;

結合前面的elasticweb項目,設計一個使用webhook的場景;

準備工作

生成webhook

開發(配置)

開發(編碼)

部署

驗證defaulter(添加預設值)

驗證validator(合法性校驗)

熟悉java開發的讀者大多知道過濾器(servlet filter),如下圖,外部請求會先到達過濾器,做一些統一的操作,例如轉碼、校驗,然後才由真正的業務邏輯處理請求:

kubebuilder實戰之七:webhook

operator中的webhook,其作用與上述過濾器類似,外部對crd資源的變更,在controller處理之前都會交給webhook提前處理,流程如下圖,該圖來自《getting started with kubernetes | operator and operator framework》:

kubebuilder實戰之七:webhook

再來看看webhook具體做了哪些事情,如下圖,kubernetes官方部落格明确指出webhook可以做兩件事:修改(mutating)和驗證(validating)

kubebuilder實戰之七:webhook

kubebuilder為我們提供了生成webhook的基礎檔案和代碼的工具,與制作api的工具類似,極大地簡化了工作量,咱們隻需聚焦業務實作即可;

基于kubebuilder制作的webhook和controller,如果是同一個資源,那麼它們在同一個程序中;

為了讓實戰有意義,咱們為前面的elasticweb項目上增加需求,讓webhook發揮實際作用;

如果使用者忘記輸入總qps,系統webhook負責設定預設值1300,操作如下圖:

kubebuilder實戰之七:webhook

為了保護系統,給單個pod的qps設定上限1000,如果外部輸入的singlepodqps值超過1000,就建立資源對象失敗,如下圖所示:

kubebuilder實戰之七:webhook

本篇實戰中的完整源碼可在github下載下傳到,位址和連結資訊如下表所示(https://github.com/zq2599/blog_demos):

名稱

連結

備注

項目首頁

該項目在github上的首頁

git倉庫位址(https)

https://github.com/zq2599/blog_demos.git

該項目源碼的倉庫位址,https協定

git倉庫位址(ssh)

[email protected]:zq2599/blog_demos.git

該項目源碼的倉庫位址,ssh協定

這個git項目中有多個檔案夾,kubebuilder相關的應用在kubebuilder檔案夾下,如下圖紅框所示:

kubebuilder實戰之七:webhook

kubebuilder檔案夾下有多個子檔案夾,本篇對應的源碼在elasticweb目錄下,如下圖紅框所示:

kubebuilder實戰之七:webhook

和controller類似,webhook既能在kubernetes環境中運作,也能在kubernetes環境之外運作;

如果webhook在kubernetes環境之外運作,是有些麻煩的,需要将證書放在所在環境,預設位址是:

為了省事兒,也為了更接近生産環境的用法,接下來的實戰的做法是将webhook部署在kubernetes環境中

為了讓webhook在kubernetes環境中運作,咱們要做一點準備工作安裝cert manager,執行以下操作:

上述操作完成後會建立很多資源,如namespace、rbac、pod等,以pod為例如下:

操作完成後,準備工作結束,可以開始實戰了;

進入elasticweb工程下,執行以下指令建立webhook:

上述指令執行完畢後,先去看看main.go檔案,如下圖紅框1所示,自動增加了一段代碼,作用是讓webhook生效:

kubebuilder實戰之七:webhook

上圖紅框2中的elasticweb_webhook.go就是新增檔案,内容如下:

上述代碼有兩處需要注意,第一處和填寫預設值有關,如下圖:

kubebuilder實戰之七:webhook

第二處和校驗有關,如下圖:

kubebuilder實戰之七:webhook

咱們要實作的業務需求就是通過修改上述elasticweb_webhook.go的内容來實作,不過代碼稍後再寫,先把配置都改好;

打開檔案config/default/kustomization.yaml,下圖四個紅框中的内容原本都被注釋了,現在請将注釋符号都删掉,使其生效:

kubebuilder實戰之七:webhook

還是檔案config/default/kustomization.yaml,節點vars下面的内容,原本全部被注釋了,現在請全部放開,放開後的效果如下圖:

kubebuilder實戰之七:webhook

配置已經完成,可以編碼了;

打開檔案elasticweb_webhook.go

新增依賴:

找到default方法,改成如下内容,可見代碼很簡單,判斷totalqps是否存在,若不存在就寫入預設值,另外還加了兩行日志:

接下來開發校驗功能,咱們把校驗功能封裝成一個validateelasticweb方法,然後在新增和修改的時候各調用一次,如下,可見最終是調用apierrors.newinvalid生成錯誤執行個體的,而此方法接受的是多個錯誤,是以要為其準備切片做入參,當然了,如果是多個參數校驗失敗,可以都放入切片中:

再找到新增和修改資源對象時被調用的方法,在裡面調用validateelasticweb:

編碼完成,可見非常簡單,接下來,咱們把以前實戰遺留的東西清理一下,再開始新的部署和驗證;

如果您是随着《kubebuilder實戰》系列一路操作下來,此時系統上應該積攢了之前遺留的内容,可以通過以下步驟完成清理:

删除elasticweb資源對象:

删除controller

删除crd

現在萬事俱備,可以部署webhook了;

部署crd

建構鏡像并推送到倉庫(我終于受夠了hub.docker.com的龜速,改為阿裡雲鏡像倉庫):

部署內建了webhook功能的controller:

檢視pod,确認啟動成功:

修改檔案config/samples/elasticweb_v1_elasticweb.yaml,修改後的内容如下,可見totalqps字段已經被注釋掉了:

建立一個elasticweb資源對象:

此時單個pod的qps是500,如果webhook的代碼生效的話,總qps就是1300,而對應的pod數應該是3個,接下來咱們看看是否符合預期;

先看elasticweb、deployment、pod等資源對象是否正常,如下所示,全部符合預期:

用kubectl describe指令檢視elasticweb資源對象的詳情,如下所示,totalqps字段被webhook設定為1300,realqps也計算正确:

再來看看controller的日志,其中的webhook部分是否符合預期,如下圖紅框所示,發現totalqps字段為空,就将設定為預設值,并且在檢測的時候singlepodqps的值也沒有超過1000:

kubebuilder實戰之七:webhook

最後别忘了用浏覽器驗證web服務是否正常,我這裡的完整位址是:http://192.168.50.75:30003/

至此,咱們完成了webhook的defaulter驗證,接下來驗證validator

接下來該驗證webhook的參數校驗功能了,先驗證修改時的邏輯;

編輯檔案config/samples/update_single_pod_qps.yaml,值如下:

用patch指令使之生效:

此時,控制台會輸出錯誤資訊:

再用kubectl describe指令檢視elasticweb資源對象的詳情,如下圖紅框,依然是500,可見webhook已經生效,阻止了錯誤的發生:

kubebuilder實戰之七:webhook

再去看controller日志,如下圖紅框所示,和代碼對應上了:

kubebuilder實戰之七:webhook

接下來再試試webhook在新增時候的校驗功能;

清理前面建立的elastic資源對象,執行指令:

修改檔案,如下圖紅框所示,咱們将singlepodqps的值改為超過1000,看看webhook是否能檢查到這個錯誤,并阻止資源對象的建立:

kubebuilder實戰之七:webhook

執行以下指令開始建立elasticweb資源對象:

控制台提示以下資訊,包含了咱們代碼中寫入的錯誤描述,證明elasticweb資源對象建立失敗,證明webhook的validator功能已經生效:

不放心的話執行kubectl get指令檢查一下,發現空空如也:

還要看下controller日志,如下圖紅框所示,符合預期:

kubebuilder實戰之七:webhook

至此,operator的webhook的開發、部署、驗證咱們就完成了,整個elasticweb也算是基本功能齊全,希望能為您的operator開發提供參考;

java系列

spring系列

docker系列

kubernetes系列

資料庫+中間件系列

devops系列

微信搜尋「程式員欣宸」,我是欣宸,期待與您一同暢遊java世界...