🇧🇷 Leia a versão em português aqui.
In on-premise Kubernetes installations set up with kubeadm, the cluster's internal certificates (used for authentication between control-plane components) are generated with a 1-year validity period by default. Once that period passes, it's common to start seeing an error like this when trying to use kubectl:
Unable to connect to the server: x509: certificate has expired or is not yet valid.
This is purely a maintenance issue — it doesn't indicate a configuration failure — but if left unaddressed, it leaves the cluster inaccessible via kubectl. In this article, I show how to check and renew these certificates.
Checking certificate validity
Before renewing, you can check the current state (and expiration date) of each cluster certificate:
kubeadm certs check-expiration
This command lists all certificates generated by kubeadm, indicating which have already expired and which are still valid — useful both for diagnosing the error and for proactively tracking when the next renewal will be needed.
Renewing the certificates
To renew all certificates at once, run this on the master server:
kubeadm certs renew all
The output should confirm that the certificates were renewed:
Done renewing certificates. You must restart the kube-apiserver, kube-controller-manager, kube-scheduler and etcd, so that they can use the new certificates.
As the command itself indicates, renewal alone isn't enough — the control-plane components need to be restarted to start using the new certificates.
Updating kubectl access
Since admin.conf is also generated from the old certificates, you need to copy it again to your ~/.kube/config after the renewal:
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Without this step, even with the certificates renewed in the cluster, kubectl will keep using the old (already expired) credentials locally.
Restarting the control-plane components
Finally, force the recreation of the static pods responsible for the control-plane, so they load the new certificates:
kubectl -n kube-system delete pod -l 'component=kube-apiserver'
kubectl -n kube-system delete pod -l 'component=kube-controller-manager'
kubectl -n kube-system delete pod -l 'component=kube-scheduler'
kubectl -n kube-system delete pod -l 'component=etcd'
These are static pods, managed directly by the kubelet (not by a Deployment or ReplicaSet) — so when deleted, the kubelet itself automatically recreates them, already reading the updated certificates.
Preventing the problem in the future
Since certificates expire annually by default, it's worth considering:
- Running
kubeadm certs check-expirationperiodically (for example, via a monitoring cron job), to be warned before expiration happens; - Documenting the installation date (or the date of the last renewal) of the cluster, since the error usually only shows up when someone tries to access the cluster and
kubectlno longer works.
This is one of those procedures that's simple but easy to forget — especially in lab or staging clusters that go months without direct interaction.
Top comments (0)