Kubeadm is unable to sign certificate on upgrade

9/20/2019

During Kubernetes upgrade from 1.14 to 1.15 with kubespray, my team had a blocking issue with the following message during the "Upgrade first master" step :

[upgrade/apply] FATAL: couldn''t upgrade control plane.
kubeadm has tried to recover everything into the earlier state.
Errors faced: [failed to renew certificates for component "kube-apiserver":
failed to renew certificate apiserver-kubelet-client:
unable to sign certificate:
must specify at least one ExtKeyUsage,
rename /etc/kubernetes/tmp/kubeadm
-backup-manifests-2019-09-19-09-06-27/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml: no such file or directory]'

Trying to isolate the task and manually running the kubeadm command line leads to the same error message :

#/usr/local/bin/kubeadm upgrade apply -y v1.15.3 --config=/etc/kubernetes/kubeadm-config.yaml --ignore-preflight-errors=all --allow-experimental-upgrades --allow-release-candidate-upgrades --etcd-upgrade=false -v 6 

or even trying to just manually renew the certificate :

/etc/kubernetes/pki# kubeadm alpha certs renew apiserver-kubelet-client -v 9
I0919 14:42:11.515503   18597 initconfiguration.go:105] detected and using CRI socket: /var/run/dockershim.sock
I0919 14:42:11.515897   18597 interface.go:384] Looking for default routes with IPv4 addresses
I0919 14:42:11.515916   18597 interface.go:389] Default route transits interfaceeth0I0919 14:42:11.516284   18597 interface.go:196] Interface eth0 is up
(...)
I0919 14:42:11.516835   18597 feature_gate.go:216] feature gates: &{map[]}
failed to renew certificate apiserver-kubelet-client: unable to sign certificate: must specify at least one ExtKeyUsage

The solution was found eventually and posted below.

-- Orabîg
kubernetes
kubespray

1 Answer

9/20/2019

The issue comes from kubeadm which uses the old certificates when it has to renew them. But when these initial certificates are too old or were manually generated, they may not include some mandatory fields that needs to be there.

In the error message, ExtKeyUsage refers to the X509v3 Extended Key Usage field.

You can check that by looking into your certificates : 2 certificates are involved : apiserver-kubelet-client.crt and front-proxy-client.crt

They are located on the master hosts at /etc/kubernetes/pki.

You can check them with

# openssl x509 -in apiserver-kubelet-client.crt -text -noout

If they do not contain the following (near the end), then kubeadm will be totally unable to renew the certificate

(...)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication

TL;DR;

The solution is simply to create brand new certificates with the following procedure

######### Backup your certificates (just in case)
master01:/etc/kubernetes/pki# cp -a /etc/kubernetes/pki /root/backup_cert/
######### Delete incomplete certificates
master01:/etc/kubernetes/pki# rm apiserver-kubelet-client.*
master01:/etc/kubernetes/pki# rm front-proxy-client.*
######### Then recreate them
master01:/etc/kubernetes/pki# kubeadm init phase certs apiserver-kubelet-client 
master01:/etc/kubernetes/pki# kubeadm init phase certs front-proxy-client

You can now restart your upgrade procedure which should be ok. (Note : if your cluster was left in a state where your first master has a SchedulingDisabled state, then do not forget to uncordon the host, because kubespray playbook won't fix that)

-- Orabîg
Source: StackOverflow