In this article, we will learn to create and provide TLS certificates for all the components that make up a Kubernetes Cluster.
Pre-requisites
- Local System (4 GB RAM, CPU capable of virtualization)
OR
- Cloud (1 GB RAM, Linux Operating System) x 2
Certificate Authority
Let's start by generating the Certificate Authority (CA) for the master node. The master node is the primary server, and the certificates that the worker nodes will use need to be signed by master node's CA.
Setting Up Environment Variables
To avoid having to enter long values every time we enter a command (which we will do a lot of), values will be added into environment variables, which we can then call upon to add values in the desired places.
MASTER=192.168.1.22
SERVICE_CIDR=10.96.0.0/24
API_SERVICE=$(echo $SERVICE_CIDR | awk 'BEGIN {FS="."} ; { printf("%s.%s.%s.1", $1, $2, $3) }')Check if the environment variables were set up correctly.
echo $MASTER
echo $SERVICE_CIDR
echo $API_SERVICE
192.168.1.22
10.96.0.0/24
10.96.0.1Generating the CA Certificate
Now we'll generate the CA Certificate – the main certificate responsible for signing all the certificates we generate later. If the certificate has not been signed with the CA key, the provided certificate of the components will be invalid.
#Generating Private Key for CA
openssl genrsa -out ca.key 2048
#To avoid permission issues, we'll comment the line starting with string RANDFILE
sudo sed -i '0,/RANDFILE/{s/RANDFILE/\#&/}' /etc/ssl/openssl.cnf
#Creating CSR with the help of Private Key
openssl req -new -key ca.key -subj "/CN=KUBERNETES-CA/O=Kubernetes" -out ca.csr
#Self sign the csr using its own private key with 1000 day validity
openssl x509 -req -in ca.csr -signkey ca.key -CAcreateserial -out ca.crt -days 1000Output:
ca.crt
ca.keyGenerating Client and Server Certificates
We will now generate certificates for all the components of our Kubernetes Cluster.
Admin Client Certificate
This certificate and key pair will be used by an admin to authenticate with the cluster.
openssl genrsa -out admin.key 2048
openssl req -new -key admin.key -subj "/CN=admin/O=system:masters" -out admin.csr
openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out admin.crt -days 1000Output:
admin.key
admin.crtKube Controller Manager Certificate
The commands below will be used to generate kube-controller-manager client certificate and private key.
openssl genrsa -out kube-controller-manager.key 2048
openssl req -new -key kube-controller-manager.key \
-subj "/CN=system:kube-controller-manager/O=system:kube-controller-manager" -out kube-controller-manager.csr
openssl x509 -req -in kube-controller-manager.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial -out kube-controller-manager.crt -days 1000kube-controller-manager Client Certificate and KeyKube Proxy Certificate
The commands below will be used to generate kube-proxy client certificate and private key.
openssl genrsa -out kube-proxy.key 2048
openssl req -new -key kube-proxy.key \
-subj "/CN=system:kube-proxy/O=system:node-proxier" -out kube-proxy.csr
openssl x509 -req -in kube-proxy.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial -out kube-proxy.crt -days 1000kube-proxy Client Certificate and KeyThe Scheduler Client Certificate
Using the commands below, we can generate kube-scheduler client certificate and private key.
openssl genrsa -out kube-scheduler.key 2048
openssl req -new -key kube-scheduler.key \
-subj "/CN=system:kube-scheduler/O=system:kube-scheduler" -out kube-scheduler.csr
openssl x509 -req -in kube-scheduler.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kube-scheduler.crt -days 100kube-scheduler Client Certificate and KeyKubernetes API Server Certificate
As openssl cannot take alternate names as command line parameters, we'll create a .conf file which will provide values to the required parameters.
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[v3_req]
basicConstraints = critical, CA:FALSE
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster
DNS.5 = kubernetes.default.svc.cluster.local
IP.1 = ${API_SERVICE}
IP.2 = ${MASTER}
IP.3 = 127.0.0.1openssl genrsa -out kube-apiserver.key 2048
openssl req -new -key kube-apiserver.key \
-subj "/CN=kube-apiserver/O=Kubernetes" -out kube-apiserver.csr -config openssl.cnf
openssl x509 -req -in kube-apiserver.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial -out kube-apiserver.crt -extensions v3_req -extfile openssl.cnf -days 1000kube-apiserver Client Certificate and KeyETCD Server Certificate
We'll now generate a certificate and key for ETCD Server. The certificate must contain the IP addresses of all servers that are a part of the ETCD cluster.
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = ${MASTER}
IP.3 = 127.0.0.1ETCDThe commands below can be used to generate the certificate key pair.
openssl genrsa -out etcd-server.key 2048
openssl req -new -key etcd-server.key \
-subj "/CN=etcd-server/O=Kubernetes" -out etcd-server.csr -config openssl-etcd.cnf
openssl x509 -req -in etcd-server.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial -out etcd-server.crt -extensions v3_req -extfile openssl-etcd.cnf -days 1000ETCD Server Certificate and KeyKubelet Client Certificate
This certificate is used by the API server to authenticate with the kubelets when it requires information from them.
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[v3_req]
basicConstraints = critical, CA:FALSE
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuthkubeletUse the commands below to generate the kubelet client certificate and key pair.
openssl genrsa -out apiserver-kubelet-client.key 2048
openssl req -new -key apiserver-kubelet-client.key \
-subj "/CN=kube-apiserver-kubelet-client/O=system:masters" -out apiserver-kubelet-client.csr -config openssl-kubelet.cnf
openssl x509 -req -in apiserver-kubelet-client.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial -out apiserver-kubelet-client.crt -extensions v3_req -extfile openssl-kubelet.cnf -days 1000kubelet Certificate and KeyService Account Key Pair
Kubernetes Controller Manager uses the Service Account Key pair to generate and sign service account tokens.
Generate the certificate and key using the commands below.
openssl genrsa -out service-account.key 2048
openssl req -new -key service-account.key \
-subj "/CN=service-accounts/O=Kubernetes" -out service-account.csr
openssl x509 -req -in service-account.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial -out service-account.crt -days 1000service-account Key PairCopying the Certificates
Use the scp command below to transfer the generated CA from the master to the worker node. We'll manually move them later on to a different directory.
scp ca.crt ca.key kube-apiserver.key kube-apiserver.crt \
apiserver-kubelet-client.crt apiserver-kubelet-client.key \
service-account.key service-account.crt \
kube-proxy.crt kube-proxy.key
etcd-server.key etcd-server.crt \
kube-controller-manager.key kube-controller-manager.crt \
kube-scheduler.key kube-scheduler.crt worker@192.168.1.5:~/Conclusion
In this article, we learned to create the CA and the kubelet client certificates, which are important for the proper functioning of a cluster.
In this next part, we will learn to setup the recently generated certificates and their components in the kubernetes cluster nodes.
Thank you for reading. Please comment below if you have any queries or find any inaccuracies in the article!