From 4e0116a54c6d0496cd0fdd4d18d669c31b954618 Mon Sep 17 00:00:00 2001 From: malingatembo Date: Wed, 1 Jul 2026 11:11:39 +0200 Subject: [PATCH] Secure TLS for Prometheus metrics endpoint Implement HTTPS serving for the operator's /metrics endpoint using OpenShift service-ca for automatic certificate management. Changes: - Add service-ca annotation to metrics Service for automatic cert generation - Mount certificate Secret in operator Pod - Configure metrics server to use service-ca certificates (TLS 1.3, HTTP/2 disabled) - Parameterize certificate paths via command-line flags (--cert-dir, --cert-name, --key-name) - Regenerate bundle manifests Note: ServiceMonitor TLS configuration (Prometheus scraping) will be handled in a follow-up ticket, as ../prometheus is currently commented out in the deployment. Fixes: OSPR-30557 --- ...ightspeed-operator-metrics_v1_service.yaml | 2 ++ ...tspeed-operator.clusterserviceversion.yaml | 8 ++++++++ cmd/main.go | 20 ++++++++++++------- config/default/metrics_service.yaml | 2 ++ config/manager/manager.yaml | 8 ++++++++ 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/bundle/manifests/openstack-lightspeed-operator-metrics_v1_service.yaml b/bundle/manifests/openstack-lightspeed-operator-metrics_v1_service.yaml index 906d54ae..6236f5bb 100644 --- a/bundle/manifests/openstack-lightspeed-operator-metrics_v1_service.yaml +++ b/bundle/manifests/openstack-lightspeed-operator-metrics_v1_service.yaml @@ -1,6 +1,8 @@ apiVersion: v1 kind: Service metadata: + annotations: + service.beta.openshift.io/serving-cert-secret-name: operator-metrics-tls creationTimestamp: null labels: app.kubernetes.io/managed-by: kustomize diff --git a/bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml b/bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml index 51669cc7..fb4b7d4b 100644 --- a/bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml +++ b/bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml @@ -331,10 +331,18 @@ spec: capabilities: drop: - ALL + volumeMounts: + - mountPath: /tmp/k8s-metrics-server/serving-certs + name: cert + readOnly: true securityContext: runAsNonRoot: true serviceAccountName: openstack-lightspeed-operator-controller-manager terminationGracePeriodSeconds: 10 + volumes: + - name: cert + secret: + secretName: operator-metrics-tls permissions: - rules: - apiGroups: diff --git a/cmd/main.go b/cmd/main.go index 60471435..519dd044 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -71,6 +71,9 @@ func main() { var probeAddr string var secureMetrics bool var enableHTTP2 bool + var certDir string + var certName string + var keyName string var tlsOpts []func(*tls.Config) flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+ "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.") @@ -82,6 +85,12 @@ func main() { "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") flag.BoolVar(&enableHTTP2, "enable-http2", false, "If set, HTTP/2 will be enabled for the metrics and webhook servers") + flag.StringVar(&certDir, "cert-dir", "/tmp/k8s-metrics-server/serving-certs", + "The directory where the TLS certificates are stored.") + flag.StringVar(&certName, "cert-name", "tls.crt", + "The name of the TLS certificate file.") + flag.StringVar(&keyName, "key-name", "tls.key", + "The name of the TLS key file.") opts := zap.Options{ Development: true, } @@ -116,13 +125,10 @@ func main() { metricsServerOptions := metricsserver.Options{ BindAddress: metricsAddr, SecureServing: secureMetrics, - // TODO(user): TLSOpts is used to allow configuring the TLS config used for the server. If certificates are - // not provided, self-signed certificates will be generated by default. This option is not recommended for - // production environments as self-signed certificates do not offer the same level of trust and security - // as certificates issued by a trusted Certificate Authority (CA). The primary risk is potentially allowing - // unauthorized access to sensitive metrics data. Consider replacing with CertDir, CertName, and KeyName - // to provide certificates, ensuring the server communicates using trusted and secure certificates. - TLSOpts: tlsOpts, + TLSOpts: tlsOpts, + CertDir: certDir, + CertName: certName, + KeyName: keyName, } if secureMetrics { diff --git a/config/default/metrics_service.yaml b/config/default/metrics_service.yaml index b580e957..fe32bdef 100644 --- a/config/default/metrics_service.yaml +++ b/config/default/metrics_service.yaml @@ -5,6 +5,8 @@ metadata: control-plane: controller-manager app.kubernetes.io/name: openstack-lightspeed-operator app.kubernetes.io/managed-by: kustomize + annotations: + service.beta.openshift.io/serving-cert-secret-name: operator-metrics-tls name: metrics namespace: system spec: diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 114e18cb..ac2b5350 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -113,5 +113,13 @@ spec: requests: cpu: 10m memory: 64Mi + volumeMounts: + - name: cert + mountPath: /tmp/k8s-metrics-server/serving-certs + readOnly: true serviceAccountName: controller-manager + volumes: + - name: cert + secret: + secretName: operator-metrics-tls terminationGracePeriodSeconds: 10