By default Kubernetes client certificates generated by kubeadm expire after 1 year. When that happens, you can no longer communicate with or control the cluster. Here’s how to resolve the issue permanently.
Prerequisite
Docker to use official image to build a customize kubeadm
kubectl to access cluster control plane
ssh access to cluster master node to upload and run customized kubeadm
Pre-Check
Before we start, let us log on the master node and get the certificates status.
1
kubeadm alpha certs check-expiration
We got 45 days left to renew our certificates.
1
2
3
4
5
6
7
8
9
10
11
CERTIFICATE EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
admin.conf Dec 02, 2022 23:24 UTC 45d no
apiserver Dec 02, 2022 23:24 UTC 45d no
apiserver-etcd-client Dec 02, 2022 23:24 UTC 45d no
apiserver-kubelet-client Dec 02, 2022 23:24 UTC 45d no
controller-manager.conf Dec 02, 2022 23:24 UTC 45d no
etcd-healthcheck-client Dec 02, 2022 23:24 UTC 45d no
etcd-peer Dec 02, 2022 23:24 UTC 45d no
etcd-server Dec 02, 2022 23:24 UTC 45d no
front-proxy-client Dec 02, 2022 23:24 UTC 45d no
scheduler.conf Dec 02, 2022 23:24 UTC 45d no
And we have to make sure what kubernetes version exactly we are using.
1
2
3
4
5
6
7
8
9
10
11
kubectl get node
# NAME STATUS ROLES AGE VERSION# ip-xxxxx.compute.internal Ready master 2y320d v1.16.1# ip-zzzzz.compute.internal Ready <none> 2y249d v1.16.1kubeadm version
# kubeadm version: &version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.1", GitCommit:"d647ddbd755faf07169599a625faf302ffc34458", GitTreeState:"clean", BuildDate:"2019-10-02T16:58:27Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}
As we can see from both kubectl and kubeadm, v1.16.1 is the version we are going to us
Customize
Now we can build a customized kubeadm based on official upstream source code.
We can lauch a container using this image to do build kubeadm binary in kubernetes source repository directory.
1
2
3
4
5
6
7
docker run --rm -v `pwd`:/go/src/k8s.io/kubernetes \
-it gcr.io/google_containers/kube-cross:v1.12.10-1 bash
# in containercd /go/src/k8s.io/kubernetes
make all WHAT=cmd/kubeadm GOFLAGS=-v
Then we can find our customized kubeadm in _output/local/bin/linux/amd64/kubeadm. To check out our results we can run:
It’s always a best practice to backup everything before we make any changes in production.
1
2
3
4
mkdir backups
cp /etc/kubernetes/pki/ backups/ -a
mv `which kubeadm` backups/ -a
cp /etc/kubernetes/kubelet.conf backups/
Then we have to replace kubeadm with our customized one.
1
cp /tmp/kubeadm /usr/bin/kubeadm
Finally we can perform the renew action and restart kubernetes control plane to effect.
1
2
3
4
5
6
7
8
9
kubeadm alpha certs renew all
# If you have multiple master nodes, run this command on# every master node to restart all control plane containersdocker ps | grep -v pause | grep -E "etcd|scheduler|controller|apiserver" | \
awk '{print $1}' | awk '{print "docker","restart",$1}' | bash
# update client config if youcp -i /etc/kubernetes/admin.conf $HOME/.kube/config
To checkout the results, we can run check-expiration again and we should see that certificates expiration won’t be a problem for us.
1
kubeadm alpha certs check-expiration
Summary
Do bear in mind that it is a not a best practice to use such long-term certificates which may cause security issues if certficates are not being kept properly. While in some environments on which you may be not willing to spend too much time to maintain or in most cases operate in a secured interal network, it can be a simple and easy way to do so.
kubeadm may differ if your Kubernetes version is not v1.16.x. Refer to official docs according to your own version.