Calculating the CA Certificate Hash for Kubeadm
Published on 12 Jul 2019 · Filed in Tutorial · 564 words (estimated 3 minutes to read)When using kubeadm
to set up a new Kubernetes cluster, the output of the kubeadm init
command that sets up the control plane for the first time contains some important information on joining additional nodes to the cluster. One piece of information in there that (until now) I hadn’t figured out how to replicate was the CA certificate hash. (Primarily I hadn’t figured it out because I hadn’t tried.) In this post, I’ll share how to calculate the CA certificate hash for kubeadm
to use when joining additional nodes to an existing cluster.
When looking to figure this out, I first started with the kubeadm
documentation. My searches led me here, which states:
The hash is calculated over the bytes of the Subject Public Key Info (SPKI) object (as in RFC7469). This value is available in the output of “kubeadm init” or can be calculated using standard tools.
That’s useful information, but what are the “standard tools” being referenced? I knew that a lot of work had been put into kubeadm init phase
(for breaking down the kubeadm init
workflow), but a quick review of that documentation didn’t reveal anything. Reviewing the referenced RFC also didn’t provide any suggestions on how the hash might be calculated. I’d messed around with openssl x509
with Kubernetes before (see this post or this post), so how about some trial-and-error?
Starting with what I knew, I started with decoding the certificate using openssl
. After reading some openssl
man pages, I arrived at this command to extract only the public key of the certificate:
openssl x509 -in /etc/kubernetes/pki/ca.crt -pubkey -noout
(Side note: the use of -noout
threw me for a bit; it says “No output, just status”, but what it really means is don’t output anything more than what I’ve already told you to output with -pubkey
or other flags.)
From there it was experimenting with openssl dgst
to see if I could get results that matched against some known CA certificate hashes I’d captured for clusters I’d built. I wasn’t having much success until I stumbled on this Stack Overflow post, which pointed me in the direction of openssl pkey
. That was the missing link I needed.
So, the final command is this:
openssl x509 -in /etc/kubernetes/pki/ca.crt -pubkey -noout |
openssl pkey -pubin -outform DER |
openssl dgst -sha256
I shared this with my team members (sharing is caring!), and my teammate Naadir Jeewan promptly responded with an Ansible filter to perform the same task. This is helpful when openssl
isn’t present on the system where you need to calculate the hash. Naadir’s Ansible filter is found here (great work, Naadir!).
There you have it. Next time you find yourself needing to calculate the CA certificate hash to use with kubeadm
, you now have two ways of getting there (either using openssl
or using Naadir’s Ansible filter).
If you have any questions, don’t hesitate to reach out to me on Twitter. Thanks!
UPDATE: Apparently, I overlooked a portion of the official documentation for kubeadm join
, which does provide a mechanism for using openssl
to calculate the CA cert hash. I checked the documentation back to version 1.15, and the information is there. (No idea how I missed this!) See the section titled “Token-based discovery with CA pinning” for another openssl
command you can use to calculate the CA cert hash. Thanks to Dan Webster for pointing this out!