Skip to content

Commit dcf49ca

Browse files
feat/fix: enhance cert-manager integration for metrics endpoints (follow-up to PR kubernetes-sigs#4243)
This commit is a follow-up to PR kubernetes-sigs#4243, which introduced support for using cert-manager certificates for securing the metrics endpoint and ServiceMonitor. Related to kubernetes-sigs#3871 and kubernetes-sigs#4003 Key enhancements: - Added support for configuring certificate integration via a Kustomize patch. - Introduced configurable flags for greater flexibility in customization. - Use Certwatcher to allow certificate rotation This configuration provides an option for users to be production-ready
1 parent d240946 commit dcf49ca

File tree

77 files changed

+1540
-686
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1540
-686
lines changed

.github/workflows/test-e2e-samples.yml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ jobs:
4141
run: |
4242
KUSTOMIZATION_FILE_PATH="testdata/project-v4/config/default/kustomization.yaml"
4343
sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH
44+
sed -i '47,49s/^#//' $KUSTOMIZATION_FILE_PATH
4445
# Uncomment all cert-manager injections
45-
sed -i '55,168s/^#//' $KUSTOMIZATION_FILE_PATH
46-
sed -i '170,185s/^#//' $KUSTOMIZATION_FILE_PATH
46+
sed -i '57,210s/^#//' $KUSTOMIZATION_FILE_PATH
47+
sed -i '212,227s/^#//' $KUSTOMIZATION_FILE_PATH
4748
cd testdata/project-v4/
4849
go mod tidy
4950
@@ -85,10 +86,11 @@ jobs:
8586
# Uncomment only ValidatingWebhookConfiguration
8687
# from cert-manager replaces; we are leaving defaulting uncommented
8788
# since this sample has no defaulting webhooks
88-
sed -i '55,121s/^#//' $KUSTOMIZATION_FILE_PATH
89+
sed -i '57,57s/^#//' $KUSTOMIZATION_FILE_PATH
90+
sed -i '133,162s/^#//' $KUSTOMIZATION_FILE_PATH
8991
# Uncomment only --conversion webhooks CA injection
90-
sed -i '153,168s/^#//' $KUSTOMIZATION_FILE_PATH
91-
sed -i '170,185s/^#//' $KUSTOMIZATION_FILE_PATH
92+
sed -i '195,210s/^#//' $KUSTOMIZATION_FILE_PATH
93+
sed -i '212,227s/^#//' $KUSTOMIZATION_FILE_PATH
9294
cd testdata/project-v4-with-plugins/
9395
go mod tidy
9496
@@ -127,9 +129,10 @@ jobs:
127129
run: |
128130
KUSTOMIZATION_FILE_PATH="testdata/project-v4-multigroup/config/default/kustomization.yaml"
129131
sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH
130-
# Uncomment all cert-manager injections
131-
sed -i '55,168s/^#//' $KUSTOMIZATION_FILE_PATH
132-
sed -i '170,185s/^#//' $KUSTOMIZATION_FILE_PATH
132+
# Uncomment all cert-manager injections for webhooks only
133+
sed -i '57,57s/^#//' $KUSTOMIZATION_FILE_PATH
134+
sed -i '96,210s/^#//' $KUSTOMIZATION_FILE_PATH
135+
sed -i '212,227s/^#//' $KUSTOMIZATION_FILE_PATH
133136
cd testdata/project-v4-multigroup
134137
go mod tidy
135138

docs/book/src/cronjob-tutorial/running.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ cluster with, so we don't need to worry about RBAC just yet.
2626

2727
If you want to run the webhooks locally, you'll have to generate
2828
certificates for serving the webhooks, and place them in the right
29-
directory (`/tmp/k8s-webhook-server/serving-certs/tls.{crt,key}`, by
29+
directory (`/tmp/k8s-metrics-server/metrics-certs/tls.{crt,key}`, by
3030
default).
3131

3232
If you're not running a local API server, you'll also need to figure out

docs/book/src/cronjob-tutorial/testdata/project/cmd/main.go

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"crypto/tls"
2222
"flag"
2323
"os"
24+
"path/filepath"
2425

2526
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
2627
// to ensure that exec-entrypoint and run can make use of them.
@@ -30,6 +31,7 @@ import (
3031
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
3132
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
3233
ctrl "sigs.k8s.io/controller-runtime"
34+
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
3335
"sigs.k8s.io/controller-runtime/pkg/healthz"
3436
"sigs.k8s.io/controller-runtime/pkg/log/zap"
3537
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
@@ -54,8 +56,9 @@ Builtin types such as Job have their scheme added by `clientgoscheme`.
5456
*/
5557

5658
var (
57-
scheme = runtime.NewScheme()
58-
setupLog = ctrl.Log.WithName("setup")
59+
scheme = runtime.NewScheme()
60+
setupLog = ctrl.Log.WithName("setup")
61+
certWatcher *certwatcher.CertWatcher
5962
)
6063

6164
func init() {
@@ -74,6 +77,9 @@ func main() {
7477
/*
7578
*/
7679
var metricsAddr string
80+
var certDir string
81+
var certName string
82+
var certKey string
7783
var enableLeaderElection bool
7884
var probeAddr string
7985
var secureMetrics bool
@@ -87,6 +93,10 @@ func main() {
8793
"Enabling this will ensure there is only one active controller manager.")
8894
flag.BoolVar(&secureMetrics, "metrics-secure", true,
8995
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
96+
flag.StringVar(&certDir, "cert-dir", "",
97+
"The directory that contains the server key and certificate. If set, the metrics server will serve using the provided key and certificate.")
98+
flag.StringVar(&certName, "cert-name", "tls.crt", "CertName is the server certificate name. Defaults to tls.crt")
99+
flag.StringVar(&certKey, "cert-key", "tls.key", "KeyName is the server key name. Defaults to tls.key")
90100
flag.BoolVar(&enableHTTP2, "enable-http2", false,
91101
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
92102
opts := zap.Options{
@@ -133,16 +143,27 @@ func main() {
133143
// https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/metrics/filters#WithAuthenticationAndAuthorization
134144
metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
135145

136-
// TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically
146+
// If cert-name, cert-key, and cert-name are not specified, controller-runtime will automatically
137147
// generate self-signed certificates for the metrics server. While convenient for development and testing,
138148
// this setup is not recommended for production.
139-
140-
// TODO(user): If cert-manager is enabled in config/default/kustomization.yaml,
141-
// you can uncomment the following lines to use the certificate managed by cert-manager.
142-
// metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs"
143-
// metricsServerOptions.CertName = "tls.crt"
144-
// metricsServerOptions.KeyName = "tls.key"
145-
149+
//
150+
// TODO(user): If you are using cert-manager, enable [METRICS-WITH-CERTS] at config/default/kustomization.yaml"
151+
// to generate and use certificates managed by cert-manager for the metrics server.
152+
if len(certDir) > 0 {
153+
setupLog.Info("using certificates for the metrics server",
154+
"cert-dir", certDir, "cert-name", certName, "cert-key", certKey)
155+
156+
var err error
157+
certWatcher, err = certwatcher.New(filepath.Join(certDir, certName), filepath.Join(certDir, certKey))
158+
if err != nil {
159+
setupLog.Error(err, "to initialize certificate watcher", "error", err)
160+
os.Exit(1)
161+
}
162+
163+
metricsServerOptions.TLSOpts = append(metricsServerOptions.TLSOpts, func(config *tls.Config) {
164+
config.GetCertificate = certWatcher.GetCertificate
165+
})
166+
}
146167
}
147168

148169
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
@@ -196,6 +217,14 @@ func main() {
196217
}
197218
// +kubebuilder:scaffold:builder
198219

220+
if secureMetrics && certWatcher != nil {
221+
setupLog.Info("Adding certificate watcher to manager")
222+
if err := mgr.Add(certWatcher); err != nil {
223+
setupLog.Error(err, "unable to add certificate watcher to manager")
224+
os.Exit(1)
225+
}
226+
}
227+
199228
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
200229
setupLog.Error(err, "unable to set up health check")
201230
os.Exit(1)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# The following manifests contain a self-signed issuer CR and a metrics certificate CR.
2+
# More document can be found at https://docs.cert-manager.io
3+
apiVersion: cert-manager.io/v1
4+
kind: Certificate
5+
metadata:
6+
labels:
7+
app.kubernetes.io/name: project
8+
app.kubernetes.io/managed-by: kustomize
9+
name: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml
10+
namespace: system
11+
spec:
12+
dnsNames:
13+
# SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
14+
# replacements in the config/default/kustomization.yaml file.
15+
- SERVICE_NAME.SERVICE_NAMESPACE.svc
16+
- SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local
17+
issuerRef:
18+
kind: Issuer
19+
name: selfsigned-issuer
20+
secretName: metrics-server-cert # this secret will not be prefixed, since it's not managed by kustomize
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# The following manifests contain a self-signed issuer CR and a certificate CR.
2+
# More document can be found at https://docs.cert-manager.io
3+
apiVersion: cert-manager.io/v1
4+
kind: Certificate
5+
metadata:
6+
labels:
7+
app.kubernetes.io/name: project
8+
app.kubernetes.io/managed-by: kustomize
9+
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
10+
namespace: system
11+
spec:
12+
# SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
13+
# replacements in the config/default/kustomization.yaml file.
14+
dnsNames:
15+
- SERVICE_NAME.SERVICE_NAMESPACE.svc
16+
- SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local
17+
issuerRef:
18+
kind: Issuer
19+
name: selfsigned-issuer
20+
secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize

docs/book/src/cronjob-tutorial/testdata/project/config/certmanager/certificate.yaml

Lines changed: 0 additions & 57 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# The following manifest contains a self-signed issuer CR.
2+
# More information can be found at https://docs.cert-manager.io
3+
# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes.
4+
apiVersion: cert-manager.io/v1
5+
kind: Issuer
6+
metadata:
7+
labels:
8+
app.kubernetes.io/name: project
9+
app.kubernetes.io/managed-by: kustomize
10+
name: selfsigned-issuer
11+
namespace: system
12+
spec:
13+
selfSigned: {}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
resources:
2-
- certificate.yaml
2+
- issuer.yaml
3+
- certificate-webhook.yaml
4+
- certificate-metrics.yaml
35

46
configurations:
57
- kustomizeconfig.yaml
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# This patch adds the args and volumes to allow the manager to use the metrics-server certs
2+
# Ensure the volumeMounts field exists by creating it if missing
3+
- op: add
4+
path: /spec/template/spec/containers/0/volumeMounts
5+
value: []
6+
# Add the volume mount for the serving certificates
7+
- op: add
8+
path: /spec/template/spec/containers/0/volumeMounts/-
9+
value:
10+
mountPath: /var/metrics/certs/
11+
name: metrics-certs
12+
readOnly: true
13+
# Add the cert-dir argument
14+
- op: add
15+
path: /spec/template/spec/containers/0/args/-
16+
value: --cert-dir=/var/metrics/certs/
17+
# Ensure the volumes field exists by creating it if missing
18+
- op: add
19+
path: /spec/template/spec/volumes
20+
value: []
21+
# Add the volume for the serving certificates
22+
- op: add
23+
path: /spec/template/spec/volumes/-
24+
value:
25+
name: metrics-certs
26+
secret:
27+
secretName: metrics-server-cert
28+
optional: false
29+
items:
30+
- key: ca.crt
31+
path: ca.crt
32+
- key: tls.crt
33+
path: tls.crt
34+
- key: tls.key
35+
path: tls.key

docs/book/src/cronjob-tutorial/testdata/project/config/default/certmanager_metrics_manager_patch.yaml

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)