Kubernetes可擴充套件Admission進入Beta階段

店家小二發表於2018-12-14

Kubernetes API Server 中有一個功能,能讓使用者(對工作負載)進行決策,這一功能在 1.9 中已經走入成熟期。

Admission 是 Kubernetes 中最強大的工具之一,可以通過限制建立物件的方式來增強 Kubernetes 叢集的安全性,這部分一直是編譯在程式碼之中的。在 1.9 中,我們將 Admission 的 Webhook 升級成 Beta,讓使用者可以在 API Server 之外對 Admission 施加影響。

Admission 是什麼?

Admission(注1),是在認證之後,資源持久化之前 的一個處理 API Server 請求的步驟。Admission 能獲取到和認證過程一致的資訊(使用者、URL 等),以及絕大多數 API 請求的完整報文。

Admission 階段由不同外掛組成,每個 Admission 都會對一個側面進行觀察和操作。例如:影響排程決策的PodNodeSelector、阻止惡意容器的PodSecurityPolicy以及實現 Namespace 資源分配的ResourceQuota。

Admission 內部分為兩個階段:

  1. 變更(Mutation,突變?):能夠修改 API 請求的報文,還可以拒絕 API 請求。
  2. 驗證:允許進行查詢,以及拒絕 API 請求。

Admission 外掛可以在這兩個階段起作用,但是變更總是在驗證之前。

Mutation

Admission 的變更功能可以在資源生成之前進行修改。在 Admission 鏈條上可以多次修改同一個欄位,因此外掛不是無序的。

PodNodeSelector就是一個例子,他使用 Namespace 的一個註解namespace.annotations[“scheduler.alpha.kubernetes.io/node-selector”],在其中查詢標籤選擇器,並將其加入pod.spec.nodeselector欄位。這一功能限制某個 Namespace 的 Pod,只能執行在指定節點上,同 Taint 的功能正好相反(也是 Admission 外掛)。

驗證

Admission 的驗證階段用來對特定 API 資源進行驗證。這一階段會在所有變更執行結束之後,API 資源不再發生變化的情況下進行。

PodNodeSelector外掛同樣演示了這一活動,他確保 Pod 的spec.nodeSelector欄位符合該 Namespace 的限制。如果變更鏈上有其他 Admission 嘗試在PodNodeSelector之後修改了資源的spec.nodeSelector,就會在驗證階段因為不符合限制而被拒絕建立。

Admission Webhook 是什麼?

Admission webhook 允許 Kubernetes 安裝者或叢集管理員無需重新編譯就可以加入 Admission 外掛,像其他基於 k8s.io/apiserver 1.9 的擴充套件 API Server(例如 metrics(注 2), service-catalog(注 3) 、以及 kube-projects(注 4))一樣。兩種 Admission Webhook 都在各自的鏈條尾端執行,和編譯的 Admission 外掛具有同樣的能力和限制。

有什麼好處?

Webhook Admission 外掛允許對任何 API Server 的任何資源進行變更和驗證,所以可能有多種形態的應用,比較普通的用例包括:

  1. 修改 Pod 這樣的資源。Istio 使用這一功能來把 Sidecar 注入到 Pod 之中。當然也可以編寫外掛強制把 Image Tag 改寫為 Image SHA。
  2. 在多租戶系統中,保留名稱空間是一個常見情況。
  3. 複雜的 CustomResource 校驗。對外掛來說,整個資源都是可見的,因此可以對依賴欄位甚至外部依賴資源進行復雜的校驗(例如 LimitRanges)。
  4. 安全響應。可以編寫一個外掛,強制將 Image Tag 轉換為 Image SHA,並阻止特定的 Image 執行。

註冊

Webhook Admission 外掛需要註冊,所有的 API Server(Kube API server 以及所有擴充套件 API Server)都共享一個配置。在註冊過程中外掛需要提供如下資訊:

  1. 如何連線到 Webhook Admission 服務。
  2. 如何驗證 Webhook Admission Server。
  3. 把請求傳送到這個伺服器的哪裡(URL)。
  4. 處理哪些資源和 HTTP 動詞。
  5. 如果連線失敗,API Server 怎麼辦。
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
 name: namespacereservations.admission.online.openshift.io
webhooks: - name: namespacereservations.admission.online.openshift.io
 clientConfig:
 service: namespace: default
 name: kubernetes
 path: /apis/admission.online.openshift.io/v1alpha1/namespacereservations
 caBundle: KUBE_CA_HERE
 rules: - operations: - CREATE
 apiGroups: - ""
 apiVersions: - "*"
 resources: - namespaces
 failurePolicy: Fail

name:Webhook 的名稱。變更類的 Hook 會使用名稱進行排序。 clientConfig:如何連線,證書信任,以及如何向 Webhook Admission 伺服器傳送資料。 rules:API Server 應該在什麼時機呼叫 Webhook。這裡只有建立 Namespace 的時候才觸發。這裡可以指定任何資源,例如serviceinstances.servicecatalog.k8s.io的create操作也是可以定義的。 failurePolicy:如果 Webhook Admission 伺服器無法連線,如何處置?有兩個選項分別是 ”Ignore“(失敗就通過) 和 ”Fail“(失敗就拒絕)。失敗則通過的設定,可能會導致無法預測的行為。

認證和信任

因為 Webhoo Admission 外掛能夠獲取任何傳送過來的請求資源的內容,並且能進行變更,所以很有必要回答下面的問題:

  • API Server 如何檢驗 Webhook Admission Server。
  • Webhook Server 如何精確認證接入進來的 API Server。
  • 接入的 API Server 是否被授權傳送請求。

連線主要分為三種:

  1. 從 Kube API Server 以及擴充套件 API Server 到外部的 Admission Webhook(可能是部署在叢集之外)。
  2. 從 Kube API Server 到自有 Admission Webhooks。
  3. 從擴充套件 API Server 到自有 Admission Webhooks。

要支援這些類別,Webhook Admission 外掛可以用一個 kubeconfig 檔案來得知如何連線到獨立的伺服器。為了和外部的 Admission Webook 進行通訊,因為認證、授權都是外部伺服器處理的,因此只能手工指定,別無他法。

自有服務來說,一個明智的外掛會提供預設的安全設施,提供簡單、安全、可移植、零配置,並可以在各個 API Server 執行的能力。

簡單、安全、可移植、零配置

如果把 Webhook Admission 伺服器構建成擴充套件 API Server 的模式,就有可能把它聚合為一個普通的 API 伺服器,會收到如下益處:

  • 你的 Webhook 會和其他 API 一樣,以類似 kube-apiserver kubernetes.default.svc (例如 https://kubernetes.default.svc/apis/admission.example.com/v1/mymutatingadmissionreviews)服務的面目出現。可以使用kubectl進行測試。
  • 無需任何配置,你的 Webhook 自動具有了叢集內建的認證和授權能力,可以使用 RBAC 規則進行訪問控制。
  • API Server 和 Webhook 之間可以直接使用內建認證進行通訊。
  • 因為通過 Kube API Server 代理通訊,因此擴充套件 API Server 不會洩露 Service Account Token。

簡單說來,這一安全拓撲可以使用 API Server 的所有安全機制,並且無需額外配置。

其他用法也是可以的,不過就需要附加的手工配置,以及大量的額外工作來完成同等目標。

如何開發 Webhook admission 伺服器?

編寫一個具有認證和鑑權能力的完整的服務是個令人生畏的任務。為簡化這一工作,有些基於 Kubernetes 1.9 的專案提供了庫支援,能把程式碼量縮減到兩百行甚至更少。可以參考 generic-admission-apiserver(注 5)以及 kubernetes-namespace-reservation(注 6)作為建立自己的安全、可移植的 Webhook Server 的示例。

在 1.9 中有了 Admission Webhook,讓 Kubernetes 更加貼近使用者需求,我們希望 Red Hat 和 Google 的這一工作能讓支援更多的工作負載,為整體生態貢獻更多(例如 Istio),現在是時候試一試了!

本文轉自kubernetes中文社群-Kubernetes 可擴充套件 Admission 進入 Beta 階段


相關文章