Creating Self-Signed Certificates

Jonathan Peña
Creating Self-Signed Certificates

Your team is currently setting up a Kubernetes cluster that consists of two worker nodes and two controller nodes. Your team needs to create a certificate authority and generate several certificates using it so that all of Kubernetes' components may safely authenticate with each other. It is your responsibility to establish the certificate authority and generate the required certificates.

Cluster Details:

  • Controllers:
    • Hostname: controller0.mylabserver.com, IP: 172.34.0.0
    • Hostname: controller1.mylabserver.com, IP: 172.34.0.1
  • Workers:
    • Hostname: worker0.mylabserver.com, IP: 172.34.1.0
    • Hostname: worker1.mylabserver.com, IP: 172.34.1.1
  • Kubernetes API Load Balancer:
    • Hostname: kubernetes.mylabserver.com, IP: 172.34.2.0

In this lab we will be copying and pasting the pre-established commands but at the same time try to comprehend what is within these commands.

The curly braces will enable us to enter multiple commands to create the .JSON config files.

We must first create the Certificate Authority. A certificate authority (CA) is a trusted entity responsible for issuing and verifying digital certificates. In the context of Kubernetes, the CA is used to generate certificates that enable secure communication between different components of the cluster, such as the API server, worker nodes, and clients. By acting as a central authority for authentication, the CA ensures that all these components can trust and communicate securely with each other.

{

cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "kubernetes": {
        "usages": ["signing", "key encipherment", "server auth", "client auth"],
        "expiry": "8760h"
      }
    }
  }
}
EOF

cat > ca-csr.json << EOF
{
  "CN": "Kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "CA",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

}
  1. ca-config.json - This is the configuration file for the CA that will be generated upon execution of the command.
  2. ca-csr.json - This is a certificate signing request to generate/sign with the metadata listed that will be generated upon execution of the command.
  3. cfssl gencert - This will generate the certificate and will convert the ca-csr.json into an actual certificate that will be generated upon execution of the command.

In a Certificate Authority (CA), the private and public portions of the certificate serve different but complementary roles.

  • ca-key.pem (Private Key): This is the private part of the certificate authority, kept securely and never shared. It is used to sign and issue certificates for the various components of your Kubernetes cluster. The private key is crucial because it proves the authenticity of the certificates generated by the CA. If this key is compromised, the entire trust system is at risk.
  • ca.pem (Public Certificate): This is the public part of the CA certificate, freely distributed to all components within your Kubernetes cluster. It enables those components to confirm that a certificate was in fact issued by the reputable CA. The public certificate ensures that any communication or certificate signed by the CA can be authenticated as legitimate.

Together, these files establish a trust relationship: the private key creates the certificates, and the public key validates them.

With this task, we have completed provisioning the certificate authority.


We still need to generate the following certificates:

  • Kubernetes Client Certificates
  • Admin Client Certificate
  • Kubelet Client Certificates
    • Kubelet Client Certificate for worker0.mylabserver.com
    • Kubelet Client Certificate for worker1.mylabserver.com
  • Kube Controller Manager Certificate
  • Kube Proxy Certificate
  • Kube Scheduler Client Certificate
  • Kubernetes API Server Certificate
  • Kubernetes Service Account Key Pair

Next, we’ll generate the Kubernetes client certificates, including the kubelet client certificates for the two worker nodes. First up is the admin client certificate. Essentially, we’re creating another certificate, but this time, we’ll use the certificate authority (CA) we just set up.

In the command you'll run, you’ll notice we reference the ca.pem (public certificate) and ca-key.pem (private key) that we generated earlier. These are crucial because they authenticate and sign the new certificates we’re about to create.

{

cat > admin-csr.json << EOF
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:masters",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  admin-csr.json | cfssljson -bare admin

}

Next, we’ll generate the kubelet client certificates, which is similar to what we did for the admin client certificate. The difference here is that we’ll be creating certificates specifically for the worker nodes, worker0.mylabserver.com and worker1.mylabserver.com. This ensures that each worker node has its own unique certificate for secure communication within the cluster.

{
cat > worker0.mylabserver.com-csr.json << EOF
{
  "CN": "system:node:worker0.mylabserver.com",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:nodes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -hostname=172.34.1.0,worker0.mylabserver.com \
  -profile=kubernetes \
  worker0.mylabserver.com-csr.json | cfssljson -bare worker0.mylabserver.com

cat > worker1.mylabserver.com-csr.json << EOF
{
  "CN": "system:node:worker1.mylabserver.com",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:nodes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -hostname=172.34.1.1,worker1.mylabserver.com \
  -profile=kubernetes \
  worker1.mylabserver.com-csr.json | cfssljson -bare worker1.mylabserver.com

}

Kube Controller Manager Certificate

Next, we’ll generate a certificate for the Kube Controller Manager. This component is critical in Kubernetes as it manages key control loops, such as ensuring the desired state of the cluster is maintained, handling node failures, and managing tasks like scaling.

The certificate is necessary to securely authenticate the Kube Controller Manager when it communicates with the Kubernetes API server. Without this certificate, the controller manager wouldn't be able to interact securely with other components of the cluster, potentially compromising the security and stability of the system.

{

cat > kube-controller-manager-csr.json << EOF
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:kube-controller-manager",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

}

Kube Proxy Certificate

Next, we’ll generate a certificate for Kube Proxy. Kube Proxy is responsible for managing network rules and ensuring traffic is properly routed to the correct pods and services within the Kubernetes cluster.

The certificate is essential to authenticate the Kube Proxy’s communication with the API server. This ensures that Kube Proxy can securely access necessary resources and configure the network for the cluster without compromising security.

{

cat > kube-proxy-csr.json << EOF
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:node-proxier",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-proxy-csr.json | cfssljson -bare kube-proxy

}

Next, we’ll generate a certificate for the Kube Scheduler Client. The Kube Scheduler is responsible for assigning newly created pods to available nodes in the cluster, based on resource availability and policy constraints.

This certificate is crucial for the Kube Scheduler to securely authenticate its interactions with the Kubernetes API server. By having its own unique certificate, the scheduler can securely communicate and perform its tasks, ensuring the cluster's stability and performance.

{

cat > kube-scheduler-csr.json << EOF
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "system:kube-scheduler",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-scheduler-csr.json | cfssljson -bare kube-scheduler

}

Kubernetes API Server Certificate

Next, we’ll generate a certificate for the Kubernetes API server. The API server is the central component that handles communication between all other Kubernetes components and external clients, acting as the gateway to the cluster.

This certificate is critical because it ensures that all communication with the API server is secure and trusted. The certificate will authenticate the API server's interactions with the controller nodes, worker nodes, and other clients, protecting the integrity and confidentiality of data exchanged in the cluster.

{

cat > kubernetes-csr.json << EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "Kubernetes The Hard Way",
      "ST": "Oregon"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -hostname=10.32.0.1,172.34.0.0,controller0.mylabserver.com,172.34.0.1,controller1.mylabserver.com,172.34.2.0,kubernetes.mylabserver.com,127.0.0.1,localhost,kubernetes.default \
  -profile=kubernetes \
  kubernetes-csr.json | cfssljson -bare kubernetes

}

This is a server certificate that the Kubernetes API server uses to enable secure access to the API over TLS. It includes the internal IP addresses and hostnames of the components that will connect to the API, such as the controllers and their respective IP addresses, as well as the load balancer.


Kubernetes Service Account Key Pair

Next, we need to generate a Kubernetes service account key pair. This certificate is used to sign service account tokens, which allow pods to authenticate with the API server securely.

{

cat > service-account-csr.json << EOF
{
"CN": "service-accounts",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "Portland",
"O": "Kubernetes",
"OU": "Kubernetes The Hard Way",
"ST": "Oregon"
}
]
}
EOF

cfssl gencert
-ca=ca.pem
-ca-key=ca-key.pem
-config=ca-config.json
-profile=kubernetes
service-account-csr.json | cfssljson -bare service-account

}

Conclusion

Now that we have generated all the necessary certificates, we are well-prepared for the next steps in setting up our Kubernetes cluster. These certificates ensure secure communication between the various components, allowing them to authenticate and trust each other.

With these certificates in place, we can proceed to install and configure the Kubernetes components effectively. This will include setting up the API server, controllers, worker nodes, and other essential services. Each component will utilize its respective certificates to establish secure connections, ensuring that our cluster operates securely and efficiently.

We’ll cover the installation process in detail in another post, where we’ll guide you through deploying the Kubernetes components, configuring networking, and verifying that everything is working as intended. This foundational work with certificates is crucial, as it sets the stage for a secure and reliable Kubernetes environment.



Great! Next, complete checkout for full access to Cybersecurity
Welcome back! You've successfully signed in
You've successfully subscribed to Cybersecurity
Success! Your account is fully activated, you now have access to all content
Success! Your billing info has been updated
Your billing was not updated