From b34adf88ff4479364b52861137e168e0da8fa3a2 Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Thu, 28 Feb 2019 14:52:21 +0000 Subject: [PATCH 1/4] cainjector: support injecting apiserver ca Signed-off-by: James Munnelly --- pkg/controller/cainjector/BUILD.bazel | 1 + pkg/controller/cainjector/controller.go | 28 ++++++++++++++- pkg/controller/cainjector/setup.go | 1 + test/e2e/suite/serving/cainjector.go | 45 +++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/pkg/controller/cainjector/BUILD.bazel b/pkg/controller/cainjector/BUILD.bazel index 4d50b55de..50fb1d703 100644 --- a/pkg/controller/cainjector/BUILD.bazel +++ b/pkg/controller/cainjector/BUILD.bazel @@ -21,6 +21,7 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", + "//vendor/k8s.io/client-go/rest:go_default_library", "//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1:go_default_library", "//vendor/sigs.k8s.io/controller-runtime:go_default_library", "//vendor/sigs.k8s.io/controller-runtime/pkg/client:go_default_library", diff --git a/pkg/controller/cainjector/controller.go b/pkg/controller/cainjector/controller.go index 23207e135..589b5331d 100644 --- a/pkg/controller/cainjector/controller.go +++ b/pkg/controller/cainjector/controller.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -38,6 +39,12 @@ var ( // object wants injection of CAs. It takes the form of a reference to a certificate // as namespace/name. The certificate is expected to have the is-serving-for annotations. WantInjectAnnotation = "certmanager.k8s.io/inject-ca-from" + + // WantInjectAPIServerCAAnnotation, if set to "true", will make the cainjector + // inject the CA certificate for the Kubernetes apiserver into the resource. + // It discovers the apiserver's CA by inspecting the service account credentials + // mounted into the + WantInjectAPIServerCAAnnotation = "certmanager.k8s.io/inject-apiserver-ca" ) // dropNotFound ignores the given error if it's a not-found error, @@ -104,6 +111,10 @@ type genericInjectReconciler struct { log logr.Logger client.Client + // restConfig is used to inject the kubernetes apiserver CA into resources + // with the 'inject-apiserver-ca' annotation + restConfig *rest.Config + resourceName string // just used for logging } @@ -143,6 +154,22 @@ func (r *genericInjectReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro return ctrl.Result{}, err } certNameRaw := metaObj.GetAnnotations()[WantInjectAnnotation] + hasInjectAPIServerCA := metaObj.GetAnnotations()[WantInjectAPIServerCAAnnotation] == "true" + if certNameRaw != "" && hasInjectAPIServerCA { + log.Info("object has both inject-ca-from and inject-apiserver-ca annotations, skipping") + return ctrl.Result{}, nil + } + if hasInjectAPIServerCA { + target.SetCA(r.restConfig.CAData) + + // actually update with injected CA data + if err := r.Client.Update(ctx, target.AsObject()); err != nil { + log.Error(err, "unable to update target object with new CA data") + return ctrl.Result{}, err + } + log.V(1).Info("updated object") + return ctrl.Result{}, nil + } if certNameRaw == "" { log.V(1).Info("object does not want CA injection, skipping") return ctrl.Result{}, nil @@ -196,6 +223,5 @@ func (r *genericInjectReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro } log.V(1).Info("updated object") - // finally requeue if we had an error in the loop return ctrl.Result{}, nil } diff --git a/pkg/controller/cainjector/setup.go b/pkg/controller/cainjector/setup.go index 52b70fc07..ee87811ed 100644 --- a/pkg/controller/cainjector/setup.go +++ b/pkg/controller/cainjector/setup.go @@ -81,6 +81,7 @@ func Register(mgr ctrl.Manager, setup injectorSetup) error { }}). Complete(&genericInjectReconciler{ Client: mgr.GetClient(), + restConfig: mgr.GetConfig(), log: ctrl.Log.WithName("inject-controller"), resourceName: setup.resourceName, injector: setup.injector, diff --git a/test/e2e/suite/serving/cainjector.go b/test/e2e/suite/serving/cainjector.go index 4cb92596b..fe6562003 100644 --- a/test/e2e/suite/serving/cainjector.go +++ b/test/e2e/suite/serving/cainjector.go @@ -231,5 +231,50 @@ var _ = framework.CertManagerDescribe("CA Injector", func() { }).Should(Equal([][]byte{hook.Webhooks[0].ClientConfig.CABundle, hook.Webhooks[1].ClientConfig.CABundle})) }) + + It("should inject the apiserver CA if the webhook as the inject-apiserver-ca annotation", func() { + if len(f.KubeClientConfig.CAData) == 0 { + Skip("skipping test as the kube client CA bundle is not set") + } + By("creating a vaidating webhook with the inject-apiserver-ca annotation") + someURL := "https://localhost:8675" + hook := admissionreg.ValidatingWebhookConfiguration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "apiserver-ca-hook", + Annotations: map[string]string{ + injctrl.WantInjectAPIServerCAAnnotation: "true", + }, + }, + Webhooks: []admissionreg.Webhook{ + { + Name: "hook1.fake.k8s.io", + ClientConfig: admissionreg.WebhookClientConfig{ + URL: &someURL, + }, + }, + { + Name: "hook2.fake.k8s.io", + ClientConfig: admissionreg.WebhookClientConfig{ + Service: &admissionreg.ServiceReference{ + Name: "some-svc", + Namespace: f.Namespace.Name, + }, + }, + }, + }, + } + Expect(f.CRClient.Create(context.Background(), &hook)).To(Succeed()) + hookToCleanUp = &hook + + By("checking that all webhooks have a populated CA") + caData := f.KubeClientConfig.CAData + Eventually(func() ([][]byte, error) { + var newHook admissionreg.ValidatingWebhookConfiguration + if err := f.CRClient.Get(context.Background(), types.NamespacedName{Name: hook.Name}, &newHook); err != nil { + return nil, err + } + return [][]byte{newHook.Webhooks[0].ClientConfig.CABundle, newHook.Webhooks[1].ClientConfig.CABundle}, nil + }, 10*time.Second, 1*time.Second).Should(Equal([][]byte{caData, caData})) + }) }) }) From 984262d6f41775e3d19133f8db96b1bc8e83b0b7 Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Thu, 28 Feb 2019 16:45:37 +0000 Subject: [PATCH 2/4] Use inject-apiserver-ca annotation for webhook Signed-off-by: James Munnelly --- deploy/charts/cert-manager/Chart.yaml | 2 +- deploy/charts/cert-manager/README.md | 3 - deploy/charts/cert-manager/requirements.lock | 6 +- deploy/charts/cert-manager/requirements.yaml | 2 +- deploy/charts/cert-manager/webhook/Chart.yaml | 2 +- .../webhook/templates/ca-sync.yaml | 157 -------------- .../webhook/templates/validating-webhook.yaml | 2 + .../charts/cert-manager/webhook/values.yaml | 5 - deploy/manifests/cert-manager-no-webhook.yaml | 12 +- deploy/manifests/cert-manager.yaml | 195 ++---------------- 10 files changed, 34 insertions(+), 352 deletions(-) delete mode 100644 deploy/charts/cert-manager/webhook/templates/ca-sync.yaml diff --git a/deploy/charts/cert-manager/Chart.yaml b/deploy/charts/cert-manager/Chart.yaml index cd0b76d31..e6f1e61e6 100644 --- a/deploy/charts/cert-manager/Chart.yaml +++ b/deploy/charts/cert-manager/Chart.yaml @@ -1,5 +1,5 @@ name: cert-manager -version: v0.7.0-alpha.3 +version: v0.7.0-alpha.4 appVersion: v0.7.0-alpha.0 description: A Helm chart for cert-manager home: https://github.com/jetstack/cert-manager diff --git a/deploy/charts/cert-manager/README.md b/deploy/charts/cert-manager/README.md index a860a562d..0a607399d 100644 --- a/deploy/charts/cert-manager/README.md +++ b/deploy/charts/cert-manager/README.md @@ -109,9 +109,6 @@ The following table lists the configurable parameters of the cert-manager chart | `webhook.image.repository` | Webhook image repository | `quay.io/jetstack/cert-manager-webhook` | | `webhook.image.tag` | Webhook image tag | `v0.7.0-alpha.0` | | `webhook.image.pullPolicy` | Webhook image pull policy | `IfNotPresent` | -| `webhook.caSyncImage.repository` | CA sync image repository | `quay.io/munnerz/apiextensions-ca-helper` | -| `webhook.caSyncImage.tag` | CA sync image tag | `v0.1.0` | -| `webhook.caSyncImage.pullPolicy` | CA sync image pull policy | `IfNotPresent` | | `cainjector.enabled` | Toggles whether the cainjector component should be installed (required for the webhook component to work) | `true` | | `cainjector.replicaCount` | Number of cert-manager cainjector replicas | `1` | | `cainjector.podAnnotations` | Annotations to add to the cainjector pods | `{}` | diff --git a/deploy/charts/cert-manager/requirements.lock b/deploy/charts/cert-manager/requirements.lock index dba31af8a..42f01d9c5 100644 --- a/deploy/charts/cert-manager/requirements.lock +++ b/deploy/charts/cert-manager/requirements.lock @@ -1,9 +1,9 @@ dependencies: - name: webhook repository: file://webhook - version: v0.7.0-alpha.2 + version: v0.7.0-alpha.3 - name: cainjector repository: file://cainjector version: v0.7.0-alpha.2 -digest: sha256:49da3fe6e94b3449715c5140f24a828e2cb5bfda658cfb34b4a828c42d963d21 -generated: 2019-02-28T10:43:57.76404494Z +digest: sha256:3df2a888b918e75df7422ca7c678d0aaf357920f7108a887ab230e55732fd8ef +generated: 2019-02-28T16:50:58.104742471Z diff --git a/deploy/charts/cert-manager/requirements.yaml b/deploy/charts/cert-manager/requirements.yaml index 9b0ba8462..302bd30b7 100644 --- a/deploy/charts/cert-manager/requirements.yaml +++ b/deploy/charts/cert-manager/requirements.yaml @@ -1,7 +1,7 @@ # requirements.yaml dependencies: - name: webhook - version: "v0.7.0-alpha.2" + version: "v0.7.0-alpha.3" repository: "file://webhook" condition: webhook.enabled - name: cainjector diff --git a/deploy/charts/cert-manager/webhook/Chart.yaml b/deploy/charts/cert-manager/webhook/Chart.yaml index 235725e7b..1748ee046 100644 --- a/deploy/charts/cert-manager/webhook/Chart.yaml +++ b/deploy/charts/cert-manager/webhook/Chart.yaml @@ -1,6 +1,6 @@ name: webhook apiVersion: v1 -version: "v0.7.0-alpha.2" +version: "v0.7.0-alpha.3" appVersion: "v0.7.0-alpha.0" description: A Helm chart for deploying the cert-manager webhook component home: https://github.com/jetstack/cert-manager diff --git a/deploy/charts/cert-manager/webhook/templates/ca-sync.yaml b/deploy/charts/cert-manager/webhook/templates/ca-sync.yaml deleted file mode 100644 index 774d2068d..000000000 --- a/deploy/charts/cert-manager/webhook/templates/ca-sync.yaml +++ /dev/null @@ -1,157 +0,0 @@ -## This file contains a CronJob that runs every week to automatically update the -## caBundle set on the APIService and ValidatingWebhookConfiguration resource. -## This allows us to store the CA bundle in a Secret resource which is -## generated by cert-manager's 'selfsigned' Issuer. -apiVersion: batch/v1beta1 -kind: CronJob -metadata: - name: {{ include "webhook.fullname" . }}-ca-sync - namespace: {{ .Release.Namespace | quote }} - labels: - app: {{ include "webhook.name" . }} - chart: {{ include "webhook.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - schedule: "@weekly" - jobTemplate: - spec: - backoffLimit: 20 - template: - metadata: - labels: - app: ca-helper - spec: - serviceAccountName: {{ include "webhook.fullname" . }}-ca-sync - restartPolicy: OnFailure - containers: - - name: ca-helper - image: {{ .Values.caSyncImage.repository }}:{{ .Values.caSyncImage.tag }} - imagePullPolicy: {{ .Values.caSyncImage.pullPolicy }} - args: - - -config=/config/config - volumeMounts: - - name: config - mountPath: /config - resources: - requests: - cpu: 10m - memory: 32Mi - limits: - cpu: 100m - memory: 128Mi - volumes: - - name: config - configMap: - name: {{ include "webhook.fullname" . }}-ca-sync ---- -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ include "webhook.fullname" . }}-ca-sync - namespace: {{ .Release.Namespace | quote }} - labels: - app: {{ include "webhook.name" . }} - chart: {{ include "webhook.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - backoffLimit: 20 - template: - metadata: - labels: - app: ca-helper - spec: - serviceAccountName: {{ include "webhook.fullname" . }}-ca-sync - restartPolicy: OnFailure - containers: - - name: ca-helper - image: {{ .Values.caSyncImage.repository }}:{{ .Values.caSyncImage.tag }} - imagePullPolicy: {{ .Values.caSyncImage.pullPolicy }} - args: - - -config=/config/config - volumeMounts: - - name: config - mountPath: /config - resources: - requests: - cpu: 10m - memory: 32Mi - limits: - cpu: 100m - memory: 128Mi - volumes: - - name: config - configMap: - name: {{ include "webhook.fullname" . }}-ca-sync ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "webhook.fullname" . }}-ca-sync - namespace: {{ .Release.Namespace | quote }} - labels: - app: {{ include "webhook.name" . }} - chart: {{ include "webhook.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -data: - config: |- - { - "validatingWebhookConfigurations": [ - { - "name": "{{ include "webhook.fullname" . }}", - "file": { - "path": "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" - } - } - ] - } ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "webhook.fullname" . }}-ca-sync - namespace: {{ .Release.Namespace | quote }} - labels: - app: {{ include "webhook.name" . }} - chart: {{ include "webhook.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} - -{{ if .Values.global.rbac.create -}} ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - name: {{ include "webhook.fullname" . }}-ca-sync - labels: - app: {{ include "webhook.name" . }} - chart: {{ include "webhook.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -rules: - - apiGroups: ["admissionregistration.k8s.io"] - resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"] - verbs: ["get", "update"] - resourceNames: - - {{ include "webhook.fullname" . }} ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - name: {{ include "webhook.fullname" . }}-ca-sync - labels: - app: {{ include "webhook.name" . }} - chart: {{ include "webhook.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ include "webhook.fullname" . }}-ca-sync -subjects: - - name: {{ include "webhook.fullname" . }}-ca-sync - namespace: {{ .Release.Namespace }} - kind: ServiceAccount -{{- end -}} diff --git a/deploy/charts/cert-manager/webhook/templates/validating-webhook.yaml b/deploy/charts/cert-manager/webhook/templates/validating-webhook.yaml index 25112194c..de1ce6e39 100644 --- a/deploy/charts/cert-manager/webhook/templates/validating-webhook.yaml +++ b/deploy/charts/cert-manager/webhook/templates/validating-webhook.yaml @@ -7,6 +7,8 @@ metadata: chart: {{ include "webhook.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} + annotations: + certmanager.k8s.io/inject-apiserver-ca: "true" webhooks: - name: certificates.admission.certmanager.k8s.io namespaceSelector: diff --git a/deploy/charts/cert-manager/webhook/values.yaml b/deploy/charts/cert-manager/webhook/values.yaml index 98ad997bc..ab0c30e7a 100644 --- a/deploy/charts/cert-manager/webhook/values.yaml +++ b/deploy/charts/cert-manager/webhook/values.yaml @@ -32,8 +32,3 @@ image: repository: quay.io/jetstack/cert-manager-webhook tag: v0.7.0-alpha.0 pullPolicy: IfNotPresent - -caSyncImage: - repository: quay.io/munnerz/apiextensions-ca-helper - tag: v0.1.0 - pullPolicy: IfNotPresent diff --git a/deploy/manifests/cert-manager-no-webhook.yaml b/deploy/manifests/cert-manager-no-webhook.yaml index 65e392569..0ff77a33b 100644 --- a/deploy/manifests/cert-manager-no-webhook.yaml +++ b/deploy/manifests/cert-manager-no-webhook.yaml @@ -988,7 +988,7 @@ metadata: namespace: "cert-manager" labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller --- @@ -1044,7 +1044,7 @@ metadata: name: cert-manager labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller rules: @@ -1064,7 +1064,7 @@ metadata: name: cert-manager labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller roleRef: @@ -1082,7 +1082,7 @@ metadata: name: cert-manager-view labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller rbac.authorization.k8s.io/aggregate-to-view: "true" @@ -1099,7 +1099,7 @@ metadata: name: cert-manager-edit labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller rbac.authorization.k8s.io/aggregate-to-edit: "true" @@ -1158,7 +1158,7 @@ metadata: namespace: "cert-manager" labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller spec: diff --git a/deploy/manifests/cert-manager.yaml b/deploy/manifests/cert-manager.yaml index b5cace7bb..dfee77c28 100644 --- a/deploy/manifests/cert-manager.yaml +++ b/deploy/manifests/cert-manager.yaml @@ -988,7 +988,7 @@ metadata: namespace: "cert-manager" labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller @@ -1001,7 +1001,7 @@ metadata: namespace: "cert-manager" labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller --- @@ -1057,7 +1057,7 @@ metadata: name: cert-manager labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller rules: @@ -1077,7 +1077,7 @@ metadata: name: cert-manager labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller roleRef: @@ -1095,7 +1095,7 @@ metadata: name: cert-manager-view labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller rbac.authorization.k8s.io/aggregate-to-view: "true" @@ -1112,7 +1112,7 @@ metadata: name: cert-manager-edit labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller rbac.authorization.k8s.io/aggregate-to-edit: "true" @@ -1133,7 +1133,7 @@ metadata: name: cert-manager-webhook:auth-delegator labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller roleRef: @@ -1158,7 +1158,7 @@ metadata: namespace: kube-system labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller roleRef: @@ -1179,7 +1179,7 @@ metadata: name: cert-manager-webhook:webhook-requester labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller rules: @@ -1200,7 +1200,7 @@ metadata: namespace: "cert-manager" labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller spec: @@ -1263,7 +1263,7 @@ metadata: namespace: "cert-manager" labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller spec: @@ -1314,7 +1314,7 @@ metadata: namespace: "cert-manager" labels: app: cert-manager - chart: cert-manager-v0.7.0-alpha.3 + chart: cert-manager-v0.7.0-alpha.4 release: cert-manager heritage: Tiller spec: @@ -1354,163 +1354,6 @@ spec: memory: 32Mi ---- -# Source: cert-manager/charts/webhook/templates/ca-sync.yaml -## This file contains a CronJob that runs every week to automatically update the -## caBundle set on the APIService and ValidatingWebhookConfiguration resource. -## This allows us to store the CA bundle in a Secret resource which is -## generated by cert-manager's 'selfsigned' Issuer. -apiVersion: batch/v1beta1 -kind: CronJob -metadata: - name: cert-manager-webhook-ca-sync - namespace: "cert-manager" - labels: - app: webhook - chart: webhook-v0.7.0-alpha.2 - release: cert-manager - heritage: Tiller -spec: - schedule: "@weekly" - jobTemplate: - spec: - backoffLimit: 20 - template: - metadata: - labels: - app: ca-helper - spec: - serviceAccountName: cert-manager-webhook-ca-sync - restartPolicy: OnFailure - containers: - - name: ca-helper - image: quay.io/munnerz/apiextensions-ca-helper:v0.1.0 - imagePullPolicy: IfNotPresent - args: - - -config=/config/config - volumeMounts: - - name: config - mountPath: /config - resources: - requests: - cpu: 10m - memory: 32Mi - limits: - cpu: 100m - memory: 128Mi - volumes: - - name: config - configMap: - name: cert-manager-webhook-ca-sync ---- -apiVersion: batch/v1 -kind: Job -metadata: - name: cert-manager-webhook-ca-sync - namespace: "cert-manager" - labels: - app: webhook - chart: webhook-v0.7.0-alpha.2 - release: cert-manager - heritage: Tiller -spec: - backoffLimit: 20 - template: - metadata: - labels: - app: ca-helper - spec: - serviceAccountName: cert-manager-webhook-ca-sync - restartPolicy: OnFailure - containers: - - name: ca-helper - image: quay.io/munnerz/apiextensions-ca-helper:v0.1.0 - imagePullPolicy: IfNotPresent - args: - - -config=/config/config - volumeMounts: - - name: config - mountPath: /config - resources: - requests: - cpu: 10m - memory: 32Mi - limits: - cpu: 100m - memory: 128Mi - volumes: - - name: config - configMap: - name: cert-manager-webhook-ca-sync ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: cert-manager-webhook-ca-sync - namespace: "cert-manager" - labels: - app: webhook - chart: webhook-v0.7.0-alpha.2 - release: cert-manager - heritage: Tiller -data: - config: |- - { - "validatingWebhookConfigurations": [ - { - "name": "cert-manager-webhook", - "file": { - "path": "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" - } - } - ] - } ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: cert-manager-webhook-ca-sync - namespace: "cert-manager" - labels: - app: webhook - chart: webhook-v0.7.0-alpha.2 - release: cert-manager - heritage: Tiller - ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - name: cert-manager-webhook-ca-sync - labels: - app: webhook - chart: webhook-v0.7.0-alpha.2 - release: cert-manager - heritage: Tiller -rules: - - apiGroups: ["admissionregistration.k8s.io"] - resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"] - verbs: ["get", "update"] - resourceNames: - - cert-manager-webhook ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - name: cert-manager-webhook-ca-sync - labels: - app: webhook - chart: webhook-v0.7.0-alpha.2 - release: cert-manager - heritage: Tiller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cert-manager-webhook-ca-sync -subjects: - - name: cert-manager-webhook-ca-sync - namespace: cert-manager - kind: ServiceAccount --- # Source: cert-manager/charts/webhook/templates/apiservice.yaml apiVersion: apiregistration.k8s.io/v1beta1 @@ -1519,7 +1362,7 @@ metadata: name: v1beta1.admission.certmanager.k8s.io labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller annotations: @@ -1545,7 +1388,7 @@ metadata: namespace: "cert-manager" labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller spec: @@ -1561,7 +1404,7 @@ metadata: namespace: "cert-manager" labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller spec: @@ -1582,7 +1425,7 @@ metadata: namespace: "cert-manager" labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller spec: @@ -1599,7 +1442,7 @@ metadata: namespace: "cert-manager" labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller spec: @@ -1620,9 +1463,11 @@ metadata: name: cert-manager-webhook labels: app: webhook - chart: webhook-v0.7.0-alpha.2 + chart: webhook-v0.7.0-alpha.3 release: cert-manager heritage: Tiller + annotations: + certmanager.k8s.io/inject-apiserver-ca: "true" webhooks: - name: certificates.admission.certmanager.k8s.io namespaceSelector: From 1618ebde4362428e1bbbc7353242d429cb5472d3 Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Thu, 28 Feb 2019 19:34:40 +0000 Subject: [PATCH 3/4] Fix loading apiserver caBundle Signed-off-by: James Munnelly --- pkg/controller/cainjector/BUILD.bazel | 1 - pkg/controller/cainjector/controller.go | 10 +++---- pkg/controller/cainjector/setup.go | 36 ++++++++++++++++++++----- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/pkg/controller/cainjector/BUILD.bazel b/pkg/controller/cainjector/BUILD.bazel index 50fb1d703..4d50b55de 100644 --- a/pkg/controller/cainjector/BUILD.bazel +++ b/pkg/controller/cainjector/BUILD.bazel @@ -21,7 +21,6 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", - "//vendor/k8s.io/client-go/rest:go_default_library", "//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration/v1:go_default_library", "//vendor/sigs.k8s.io/controller-runtime:go_default_library", "//vendor/sigs.k8s.io/controller-runtime/pkg/client:go_default_library", diff --git a/pkg/controller/cainjector/controller.go b/pkg/controller/cainjector/controller.go index 589b5331d..4552277a6 100644 --- a/pkg/controller/cainjector/controller.go +++ b/pkg/controller/cainjector/controller.go @@ -29,7 +29,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -111,9 +110,9 @@ type genericInjectReconciler struct { log logr.Logger client.Client - // restConfig is used to inject the kubernetes apiserver CA into resources - // with the 'inject-apiserver-ca' annotation - restConfig *rest.Config + // apiserverCABundle is the ca bundle used by the apiserver. + // This will be injected into resources that have the ` + apiserverCABundle []byte resourceName string // just used for logging } @@ -160,7 +159,8 @@ func (r *genericInjectReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro return ctrl.Result{}, nil } if hasInjectAPIServerCA { - target.SetCA(r.restConfig.CAData) + log.V(1).Info("setting apiserver ca bundle on injectable") + target.SetCA(r.apiserverCABundle) // actually update with injected CA data if err := r.Client.Update(ctx, target.AsObject()); err != nil { diff --git a/pkg/controller/cainjector/setup.go b/pkg/controller/cainjector/setup.go index ee87811ed..601d92061 100644 --- a/pkg/controller/cainjector/setup.go +++ b/pkg/controller/cainjector/setup.go @@ -17,9 +17,11 @@ limitations under the License. package cainjector import ( + "io/ioutil" + admissionreg "k8s.io/api/admissionregistration/v1beta1" corev1 "k8s.io/api/core/v1" - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" apireg "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/handler" @@ -65,6 +67,12 @@ func Register(mgr ctrl.Manager, setup injectorSetup) error { return err } + cfg := mgr.GetConfig() + caBundle, err := dataFromSliceOrFile(cfg.CAData, cfg.CAFile) + if err != nil { + return err + } + return ctrl.NewControllerManagedBy(mgr). For(typ). Watches(&source.Kind{Type: &certmanager.Certificate{}}, @@ -80,14 +88,30 @@ func Register(mgr ctrl.Manager, setup injectorSetup) error { toInjectable: certToInjectableFunc(setup.listType, setup.resourceName), }}). Complete(&genericInjectReconciler{ - Client: mgr.GetClient(), - restConfig: mgr.GetConfig(), - log: ctrl.Log.WithName("inject-controller"), - resourceName: setup.resourceName, - injector: setup.injector, + Client: mgr.GetClient(), + apiserverCABundle: caBundle, + log: ctrl.Log.WithName("inject-controller"), + resourceName: setup.resourceName, + injector: setup.injector, }) } +// dataFromSliceOrFile returns data from the slice (if non-empty), or from the file, +// or an error if an error occurred reading the file +func dataFromSliceOrFile(data []byte, file string) ([]byte, error) { + if len(data) > 0 { + return data, nil + } + if len(file) > 0 { + fileData, err := ioutil.ReadFile(file) + if err != nil { + return []byte{}, err + } + return fileData, nil + } + return nil, nil +} + // RegisterALL registers all known injection controllers with the given manager, and adds relevant indicides. func RegisterAll(mgr ctrl.Manager) error { for _, setup := range injectorSetups { From 63f4f483042065a1a4e184f8b4398a2c7c16ef0c Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Thu, 28 Feb 2019 20:39:14 +0000 Subject: [PATCH 4/4] Make injecting APIServer CA optional in Helm chart Signed-off-by: James Munnelly --- deploy/charts/cert-manager/README.md | 1 + .../cert-manager/webhook/templates/validating-webhook.yaml | 2 ++ deploy/charts/cert-manager/webhook/values.yaml | 7 +++++++ 3 files changed, 10 insertions(+) diff --git a/deploy/charts/cert-manager/README.md b/deploy/charts/cert-manager/README.md index 0a607399d..fa9200a17 100644 --- a/deploy/charts/cert-manager/README.md +++ b/deploy/charts/cert-manager/README.md @@ -109,6 +109,7 @@ The following table lists the configurable parameters of the cert-manager chart | `webhook.image.repository` | Webhook image repository | `quay.io/jetstack/cert-manager-webhook` | | `webhook.image.tag` | Webhook image tag | `v0.7.0-alpha.0` | | `webhook.image.pullPolicy` | Webhook image pull policy | `IfNotPresent` | +| `webhook.injectAPIServerCA` | if true, the apiserver's CABundle will be automatically injected into the ValidatingWebhookConfiguration resource | `true` | | `cainjector.enabled` | Toggles whether the cainjector component should be installed (required for the webhook component to work) | `true` | | `cainjector.replicaCount` | Number of cert-manager cainjector replicas | `1` | | `cainjector.podAnnotations` | Annotations to add to the cainjector pods | `{}` | diff --git a/deploy/charts/cert-manager/webhook/templates/validating-webhook.yaml b/deploy/charts/cert-manager/webhook/templates/validating-webhook.yaml index de1ce6e39..428b816a1 100644 --- a/deploy/charts/cert-manager/webhook/templates/validating-webhook.yaml +++ b/deploy/charts/cert-manager/webhook/templates/validating-webhook.yaml @@ -8,7 +8,9 @@ metadata: release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: +{{- if .Values.injectAPIServerCA }} certmanager.k8s.io/inject-apiserver-ca: "true" +{{- end }} webhooks: - name: certificates.admission.certmanager.k8s.io namespaceSelector: diff --git a/deploy/charts/cert-manager/webhook/values.yaml b/deploy/charts/cert-manager/webhook/values.yaml index ab0c30e7a..84fe539f2 100644 --- a/deploy/charts/cert-manager/webhook/values.yaml +++ b/deploy/charts/cert-manager/webhook/values.yaml @@ -32,3 +32,10 @@ image: repository: quay.io/jetstack/cert-manager-webhook tag: v0.7.0-alpha.0 pullPolicy: IfNotPresent + +# if true, the apiserver's cabundle will be automatically injected into the +# webhook's ValidatingWebhookConfiguration resource by the CA injector. +# in future this will default to false, as the apiserver can use the loopback +# configuration caBundle to talk to itself in kubernetes 1.11+ +# see https://github.com/kubernetes/kubernetes/pull/62649 +injectAPIServerCA: true