From f2e382e566726d6f45f05507a571f74d0205d319 Mon Sep 17 00:00:00 2001 From: Philippe Scorsolini Date: Mon, 9 Oct 2023 09:01:16 +0200 Subject: [PATCH 1/2] feat: add readiness and liveness probes to crossplane Signed-off-by: Philippe Scorsolini --- .../crossplane/templates/deployment.yaml | 12 +++++- cmd/crossplane/core/core.go | 38 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/cluster/charts/crossplane/templates/deployment.yaml b/cluster/charts/crossplane/templates/deployment.yaml index df77fd084e7..7d066b60556 100644 --- a/cluster/charts/crossplane/templates/deployment.yaml +++ b/cluster/charts/crossplane/templates/deployment.yaml @@ -123,9 +123,17 @@ spec: name: {{ .Chart.Name }} resources: {{- toYaml .Values.resourcesCrossplane | nindent 12 }} - {{- if or .Values.metrics.enabled (.Values.webhooks.enabled) }} + livenessProbe: + httpGet: + path: /healthz + port: healthz + readinessProbe: + httpGet: + path: /readyz + port: healthz ports: - {{- end }} + - name: healthz + containerPort: 5000 {{- if .Values.metrics.enabled }} - name: metrics containerPort: 8080 diff --git a/cmd/crossplane/core/core.go b/cmd/crossplane/core/core.go index 160323d9cff..baf00c95d93 100644 --- a/cmd/crossplane/core/core.go +++ b/cmd/crossplane/core/core.go @@ -36,6 +36,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/webhook" "github.com/crossplane/crossplane-runtime/pkg/certificates" @@ -188,6 +189,8 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli LeaderElectionResourceLock: resourcelock.LeasesResourceLock, LeaseDuration: func() *time.Duration { d := 60 * time.Second; return &d }(), RenewDeadline: func() *time.Duration { d := 50 * time.Second; return &d }(), + + HealthProbeBindAddress: ":5000", }) if err != nil { return errors.Wrap(err, "Cannot create manager") @@ -298,17 +301,46 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli // fleshed out, implement a registration pattern similar to scheme // registrations. if err := xrd.SetupWebhookWithManager(mgr, o); err != nil { - return errors.Wrap(err, "cannot setup webhook for compositeresourcedefinitions") + return errors.Wrap(err, "Cannot setup webhook for compositeresourcedefinitions") } if err := composition.SetupWebhookWithManager(mgr, o); err != nil { - return errors.Wrap(err, "cannot setup webhook for compositions") + return errors.Wrap(err, "Cannot setup webhook for compositions") } if o.Features.Enabled(features.EnableAlphaUsages) { if err := usage.SetupWebhookWithManager(mgr, o); err != nil { - return errors.Wrap(err, "cannot setup webhook for usages") + return errors.Wrap(err, "Cannot setup webhook for usages") } } } + if err := c.SetupProbes(mgr); err != nil { + return errors.Wrap(err, "Cannot setup probes") + } + return errors.Wrap(mgr.Start(ctrl.SetupSignalHandler()), "Cannot start controller manager") } + +// SetupProbes sets up the health and ready probes. +func (c *startCommand) SetupProbes(mgr ctrl.Manager) error { + // Add default readiness probe + if err := mgr.AddReadyzCheck("ping", healthz.Ping); err != nil { + return errors.Wrap(err, "cannot create ping ready check") + } + + // Add default health probe + if err := mgr.AddHealthzCheck("ping", healthz.Ping); err != nil { + return errors.Wrap(err, "cannot create ping health check") + } + + // Add probes waiting for the webhook server if webhooks are enabled + if c.WebhookEnabled { + hookServer := mgr.GetWebhookServer() + if err := mgr.AddReadyzCheck("webhook", hookServer.StartedChecker()); err != nil { + return errors.Wrap(err, "cannot create webhook ready check") + } + if err := mgr.AddHealthzCheck("webhook", hookServer.StartedChecker()); err != nil { + return errors.Wrap(err, "cannot create webhook health check") + } + } + return nil +} From 990228f24caafe5daa1f115b868bf51ca66aa22d Mon Sep 17 00:00:00 2001 From: Philippe Scorsolini Date: Mon, 9 Oct 2023 10:32:33 +0200 Subject: [PATCH 2/2] chore: all lower case errors Signed-off-by: Philippe Scorsolini --- cmd/crossplane/core/core.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cmd/crossplane/core/core.go b/cmd/crossplane/core/core.go index baf00c95d93..783d7c93ab5 100644 --- a/cmd/crossplane/core/core.go +++ b/cmd/crossplane/core/core.go @@ -149,7 +149,7 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli cfg, err := ctrl.GetConfig() if err != nil { - return errors.Wrap(err, "Cannot get config") + return errors.Wrap(err, "cannot get config") } cfg.WarningHandler = rest.NewWarningWriter(os.Stderr, rest.WarningWriterOptions{ @@ -193,7 +193,7 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli HealthProbeBindAddress: ":5000", }) if err != nil { - return errors.Wrap(err, "Cannot create manager") + return errors.Wrap(err, "cannot create manager") } o := controller.Options{ @@ -253,7 +253,7 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli filepath.Join(c.TLSClientCertsDir, corev1.TLSPrivateKeyKey), false) if err != nil { - return errors.Wrap(err, "Cannot load TLS certificates for external secret stores") + return errors.Wrap(err, "cannot load TLS certificates for external secret stores") } o.ESSOptions = &controller.ESSOptions{ @@ -270,7 +270,7 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli } if err := apiextensions.Setup(mgr, ao); err != nil { - return errors.Wrap(err, "Cannot setup API extension controllers") + return errors.Wrap(err, "cannot setup API extension controllers") } po := pkgcontroller.Options{ @@ -285,13 +285,13 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli if c.CABundlePath != "" { rootCAs, err := ParseCertificatesFromPath(c.CABundlePath) if err != nil { - return errors.Wrap(err, "Cannot parse CA bundle") + return errors.Wrap(err, "cannot parse CA bundle") } po.FetcherOptions = append(po.FetcherOptions, xpkg.WithCustomCA(rootCAs)) } if err := pkg.Setup(mgr, po); err != nil { - return errors.Wrap(err, "Cannot add packages controllers to manager") + return errors.Wrap(err, "cannot add packages controllers to manager") } // Registering webhooks with the manager is what actually starts the webhook @@ -301,23 +301,23 @@ func (c *startCommand) Run(s *runtime.Scheme, log logging.Logger) error { //noli // fleshed out, implement a registration pattern similar to scheme // registrations. if err := xrd.SetupWebhookWithManager(mgr, o); err != nil { - return errors.Wrap(err, "Cannot setup webhook for compositeresourcedefinitions") + return errors.Wrap(err, "cannot setup webhook for compositeresourcedefinitions") } if err := composition.SetupWebhookWithManager(mgr, o); err != nil { - return errors.Wrap(err, "Cannot setup webhook for compositions") + return errors.Wrap(err, "cannot setup webhook for compositions") } if o.Features.Enabled(features.EnableAlphaUsages) { if err := usage.SetupWebhookWithManager(mgr, o); err != nil { - return errors.Wrap(err, "Cannot setup webhook for usages") + return errors.Wrap(err, "cannot setup webhook for usages") } } } if err := c.SetupProbes(mgr); err != nil { - return errors.Wrap(err, "Cannot setup probes") + return errors.Wrap(err, "cannot setup probes") } - return errors.Wrap(mgr.Start(ctrl.SetupSignalHandler()), "Cannot start controller manager") + return errors.Wrap(mgr.Start(ctrl.SetupSignalHandler()), "cannot start controller manager") } // SetupProbes sets up the health and ready probes.