本篇文章已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
可延伸的許可控制為 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 分為兩個階段
- Mutation,允許修改主體內容本身以及拒絕 API 請求。
- 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,例如 metrics、service-catalog 或 kube-projects,而無需重新編譯它們。兩種 admission webhook 都會在各自鏈的末端執行,並且具有與編譯 admission 外掛程式相同的權限和限制。
它們有什麼好處?
Webhook admission 外掛程式允許對任何 API 伺服器上的任何資源進行 mutation 和 validation,因此可能的應用非常廣泛。一些常見的用例包括
- 資源(如 pod)的 Mutation。Istio 已經討論過這樣做,將 side-car 容器注入到 pod 中。您也可以編寫一個外掛程式,強制將映像標籤解析為映像 SHA。
- 名稱限制。在多租戶系統上,保留命名空間已成為一個用例。
- 複雜的 CustomResource 驗證。由於整個物件都是可見的,因此聰明的 admission 外掛程式可以對相依欄位(A 需要 B)甚至外部資源(與 LimitRanges 比較)執行複雜的驗證。
- 安全回應。如果您強制將映像標籤設為映像 SHA,則可以編寫一個 admission 外掛程式,以防止某些 SHA 執行。
註冊
兩種型別的 Webhook admission 外掛程式都在 API 中註冊,並且所有 API 伺服器(kube-apiserver 和所有擴充 API 伺服器)都共享它們的通用設定。在註冊過程中,webhook admission 外掛程式會描述
- 如何連線到 webhook admission 伺服器
- 如何驗證 webhook admission 伺服器(它真的是我期望的伺服器嗎?)
- 在該伺服器上傳送資料的位置(哪個 URL 路徑)
- 它將處理哪些資源和哪些 HTTP 動詞
- 連線失敗時 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 伺服器是否具有授權來發出請求 有三種主要的連線類別
- 從 kube-apiserver 或擴充 apiserver 到外部託管的 admission webhook(webhook 未託管在叢集中)
- 從 kube-apiserver 到自我託管的 admission webhook
- 從擴充 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-apiserver 和 kubernetes-namespace-reservation 專案,以取得程式庫以及如何建構您自己的安全且可攜式 webhook admission 伺服器的範例。
透過 1.9 中引入的 admission webhook,我們使 Kubernetes 更加適應您的需求。我們希望這項由 Red Hat 和 Google 共同推動的工作能夠支援更多的工作負載和生態系統元件。(Istio 就是一個例子。)現在是嘗試的好時機!
如果您有興趣提供回饋或為此領域做出貢獻,請加入我們的 SIG API machinery。