kubernetes高階之動態准入控制

周國通發表於2019-06-25

系列目錄

動態准入控制器文件介紹瞭如何使用標準的,外掛式的准入控制器.但是,但是由於以下原因,外掛式的准入控制器在一些場景下並不靈活:

  • 它們需要編譯到kube-apiserver裡

  • 它們僅在apiserver啟動的時候可以配置

准入鉤子(Admission Webhooks 從1.9版本開始)解決了這些問題,它允許准入控制器獨立於核心程式碼編譯並且可以在執行時配置.

什麼是准入鉤子

准入鉤子是一種http回撥,它接收准入請求然後做一些處理.你可以定義兩種型別的准入鉤子:驗證鉤子變換鉤子.對於驗證鉤子,你可以拒絕請求以使自定義准入策略生效.對於變換鉤子,你可以改變請求來使自定義的預設配置生效.

體驗准入鉤子

准入控制鉤子是叢集管制皮膚不可缺少的一部分.你在編寫部署它們時必須要警惕.如果你想要編寫/佈置生產級別的准入控制器,請閱讀以下使用者指南.下面我們將介紹如何快速體驗准入鉤子.

準備工作:

  • 確保你的kubernetes叢集版本至少是1.9版本.

  • 確保變換鉤子(MutatingAdmissionWebhook) 和驗證鉤子(ValidatingAdmissionWebhook)已經啟用.這裡是推薦開啟的一組准入控制器.

編寫一個准入鉤子伺服器(admission webhook server)

請參閱已經被kubernetes e2e測試驗證通過的准入伺服器鉤子( admission webhook server)的實現.這個web鉤子處理apiserver發出的admissionReview請求,然後把結果封裝成一個admissionResponse返回給請求者.

admissionReview請求可能有多個版本( v1beta1 或者 未來的v1),web鉤子可以通過admissionReviewVersions欄位來定義它們接受的版本.apiserver會嘗試使用列表中出現的,支援的第一個版本.如果列表中的版本沒有一個是被支援的,驗證將失敗.如果webhook配置已經持久化,對web鉤子的請求將會失敗並被失敗策略控制.

示例鉤子伺服器(admission webhook server)把ClientAuth欄位留空,預設為NoClientCert.這意味著鉤子伺服器不驗證客戶端身份.如果你需要使用mutual TLS或者其它方法來驗證客戶端請求,請參考如何認證apiserver

部署准入控制服務

e2e測試的鉤子伺服器通過部署api(https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/#deployment-v1beta1-apps)被部署到kubernetes叢集中.測試專案也為鉤子伺服器建立了一個前端服務,程式碼

你也可以把你的鉤子服務部署到叢集外,你需要相應地更新web鉤子客戶端配置

執行時配置准入web鉤子

你可以通過ValidatingWebhookConfigurationMutatingWebhookConfiguration動態地配置哪些資源被哪些web鉤子控制.

以下是一個validatingWebhookConfiguration配置的示例,變換鉤子的配置也類似

apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
  name: <name of this configuration object>
webhooks:
- name: <webhook name, e.g., pod-policy.example.io>
  rules:
  - apiGroups:
    - ""
    apiVersions:
    - v1
    operations:
    - CREATE
    resources:
    - pods
    scope: "Namespaced"
  clientConfig:
    service:
      namespace: <namespace of the front-end service>
      name: <name of the front-end service>
    caBundle: <pem encoded ca cert that signs the server cert used by the webhook>
  admissionReviewVersions:
  - v1beta1
  timeoutSeconds: 1

scope欄位指定了叢集級別的資源("Cluster")或者名稱空間級別的資源("Namespaced")需要匹配這些規則."*"表示沒有任何範圍限制.

注意,如果使用clientConfig.service,服務端證書必須對<svc_name>.<svc_namespace>.svc有效.

web鉤子請求預設超時時間為30秒,但是從1.14版本開始,你可以自由設定超時時間但是建議設定較小的時間.如果web鉤子請求超時,請求將被web鉤子的失敗策略處理.

當apiserver接收到一個匹配規則的請求,apiserver將會傳送一個admissionReview請求到clientConfig配置的web鉤子裡.

建立web鉤子配置以後,系統將會經過一段時間使新配置生效.

認證apiserver

如果你的准入web鉤子需要認證,你可以配置apiserver使用基本認證(basic auth), bearer token 或者證書認證.需要三個步驟來完成認證配置.

  • 當啟動apiserver時,通過--admission-control-config-file選項來指定準入控制配置檔案的位置.

  • 在准入控制配置檔案裡,指定變換控制器(MutatingAdmissionWebhook)和驗證控制器(ValidatingAdmissionWebhook)從哪裡讀取證書.證書儲存在kubeConfig檔案裡(和kubectl使用的相同),欄位名為kubeConfigFile.下面是准入控制配置檔案示例

apiVersion: apiserver.k8s.io/v1alpha1
kind: AdmissionConfiguration
plugins:
- name: ValidatingAdmissionWebhook
  configuration:
    apiVersion: apiserver.config.k8s.io/v1alpha1
    kind: WebhookAdmission
    kubeConfigFile: <path-to-kubeconfig-file>
- name: MutatingAdmissionWebhook
  configuration:
    apiVersion: apiserver.config.k8s.io/v1alpha1
    kind: WebhookAdmission
    kubeConfigFile: <path-to-kubeconfig-file>

這裡是admissionConfigurationschema定義

  • 在kubeConfig檔案裡,提供證書
apiVersion: v1
kind: Config
users:
# DNS name of webhook service, i.e., <service name>.<namespace>.svc, or the URL
# of the webhook server.
- name: 'webhook1.ns1.svc'
  user:
    client-certificate-data: <pem encoded certificate>
    client-key-data: <pem encoded key>
# The `name` supports using * to wildmatch prefixing segments.
- name: '*.webhook-company.org'
  user:
    password: <password>
    username: <name>
# '*' is the default match.
- name: '*'
  user:
    token: <token>

當然,你需要設定web鉤子伺服器來處理這些認證.

相關文章