Which certificate does kubelet use?
This is a kubeadm based 1.16 cluster. The way I understand mTLS work between an apiserver & kubelet is:
apiserver -> kubelet
--kubelet-client-certificate & --kubelet-client-key => The certs & key given here(apiserver) is for apiserver(client) to kubelet (server)
--client-ca => The CA given here(kubelet) is what verfies if request from apiserver is indeed the right one.
And then we have the other way:
kubelet -> apiserver
--tls-cert-file & --tls-key-file => Passed in kubelet conf. Generally present at /var/lib/kubelet/pki/kubelet.{crt,key}
--kubelet-certificate-authority => The above cert gets verified by this CA passed in apiserver
However, there is a kubelet.conf
file present at /etc/kubernetes which again has client-certificate-data
and client-key-data
. When is this client-cert used?
Also, if we enable auto-rotation in kubelet, there is a client-cert under /var/lib/kubelet/pki/kubelet-client-current.pem
which may or may not be referenced in kubelet.conf based on the kubeadm version used (because of the bug in kubeadm prior to 1.17). I'm confused on how & when are the kubelet client cert used. Any help on this?
The client-certificate-data
and client-key-data
are there due to a bug. This is well reflected by the official docs:
Warning: On nodes created with
kubeadm init
, prior to kubeadm version 1.17, there is a bug where you manually have to modify the contents ofkubelet.conf
. Afterkubeadm init
finishes, you should updatekubelet.conf
to point to the rotated kubelet client certificates, by replacingclient-certificate-data
andclient-key-data
with:client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
Some useful sources with more info:
-
PKI certificates and requirements
-
Certificate Management with kubeadm
EDIT:
Based on the kubelet integration:
When you run
kubeadm join
, kubeadm uses the Bootstrap Token credential to perform a TLS bootstrap, which fetches the credential needed to download the kubelet-config-1.X ConfigMap and writes it to/var/lib/kubelet/config.yaml
. The dynamic environment file is generated in exactly the same way askubeadm init
.Next,
kubeadm
runs the following two commands to load the new configuration into the kubelet:systemctl daemon-reload && systemctl restart kubelet
After the kubelet loads the new configuration, kubeadm writes the
/etc/kubernetes/bootstrap-kubelet.conf
KubeConfig file, which contains a CA certificate and Bootstrap Token. These are used by the kubelet to perform the TLS Bootstrap and obtain a unique credential, which is stored in/etc/kubernetes/kubelet.conf
. When this file is written, the kubelet has finished performing the TLS Bootstrap.
This indicates that cert/credentials stored in kubelet.conf
are used during kubelet startup process. Removing this file or changing its content will be verified during kubelet restart. This can be tested yourself as below:
- If you remove the file:
failed to run kubelet: unable to load bootstrap kubeconfig
- If you misconfigure the file or provide wrong certs:
config loaded from file: /etc/kubernetes/kubelet/conf
bootstrap.go:240 unable to read existing bootstrap client config: f.e. invalid configuration
or unable to load TLS certificates from existing bootstrap client config: data does not contain any valid RSA or ECDSA certificate
Also, as a side note:
I strongly recommend using a newer version of Kubernetes as yours is 5 major versions older than the current stable one: 1.21 / April 8, 2021. Keeping things up-to-date will save you a lot of trouble in the future.