本篇文章已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

可延伸的許可控制為 Beta 版

在這篇文章中,我們回顧了 Kubernetes API 伺服器中的一項功能,該功能可讓您實作任意控制決策,並且在 Kubernetes 1.9 中已顯著成熟。

API 伺服器處理的 admission 階段是透過限制可以建立的物件來保護 Kubernetes 叢集的最強大工具之一,但它一直僅限於編譯程式碼。在 1.9 中,我們將 admission 的 webhook 提升為 beta 版,讓您可以從 API 伺服器程序外部利用 admission。

什麼是 Admission?

Admission處理 API 伺服器請求 的階段,發生在資源持久化之前,但在授權之後。Admission 可以存取與授權相同的資訊(使用者、URL 等)以及 API 請求的完整主體(對於大多數請求)。

admission 階段由個別外掛程式組成,每個外掛程式都專注於狹隘的範圍,並且具有正在檢查內容的語義知識。範例包括:PodNodeSelector(影響排程決策)、PodSecurityPolicy(防止容器升級)和 ResourceQuota(強制執行每個命名空間的資源分配)。

Admission 分為兩個階段

  1. Mutation,允許修改主體內容本身以及拒絕 API 請求。
  2. Validation,允許內省查詢和拒絕 API 請求。admission 外掛程式可以同時位於這兩個階段,但所有 mutation 都發生在 validation 之前。

Mutation

admission 的 mutation 階段允許在資源持久化之前修改資源內容。由於同一個欄位在 admission 鏈中可能會被多次修改,因此 mutation 中 admission 外掛程式的順序很重要。

mutating admission 外掛程式的一個範例是 PodNodeSelector 外掛程式,它使用命名空間上的註解 namespace.annotations[“scheduler.alpha.kubernetes.io/node-selector”] 來尋找標籤選擇器並將其新增至 pod.spec.nodeselector 欄位。這正面地限制了特定命名空間中的 pod 可以登陸的節點,而不是污點,污點提供負面限制(也使用 admission 外掛程式)。

Validation

admission 的 validation 階段允許在特定 API 資源上強制執行不變性。validation 階段在所有 mutator 完成後執行,以確保資源不會再次變更。

validation admission 外掛程式的一個範例也是 PodNodeSelector 外掛程式,它確保所有 pod 的 spec.nodeSelector 欄位都受到命名空間上節點選擇器限制的約束。即使 mutating admission 外掛程式嘗試在 PodNodeSelector 在 mutating 鏈中執行後變更 spec.nodeSelector 欄位,驗證鏈中的 PodNodeSelector 也會阻止建立 API 資源,因為它無法通過驗證。

什麼是 admission webhook?

Admission webhook 允許 Kubernetes 安裝程式或叢集管理員將 mutating 和 validating admission 外掛程式新增至 kube-apiserver 的 admission 鏈,以及任何基於 k8s.io/apiserver 1.9 的擴充 apiserver,例如 metricsservice-catalogkube-projects,而無需重新編譯它們。兩種 admission webhook 都會在各自鏈的末端執行,並且具有與編譯 admission 外掛程式相同的權限和限制。

它們有什麼好處?

Webhook admission 外掛程式允許對任何 API 伺服器上的任何資源進行 mutation 和 validation,因此可能的應用非常廣泛。一些常見的用例包括

  1. 資源(如 pod)的 Mutation。Istio 已經討論過這樣做,將 side-car 容器注入到 pod 中。您也可以編寫一個外掛程式,強制將映像標籤解析為映像 SHA。
  2. 名稱限制。在多租戶系統上,保留命名空間已成為一個用例。
  3. 複雜的 CustomResource 驗證。由於整個物件都是可見的,因此聰明的 admission 外掛程式可以對相依欄位(A 需要 B)甚至外部資源(與 LimitRanges 比較)執行複雜的驗證。
  4. 安全回應。如果您強制將映像標籤設為映像 SHA,則可以編寫一個 admission 外掛程式,以防止某些 SHA 執行。

註冊

兩種型別的 Webhook admission 外掛程式都在 API 中註冊,並且所有 API 伺服器(kube-apiserver 和所有擴充 API 伺服器)都共享它們的通用設定。在註冊過程中,webhook admission 外掛程式會描述

  1. 如何連線到 webhook admission 伺服器
  2. 如何驗證 webhook admission 伺服器(它真的是我期望的伺服器嗎?)
  3. 在該伺服器上傳送資料的位置(哪個 URL 路徑)
  4. 它將處理哪些資源和哪些 HTTP 動詞
  5. 連線失敗時 API 伺服器應執行的操作(例如,如果 admission webhook 伺服器關閉)
1 apiVersion: admissionregistration.k8s.io/v1beta1  
2 kind: ValidatingWebhookConfiguration  
3 metadata:  
4   name: namespacereservations.admission.online.openshift.io  
5 webhooks:  
6 - name: namespacereservations.admission.online.openshift.io  
7   clientConfig:  
8     service:  
9       namespace: default  
10      name: kubernetes  
11     path: /apis/admission.online.openshift.io/v1alpha1/namespacereservations  
12    caBundle: KUBE\_CA\_HERE  
13  rules:  
14  - operations:  
15    - CREATE  
16    apiGroups:  
17    - ""  
18    apiVersions:  
19    - "\*"  
20    resources:  
21    - namespaces  
22  failurePolicy: Fail

第 6 行:name - webhook 本身的名稱。對於 mutating webhook,這些會排序以提供順序。
第 7 行:clientConfig - 提供有關如何連線、信任 webhook admission 伺服器以及向其傳送資料的資訊。
第 13 行:rules - 描述 API 伺服器何時應呼叫此 admission 外掛程式。在這種情況下,僅適用於命名空間的建立。您可以在此處指定任何資源,因此指定 serviceinstances.servicecatalog.k8s.io 的建立也是合法的。
第 22 行:failurePolicy - 說明如果 webhook admission 伺服器不可用時該怎麼辦。選項為「Ignore」(失敗時開放)或「Fail」(失敗時關閉)。失敗時開放會為所有用戶端造成不可預測的行為。

驗證和信任

由於 webhook admission 外掛程式具有很大的權限(請記住,它們可以查看傳送給它們的任何請求的 API 資源內容,並且可能會為 mutating 外掛程式修改它們),因此務必考慮

  • 個別 API 伺服器如何驗證它們與 webhook admission 伺服器的連線
  • webhook admission 伺服器如何精確地驗證哪個 API 伺服器正在聯絡它
  • 該特定 API 伺服器是否具有授權來發出請求 有三種主要的連線類別
  1. 從 kube-apiserver 或擴充 apiserver 到外部託管的 admission webhook(webhook 未託管在叢集中)
  2. 從 kube-apiserver 到自我託管的 admission webhook
  3. 從擴充 apiserver 到自我託管的 admission webhook 為了支援這些類別,webhook admission 外掛程式接受 kubeconfig 檔案,該檔案描述如何連線到個別伺服器。對於與外部託管的 admission webhook 互動,由於驗證/授權和存取路徑歸您要掛接的伺服器所有,因此實際上沒有手動設定該檔案的替代方案。

對於自我託管類別,巧妙建構的 webhook admission 伺服器和拓撲可以利用 admission 外掛程式中內建的安全預設值,並具有安全、可攜式、零設定拓撲,可從任何 API 伺服器運作。

簡單、安全、可攜式、零設定拓撲

如果您將 webhook admission 伺服器也建構為擴充 API 伺服器,則可以將其彙總為正常的 API 伺服器。這有許多優點

  • 您的 webhook 像任何其他 API 一樣在預設 kube-apiserver 服務 kubernetes.default.svc 下可用(例如 https://kubernetes.default.svc/apis/admission.example.com/v1/mymutatingadmissionreviews)。在其他優點中,您可以使用 kubectl 進行測試。
  • 您的 webhook 自動(無需任何設定)使用 kube-apiserver 提供的叢集內驗證和授權。您可以使用正常的 RBAC 規則來限制對 webhook 的存取。
  • 您的擴充 API 伺服器和 kube-apiserver 自動(無需任何設定)使用它們的叢集內憑證與 webhook 通訊。
  • 擴充 API 伺服器不會將其服務帳戶權杖洩漏到您的 webhook,因為它們會通過 kube-apiserver,後者是安全的前端 Proxy。


來源:https://drive.google.com/a/redhat.com/file/d/12nC9S2fWCbeX_P8nrmL6NgOSIha4HDNp

簡而言之:安全的拓撲利用 API 伺服器彙總的所有安全機制,並且額外地不需要額外的設定。

其他拓撲是可能的,但需要額外的手動設定以及大量的工作來建立安全的設定,尤其是當服務目錄等擴充 API 伺服器發揮作用時。上面的拓撲是零設定且可移植到每個 Kubernetes 叢集。

如何編寫 webhook admission 伺服器?

編寫完整的伺服器,包括驗證和授權,可能會讓人望而生畏。為了使其更容易,有一些基於 Kubernetes 1.9 的專案提供了一個程式庫,用於在 200 行或更少的程式碼中建構您的 webhook admission 伺服器。查看 generic-admission-apiserverkubernetes-namespace-reservation 專案,以取得程式庫以及如何建構您自己的安全且可攜式 webhook admission 伺服器的範例。

透過 1.9 中引入的 admission webhook,我們使 Kubernetes 更加適應您的需求。我們希望這項由 Red Hat 和 Google 共同推動的工作能夠支援更多的工作負載和生態系統元件。(Istio 就是一個例子。)現在是嘗試的好時機!

如果您有興趣提供回饋或為此領域做出貢獻,請加入我們的 SIG API machinery