1. 程式人生 > >Kubernetes 新概念 “Initializers”解析(中):能讓你為叢集編寫外掛的新模型_Kubernetes中文社群

Kubernetes 新概念 “Initializers”解析(中):能讓你為叢集編寫外掛的新模型_Kubernetes中文社群

Kubernetes v1.7 新增了 Initializers,它可以用來方便地擴充套件准入控制,今天的文章來自 Google Kubernetes 現役工程師 Ahmet Alp Balkan,讓他帶領我們詳解 Initializer。通過上期的文章,我們瞭解了 Initializers 的相關屬性,今天的內容讓我們進一步探索Initializers 的相關屬性和操作流程。

initialization 剖析

1.配置需要 initialization 的資源型別 :

InitializerConfiguration(https://kubernetes.io/docs/admin/extensible-admission-controllers/#configure-initializers-on-the-fly) 物件允許你配置被 initializers 分配到的資源型別。

舉個例子來說,你可以進行建立,將“myproxy”initializer 新增到型別apps/v1beta1.Deployment 和 v1.DeamonSet 物件中。你可以儘可能多地建立 InitializerConfigurations,它們將適用於所有名稱空間  。

2.API 伺服器將為新資源分配 initializers

當你向 apiserver 提交 Deployment 物件時,將更新 Deployment 的metadata.initalizers.pending 並在其中新增“myproxy”值。此欄位顯示當前分配給資源的initializers 。

準確的說,不是由 apiserver 新增 initializers。有一個名為“Initializer”的准入控制外掛,這使整個 initialization流程成為可能。它通過將 –admission-controller=Initializer 標誌新增到 kube-apiserver 來進行啟用 。

3.可以編寫一個控制器來檢測資源情況:

你開發並部署到叢集的自定義控制器使用Watch API 來對新的資源進行監聽,捕獲並進行所需的修改。

4.等待修改資源的輪次:

一旦你的控制器通過 Watch API 攔截一個物件,它只能修改物件,如果它在初始化器列表(metadata.initializers.pending[0])的第一個元素上檢查到它的名字的話。否則,這意味著它是一些其他 initializers 修改資源的輪次,而現在應該跳過修改。

5.完成修改, 生成下一個 initializer。

完成對資源的修改後, 控制器應從物件的 metadata.initializers.pending 列表中刪除其名稱, 並將該物件儲存回 API 伺服器。

6.不存在更多 initializers 時, 資源準備好進行實現:

當 Kubernetes API 伺服器檢測到該物件沒有其他掛起的 initializers 時, 它會判定物件 “已initialized”。Kubernetes 排程程式和其他控制器可以檢測到完全 initialized 的物件並加以利用。

您可以同時在群集上執行多個 initializers。這些自定義控制器中的每一個都將收到有關對資源 (如 Pods) 的修改的通知,  但他們會等待輪次來對物件進行修改,直到他們在列表中檢測他們的名字。

Initializers:在 Kubernetes API 中進行實現

在不知道它們實際上是如何在 Kubernetes API 伺服器之下實現的情況下,你可以對 initializers 進行開發和部署 。我們來詳細討論一下它是如何在 Kubernetes API 中進行實現的:

簡而言之, 當一個 Pod 資源提交到 API 並被分配一個待定的 initializers 列表時, 直到 initialization 完成,它實際上都不會被安排。Kubernetes 排程程式, 這個所謂的排程程式其實是另一個控制器,檢測在 API 伺服器中顯示的 pod,並分配給每個節點。

那麼, 為什麼排程程式和其他控制器在初始化之前無法看到該物件, 即使該物件儲存在 API 伺服器 (和預計資料庫中), 並且對某些其他控制器 (即 initializers)可見?

答案是存在一個叫 includeUninitialized 的請求引數。此引數預設為 false, 因此, API 將未初始化的物件從預設客戶端(如 kubectl)和控制器 (如排程程式) 隱藏在 “監視” 或 “列表” 之類的請求中。所以你開發的 initializers 必須設定 includeUninitialized = true 查詢引數才能監測這些物件。

Initializers 阻止建立請求。當建立物件的請求提交到 API 伺服器時, 它不會馬上返回, 並且請求會一直被阻止, 直到 initialization 完成。如果使用的是 kubectl, 並且物件在 uninitialized 狀態下被阻止, 你會在30秒後發現 kubectl 超時。

作者簡介

Ahmet Alp Balkan

Kubernetes 和 Google 容器引擎現役工程師,負責開發開源軟體,精益開發經驗並傳播相應技術細節。