8.5. 動的受付の設定

この手順では、動的受付を設定するための手順の概要を説明します。受付チェーンの機能は、Webhook サーバーを呼び出すように Webhook 受付プラグインを設定することで拡張されます。

Webhook サーバーは集約された API サーバーとしても設定されます。これにより、他の OpenShift Container Platform コンポーネントは内部認証情報を使用して Webhook と通信でき、oc コマンドを使用したテストを容易にします。さらに、これによりロールベースのアクセス制御 (RBAC) が Webhook に対して可能となり、他の API サーバーからのトークン情報が Webhook に開示されないようになります。

前提条件

  • クラスター管理者のアクセスを持つ OpenShift Container Platform アカウント。
  • OpenShift Container Platform CLI(oc)がインストールされていること。
  • 公開されている Webhook サーバーコンテナーイメージ。

手順

  1. Webhook サーバーコンテナーイメージをビルドし、イメージレジストリーを使用してこれをクラスターで使用できるようにします。
  2. ローカル CA キーおよび証明書を作成し、それらを使用して Webhook サーバーの証明書署名要求 (CSR) に署名します。
  3. Webhook リソースの新規プロジェクトを作成します。

    $ oc new-project my-webhook-namespace  1
    1
    Webhook サーバーで特定の名前が使用される可能性があることに注意してください。
  4. rbac.yaml というファイルで集約された API サービスの RBAC ルールを定義します。

    apiVersion: v1
    kind: List
    items:
    
    - apiVersion: rbac.authorization.k8s.io/v1  1
      kind: ClusterRoleBinding
      metadata:
        name: auth-delegator-my-webhook-namespace
      roleRef:
        kind: ClusterRole
        apiGroup: rbac.authorization.k8s.io
        name: system:auth-delegator
      subjects:
      - kind: ServiceAccount
        namespace: my-webhook-namespace
        name: server
    
    - apiVersion: rbac.authorization.k8s.io/v1  2
      kind: ClusterRole
      metadata:
        annotations:
        name: system:openshift:online:my-webhook-server
      rules:
      - apiGroups:
        - online.openshift.io
        resources:
        - namespacereservations  3
        verbs:
        - get
        - list
        - watch
    
    - apiVersion: rbac.authorization.k8s.io/v1  4
      kind: ClusterRole
      metadata:
        name: system:openshift:online:my-webhook-requester
      rules:
      - apiGroups:
        - admission.online.openshift.io
        resources:
        - namespacereservations 5
        verbs:
        - create
    
    - apiVersion: rbac.authorization.k8s.io/v1  6
      kind: ClusterRoleBinding
      metadata:
        name: my-webhook-server-my-webhook-namespace
      roleRef:
        kind: ClusterRole
        apiGroup: rbac.authorization.k8s.io
        name: system:openshift:online:my-webhook-server
      subjects:
      - kind: ServiceAccount
        namespace: my-webhook-namespace
        name: server
    
    - apiVersion: rbac.authorization.k8s.io/v1  7
      kind: RoleBinding
      metadata:
        namespace: kube-system
        name: extension-server-authentication-reader-my-webhook-namespace
      roleRef:
        kind: Role
        apiGroup: rbac.authorization.k8s.io
        name: extension-apiserver-authentication-reader
      subjects:
      - kind: ServiceAccount
        namespace: my-webhook-namespace
        name: server
    
    - apiVersion: rbac.authorization.k8s.io/v1  8
      kind: ClusterRole
      metadata:
        name: my-cluster-role
      rules:
      - apiGroups:
        - admissionregistration.k8s.io
        resources:
        - validatingwebhookconfigurations
        - mutatingwebhookconfigurations
        verbs:
        - get
        - list
        - watch
      - apiGroups:
        - ""
        resources:
        - namespaces
        verbs:
        - get
        - list
        - watch
    
    - apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: my-cluster-role
      roleRef:
        kind: ClusterRole
        apiGroup: rbac.authorization.k8s.io
        name: my-cluster-role
      subjects:
      - kind: ServiceAccount
        namespace: my-webhook-namespace
        name: server
    1
    認証および認可を Webhook サーバー API に委任します。
    2
    Webhook サーバーがクラスターリソースにアクセスできるようにします。
    3
    リソースを参照します。この例では、namespacereservations リソースを参照します。
    4
    集約された API サーバーが受付レビューを作成できるようにします。
    5
    リソースを参照します。この例では、namespacereservations リソースを参照します。
    6
    Webhook サーバーがクラスターリソースにアクセスできるようにします。
    7
    認証を終了するために設定を読み取るためのロールバインディングです。
    8
    集約された API サーバーのデフォルトのクラスターロールおよびクラスターロールバインディングです。
  5. これらの RBAC ルールをクラスターに適用します。

    $ oc auth reconcile -f rbac.yaml
  6. namespace に Webhook をデーモンセットサーバーとして デプロイするために使用される webhook-daemonset.yaml という YAML ファイルを作成します。

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      namespace: my-webhook-namespace
      name: server
      labels:
        server: "true"
    spec:
      selector:
        matchLabels:
          server: "true"
      template:
        metadata:
          name: server
          labels:
            server: "true"
        spec:
          serviceAccountName: server
          containers:
          - name: my-webhook-container  1
            image: <image_registry_username>/<image_path>:<tag>  2
            imagePullPolicy: IfNotPresent
            command:
            - <container_commands>  3
            ports:
            - containerPort: 8443 4
            volumeMounts:
            - mountPath: /var/serving-cert
              name: serving-cert
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8443 5
                scheme: HTTPS
          volumes:
          - name: serving-cert
            secret:
              defaultMode: 420
              secretName: server-serving-cert
    1
    Webhook サーバーで特定のコンテナー名が使用される可能性があることに注意してください。
    2
    Webhook サーバーコンテナーイメージを参照します。<image_registry_username>/<image_path>:<tag> を適切な値に置き換えます。
    3
    Webhook コンテナー run コマンドを指定します。<container_commands> を適切な値に置き換えます。
    4
    Pod 内のターゲットポートを定義します。この例では、ポート 8443 を使用します。
    5
    Readiness プローブによって使用されるポートを指定します。この例では、ポート 8443 を使用します。
  7. デーモンセットをデプロイします。

    $ oc apply -f webhook-daemonset.yaml
  8. サービス提供証明書の署名側のシークレットを webhook-secret.yaml という YAML ファイル内に定義します。

    apiVersion: v1
    kind: Secret
    metadata:
      namespace: my-webhook-namespace
      name: server-serving-cert
    type: kubernetes.io/tls
    data:
      tls.crt: <server_certificate>  1
      tls.key: <server_key>  2
    1
    署名された Webhook サーバー証明書を参照します。<server_certificate> を base64 形式の適切な証明書に置き換えます。
    2
    署名された Webhook サーバーキーを参照します。<server_key> を base64 形式の適切なキーに置き換えます。
  9. シークレットを作成します。

    $ oc apply -f webhook-secret.yaml
  10. サービスアカウントおよびサービスを、webhook-service.yaml という YAML ファイル内に定義します。

    apiVersion: v1
    kind: List
    items:
    
    - apiVersion: v1
      kind: ServiceAccount
      metadata:
        namespace: my-webhook-namespace
        name: server
    
    - apiVersion: v1
      kind: Service
      metadata:
        namespace: my-webhook-namespace
        name: server
        annotations:
          service.alpha.openshift.io/serving-cert-secret-name: server-serving-cert
      spec:
        selector:
          server: "true"
        ports:
        - port: 443  1
          targetPort: 8443  2
    1
    サービスがリッスンするポートを定義します。この例では、ポート 443 を使用します。
    2
    サービスが接続を転送する Pod 内のターゲットポートを定義します。この例では、ポート 8443 を使用します。
  11. クラスターに Webhook サーバーを公開します。

    $ oc apply -f webhook-service.yaml
  12. Webhook サーバーのカスタムリソース定義を webhook-crd.yaml という名前のファイルに定義します。

    apiVersion: apiextensions.k8s.io/v1beta1
    kind: CustomResourceDefinition
    metadata:
      name: namespacereservations.online.openshift.io  1
    spec:
      group: online.openshift.io  2
      version: v1alpha1  3
      scope: Cluster  4
      names:
        plural: namespacereservations  5
        singular: namespacereservation  6
        kind: NamespaceReservation  7
    1
    CustomResourceDefinition spec 値を反映させ、 <plural>.<group> 形式を使用します。この例では、namespacereservations リソースを使用します。
    2
    REST API グループ名です。
    3
    REST API バージョン名です。
    4
    許可される値は Namespaced または Cluster です。
    5
    URL に含まれる複数形の名前です。
    6
    oc 出力に表示されるエイリアスです。
    7
    リソースマニフェストの参照です。
  13. カスタムリソース定義を適用します。

    $ oc apply -f webhook-crd.yaml
  14. Webhook サーバーも、webhook-api-service.yaml というファイル内に集約された API サーバーとして設定します。

    apiVersion: apiregistration.k8s.io/v1beta1
    kind: APIService
    metadata:
      name: v1beta1.admission.online.openshift.io
    spec:
      caBundle: <ca_signing_certificate>  1
      group: admission.online.openshift.io
      groupPriorityMinimum: 1000
      versionPriority: 15
      service:
        name: server
        namespace: my-webhook-namespace
      version: v1beta1
    1
    Webhook サーバーで使用されるサーバー証明書に署名する PEM でエンコーディングされた CA 証明書です。<ca_signing_certificate> を base64 形式の適切な証明書に置き換えます。
  15. 集約された API サービスをデプロイします。

    $ oc apply -f webhook-api-service.yaml
  16. Webhook 受付プラグイン設定を webhook-config.yaml というファイル内に定義します。以下の例では、検証用の受付プラグインを使用します。

    apiVersion: admissionregistration.k8s.io/v1beta1
    kind: ValidatingWebhookConfiguration
    metadata:
      name: namespacereservations.admission.online.openshift.io  1
    webhooks:
    - name: namespacereservations.admission.online.openshift.io  2
      clientConfig:
        service:  3
          namespace: default
          name: kubernetes
          path: /apis/admission.online.openshift.io/v1beta1/namespacereservations  4
        caBundle: <ca_signing_certificate>  5
      rules:
      - operations:
        - CREATE
        apiGroups:
        - project.openshift.io
        apiVersions:
        - "*"
        resources:
        - projectrequests
      - operations:
        - CREATE
        apiGroups:
        - ""
        apiVersions:
        - "*"
        resources:
        - namespaces
      failurePolicy: Fail
    1
    ValidatingWebhookConfiguration オブジェクトの名前。この例では、namespacereservations リソースを使用します。
    2
    呼び出す Webhook の名前です。この例では、namespacereservations リソースを使用します。
    3
    集約された API を使用して Webhook サーバーへのアクセスを有効にします。
    4
    受付要求に使用される Webhook URL です。この例では、namespacereservation リソースを使用します。
    5
    Webhook サーバーで使用されるサーバー証明書に署名する PEM でエンコーディングされた CA 証明書です。<ca_signing_certificate> を base64 形式の適切な証明書に置き換えます。
  17. Webhook をデプロイします。

    $ oc apply -f webhook-config.yaml
  18. Webhook が想定通りに機能していることを確認します。たとえば、特定の namespace を予約するように動的受付を設定している場合は、これらの namespace の作成要求が拒否され、予約されていない namespace の作成要求が正常に実行されることを確認します。