Gardener v1.87+ shoot API server certificate rotation: transient x509 failures when control plane restarts during renewal
0 reputation · 23 Jul 2024, 09:37 UTC
0 reputation · 23 Jul 2024, 09:37 UTC
On Gardener v1.87+ shoots, certificate rotation via cert-manager updates the serving certificate secret, and the kube-apiserver is expected to pick it up through its TLS file watcher (Kubernetes >= v1.22) without a restart. The new CA bundle is then propagated to clients through the shoot's status credentials.
My concern is the ordering gap: if the kube-apiserver pod restarts (crash, node drain, or reconciliation-triggered rollout) after the secret is updated but before the file watcher reloads it, the API server may serve a certificate that clients no longer trust, producing intermittent x509: certificate signed by unknown authority errors. There appears to be no documented synchronization barrier ensuring all API server replicas have reloaded before the new CA bundle is published.
Assume a shoot on Kubernetes 1.28, Gardener v1.87, with manual rotation triggered via the gardener.cloud/operation=rotate-certificates annotation.
30275 reputation · 23 Jul 2024, 15:32 UTC
The rotation‑to‑reload window is not formally bounded; it is eventually consistent by design. Gardener publishes the new CA bundle to the shoot status as soon as the serving‑certificate secret is marked Ready, without waiting for all kube‑apiserver pods to reload the new TLS files. Consequently, if a control‑plane pod restarts after the secret update but before its file‑watcher reloads, it can serve a certificate that clients no longer trust, producing transient x509: certificate signed by unknown authority errors. Concurrent autoscaling of the API server during rotation widens this race because new replicas may start with the updated secret while old replicas still serve the old certificate, and the new CA bundle has not yet been propagated to clients.
--tls-cert-file-refresh-interval) and is not exposed in the Shoot spec.Ready condition is true. There is no built‑in barrier that waits for all API‑server pods to confirm reload.kubectl annotate shoot <shoot-name> gardener.cloud/operation=rotate-certificates --overwritekubectl get secret -n <seed-namespace> <tls-serving-secret> -o yaml -wReady: True, monitor the shoot status credentials for the new CA bundle: kubectl get shoot <shoot-name> -o jsonpath='{.status.credentials.kubeconfig}' | base64 -d | grep certificate-authority-datakubectl logs -n kube-system -l component=kube-apiserver | grep -i "TLS certificate reloaded"--tls-cert-file-refresh-interval set via spec.controlPlaneConfig.kubeApiserver.extraArgs, note that value; otherwise assume the default 10 min and plan accordingly.Do you have a custom tls-cert-file-refresh-interval configured for the shoot’s kube‑apiserver (via controlPlaneConfig)? Knowing the actual interval determines how long you must wait after the secret update before expecting all API‑server pods to have reloaded.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.