From 86e940a6f0ac0790e3864fa32bfccd76967f594d Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Thu, 4 Jun 2026 15:50:51 -0500 Subject: [PATCH] feat: replace cert-manager webhook Certificate with CSI volume mount for TLS Provision the webhook serving certificate through the cert-manager CSI driver instead of a cert-manager Certificate + cainjection. The manager mounts the cert directly from a csi.cert-manager.io volume, so there is no standalone Certificate resource, no CA-injection wiring on the webhook configurations, and no cluster-wide cert-manager Certificate dependency in the production overlay. - Remove the config/base/certmanager base (Issuer/Certificate + kustomize name-reference + CA-injection replacements). - Add a generic config/components/csi-webhook-cert component that mounts the webhook-server-tls CSI volume on the manager Deployment. The issuer is intentionally left unset so each consuming overlay (or the infra repo) patches csi.cert-manager.io/issuer-kind and issuer-name for its environment. - Drop the optional compute-webhook-cert Secret volume/mount from the base manager Deployment; the CSI volume now supplies serving-certs. - single-cluster overlay: drop the certmanager base, the cainjection patch, and the dnsName/CA replacement blocks; wire in the csi-webhook-cert component instead. - dev overlay: keep an inline self-signed Issuer + Certificate for the local host.docker.internal webhook (no CSI driver in the dev kind/docker setup) and annotate the webhook configs with inject-ca-from directly. Co-Authored-By: Claude Opus 4.8 (1M context) --- config/base/certmanager/certificate.yaml | 27 ------ config/base/certmanager/kustomization.yaml | 5 - config/base/certmanager/kustomizeconfig.yaml | 8 -- config/base/manager/manager.yaml | 11 --- .../csi-webhook-cert/kustomization.yaml | 32 +++++++ config/overlays/dev/config.yaml | 7 +- config/overlays/dev/kustomization.yaml | 70 +++++--------- config/overlays/dev/webhook-cert.yaml | 18 ++++ config/overlays/dev/webhook_patch.yaml | 17 ---- .../single-cluster/kustomization.yaml | 93 +------------------ .../webhookcainjection_patch.yaml | 19 ---- 11 files changed, 74 insertions(+), 233 deletions(-) delete mode 100644 config/base/certmanager/certificate.yaml delete mode 100644 config/base/certmanager/kustomization.yaml delete mode 100644 config/base/certmanager/kustomizeconfig.yaml create mode 100644 config/components/csi-webhook-cert/kustomization.yaml create mode 100644 config/overlays/dev/webhook-cert.yaml delete mode 100644 config/overlays/single-cluster/webhookcainjection_patch.yaml diff --git a/config/base/certmanager/certificate.yaml b/config/base/certmanager/certificate.yaml deleted file mode 100644 index 3b15b5b3..00000000 --- a/config/base/certmanager/certificate.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - labels: - app.kubernetes.io/name: compute - app.kubernetes.io/managed-by: kustomize - name: selfsigned-issuer -spec: - selfSigned: {} ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - labels: - app.kubernetes.io/name: compute - app.kubernetes.io/managed-by: kustomize - name: compute-serving-cert -spec: - # The Service name and namespace get substituted in by kustomize - # replacements in the consuming overlay. - dnsNames: - - SERVICE_NAME.SERVICE_NAMESPACE.svc - - SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: compute-webhook-cert diff --git a/config/base/certmanager/kustomization.yaml b/config/base/certmanager/kustomization.yaml deleted file mode 100644 index bebea5a5..00000000 --- a/config/base/certmanager/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -resources: -- certificate.yaml - -configurations: -- kustomizeconfig.yaml diff --git a/config/base/certmanager/kustomizeconfig.yaml b/config/base/certmanager/kustomizeconfig.yaml deleted file mode 100644 index cf6f89e8..00000000 --- a/config/base/certmanager/kustomizeconfig.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# This configuration is for teaching kustomize how to update name ref substitution -nameReference: -- kind: Issuer - group: cert-manager.io - fieldSpecs: - - kind: Certificate - group: cert-manager.io - path: spec/issuerRef/name diff --git a/config/base/manager/manager.yaml b/config/base/manager/manager.yaml index 03028177..e2c06e97 100644 --- a/config/base/manager/manager.yaml +++ b/config/base/manager/manager.yaml @@ -66,20 +66,9 @@ spec: volumeMounts: - name: config mountPath: /config - - name: webhook-cert - mountPath: /tmp/k8s-webhook-server/serving-certs - readOnly: true serviceAccountName: compute terminationGracePeriodSeconds: 10 volumes: - name: config configMap: name: compute-config - # Optional so the manager can run without admission webhooks: when - # `webhookServer:` is omitted from the server config, the binary - # skips the webhook server entirely and the missing Secret is fine. - - name: webhook-cert - secret: - secretName: compute-webhook-cert - defaultMode: 420 - optional: true diff --git a/config/components/csi-webhook-cert/kustomization.yaml b/config/components/csi-webhook-cert/kustomization.yaml new file mode 100644 index 00000000..feade65a --- /dev/null +++ b/config/components/csi-webhook-cert/kustomization.yaml @@ -0,0 +1,32 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +patches: + # Add the CSI webhook cert volume and volumeMount to the manager Deployment. + # The issuer (csi.cert-manager.io/issuer-kind and csi.cert-manager.io/issuer-name) + # must be patched in by the consuming overlay or infra repo. + - target: + kind: Deployment + name: compute-manager + patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: compute-manager + spec: + template: + spec: + containers: + - name: manager + volumeMounts: + - name: webhook-server-tls + mountPath: /tmp/k8s-webhook-server/serving-certs + readOnly: true + volumes: + - name: webhook-server-tls + csi: + driver: csi.cert-manager.io + readOnly: true + volumeAttributes: + csi.cert-manager.io/fs-group: "65532" + csi.cert-manager.io/dns-names: compute-webhook.compute-system.svc,compute-webhook.compute-system.svc.cluster.local diff --git a/config/overlays/dev/config.yaml b/config/overlays/dev/config.yaml index 1d49a6c6..6ef2f00e 100644 --- a/config/overlays/dev/config.yaml +++ b/config/overlays/dev/config.yaml @@ -2,9 +2,4 @@ apiVersion: apiserver.config.datumapis.com/v1alpha1 kind: WorkloadOperator metricsServer: bindAddress: "0" - -webhookServer: - tls: - secretRef: - name: compute-webhook-cert - namespace: kube-system +webhookServer: {} diff --git a/config/overlays/dev/kustomization.yaml b/config/overlays/dev/kustomization.yaml index 7b076890..339cee0f 100644 --- a/config/overlays/dev/kustomization.yaml +++ b/config/overlays/dev/kustomization.yaml @@ -1,55 +1,29 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: compute-system + resources: - ../../base/crd - ../../base/webhook - - ../../base/certmanager + - webhook-cert.yaml -replacements: - - source: - kind: Certificate - group: cert-manager.io - version: v1 - name: compute-serving-cert - fieldPath: .metadata.namespace - targets: - - select: - kind: ValidatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - create: true - - select: - kind: MutatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - create: true - - source: - kind: Certificate - group: cert-manager.io - version: v1 - name: compute-serving-cert - fieldPath: .metadata.name - targets: - - select: - kind: ValidatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 1 - create: true - - select: - kind: MutatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 1 - create: true +patches: + # Wire cainjector to the dev cert so the API server can verify the webhook. + - patch: |- + apiVersion: admissionregistration.k8s.io/v1 + kind: MutatingWebhookConfiguration + metadata: + name: compute-mutating + annotations: + cert-manager.io/inject-ca-from: compute-system/compute-serving-cert + - patch: |- + apiVersion: admissionregistration.k8s.io/v1 + kind: ValidatingWebhookConfiguration + metadata: + name: compute-validating + annotations: + cert-manager.io/inject-ca-from: compute-system/compute-serving-cert transformers: - webhook_patch.yaml diff --git a/config/overlays/dev/webhook-cert.yaml b/config/overlays/dev/webhook-cert.yaml new file mode 100644 index 00000000..db7bf928 --- /dev/null +++ b/config/overlays/dev/webhook-cert.yaml @@ -0,0 +1,18 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: compute-serving-cert +spec: + dnsNames: + - host.docker.internal + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: compute-webhook-cert diff --git a/config/overlays/dev/webhook_patch.yaml b/config/overlays/dev/webhook_patch.yaml index 846649e3..bb302318 100644 --- a/config/overlays/dev/webhook_patch.yaml +++ b/config/overlays/dev/webhook_patch.yaml @@ -1,23 +1,6 @@ --- apiVersion: builtin kind: PatchTransformer -metadata: - name: webhook-cert-patch -patch: |- - - op: replace - path: /spec/dnsNames - value: ["host.docker.internal"] - - op: replace - path: /spec/secretName - value: compute-webhook-cert -target: - kind: Certificate - group: cert-manager.io - version: v1 - name: compute-serving-cert ---- -apiVersion: builtin -kind: PatchTransformer metadata: name: mutatingwebhook-url-patch patch: |- diff --git a/config/overlays/single-cluster/kustomization.yaml b/config/overlays/single-cluster/kustomization.yaml index 160b894d..7a2d0320 100644 --- a/config/overlays/single-cluster/kustomization.yaml +++ b/config/overlays/single-cluster/kustomization.yaml @@ -9,100 +9,9 @@ resources: - ../../base/crd - ../../base/manager - ../../base/webhook - - ../../base/certmanager components: - ../../components/leader_election - ../../components/controller_rbac - ../../components/resource-metrics - ../../components/high-availability - -patches: -- path: webhookcainjection_patch.yaml - -replacements: -# Fill in SERVICE_NAME / SERVICE_NAMESPACE placeholders in the Certificate's -# dnsNames so the cert is issued for the actual webhook Service location. -- source: - kind: Service - version: v1 - name: compute-webhook - fieldPath: .metadata.name - targets: - - select: - kind: Certificate - group: cert-manager.io - version: v1 - name: compute-serving-cert - fieldPaths: - - .spec.dnsNames.0 - - .spec.dnsNames.1 - options: - delimiter: '.' - index: 0 - create: true -- source: - kind: Service - version: v1 - name: compute-webhook - fieldPath: .metadata.namespace - targets: - - select: - kind: Certificate - group: cert-manager.io - version: v1 - name: compute-serving-cert - fieldPaths: - - .spec.dnsNames.0 - - .spec.dnsNames.1 - options: - delimiter: '.' - index: 1 - create: true -# Wire the Certificate namespace + name into the cert-manager.io/inject-ca-from -# annotation on the webhook configurations so cainjector populates caBundle. -- source: - kind: Certificate - group: cert-manager.io - version: v1 - name: compute-serving-cert - fieldPath: .metadata.namespace - targets: - - select: - kind: ValidatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - create: true - - select: - kind: MutatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 0 - create: true -- source: - kind: Certificate - group: cert-manager.io - version: v1 - name: compute-serving-cert - fieldPath: .metadata.name - targets: - - select: - kind: ValidatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 1 - create: true - - select: - kind: MutatingWebhookConfiguration - fieldPaths: - - .metadata.annotations.[cert-manager.io/inject-ca-from] - options: - delimiter: '/' - index: 1 - create: true + - ../../components/csi-webhook-cert diff --git a/config/overlays/single-cluster/webhookcainjection_patch.yaml b/config/overlays/single-cluster/webhookcainjection_patch.yaml deleted file mode 100644 index 41718fb7..00000000 --- a/config/overlays/single-cluster/webhookcainjection_patch.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - labels: - app.kubernetes.io/name: compute - app.kubernetes.io/managed-by: kustomize - name: compute-mutating - annotations: - cert-manager.io/inject-ca-from: system/compute-serving-cert ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - labels: - app.kubernetes.io/name: compute - app.kubernetes.io/managed-by: kustomize - name: compute-validating - annotations: - cert-manager.io/inject-ca-from: system/compute-serving-cert