This is the second part of the multi-part series on Building a Kubernetes Cluster from Scratch. You can find the link to part 1 here.

In this part of this series, we will learn to create and provide TLS certificates for all the components that make up the 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 generate the Certificate Authority (CA) for the master node. The master node is the primary server, and the worker nodes will verify the provided certificate with the master node.

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) }')
Setting up Environment Variables

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.1
Echoed Values of Set Environment Variables

Generating a CA Certificate

Now, we generate a 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 1000
Generating the CA Certificate and Key
✍️
The CA.key file is used to sign the certificates. Avoid sharing this key.

Output:

ca.crt
ca.key

Generating 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 1000
Commands for Generating Admin Client Certificate and Key
Output:
admin.key
admin.crt
ℹ️
Output for the certificate generation commands below has been omitted to avoid redundancy. This is because the generated files are of the same type (certificate and key pair) and only differ in name.
💡
The admin user has been placed in the system: Masters Group, which can now perform administrative actions on the cluster.

Kube 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 1000
Commands Generating kube-controller-manager Client Certificate and Key

Kube 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 1000
Commands for Generating kube-proxy Client Certificate and Key

The 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 100
Commands for Generating kube-scheduler Client Certificate and Key

Kubernetes API Server Certificate

As openssl cannot take alternate names as command line parameters, we'll create a .conf file to provide params.

[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.1
Certificate Configuration for Kube API Server
openssl 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 1000
Commands for Generating kube-apiserver Client Certificate and Key

ETCD 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.1
Certificate Configuration for ETCD

We'll use the commands below 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 1000
Commands for Generating ETCD Server Certificate and Key

Kubelet 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 = clientAuth
Certificate Configuration of kubelet

Use 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 1000
Commands for generating kubelet Certificate and Key

Service 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 1000
Commands for Generating service-account Key Pair

Copying 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:~/
Copying Certificate Files from Master Node to Worker Node

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!