Control plane certificates

Let’s start creating the certificate for our kube master components.

As with the previous steps, create a directory that will contain the master node components’ certificates and generate the certificate files for each of them in the following way:

johndoe@management-vm$ mkdir ~/certs/control-plane/

johndoe@management-vm$ cd ~/certs/control-plane/

For kube-controller-manager, use the following command:

johndoe@management-vm$ cat << EOF > kube-controller-manager-csr.json
{
"CN": "system:kube-controller-manager",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "New York",
"O": "system:kube-controller-manager",
"OU": "Kubernetes",
"ST": "NY"
}
]
}
EOF

johndoe@management-vm$ 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

For the kube-proxy, use the following command:

johndoe@management-vm$ cat << EOF > kube-proxy-csr.json
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "New York",
"O": "system:node-proxier",
"OU": "Kubernetes",
"ST": "NY"
}
]
}
EOF

johndoe@management-vm$ cfssl gencert \
-ca=../ca.pem \
-ca-key=../ca-key.pem \
-config=../ca-config.json \
-profile=kubernetes \
kube-proxy-csr.json | cfssljson -bare kube-proxy

For the kube-scheduler, use the following command:

johndoe@management-vm$ cat << EOF > kube-scheduler-csr.json
{
"CN": "system:kube-scheduler",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "New York",
"O": "system:kube-scheduler",
"OU": "Kubernetes",
"ST": "NY"
}
]
}
EOF

johndoe@management-vm$ cfssl gencert \
-ca=../ca.pem \
-ca-key=../ca-key.pem \
-config=../ca-config.json \
-profile=kubernetes \
kube-scheduler-csr.json | cfssljson -bare kube-scheduler

Now we need to create the API server. You will notice that it is similar to the process we used with the kubelets, as this certificate requires the hostname parameter. But with the kube-api cert, we will not only provide the hostname and IP address of the individual nodes, we will also provide instead all of the possible hostnames and IPs that our API server will be using: the load-balancer public IP, the IP of each master node, and a special FQDN, kubernetes.default. All of them will be in a single cert.

Let’s create a separate directory first using the following command:

johndoe@management-vm$ mkdir ~/certs/api/

johndoe@management-vm$ cd ~/certs/api/

Now, let's create a variable for the hostname using the following command:

johndoe@management-vm$API_HOSTNAME=10.20.0.1,192.168.0.11,kube-controller-1,192.168.0.12,kube-controller-2,<PUBLIC_IP>,127.0.0.1,localhost,kubernetes.default
Note that you should replace <PUBLIC_IP> with your public IP address.

Now, let's create the certificate using the following command:

johndoe@management-vm$ cat << EOF > kubernetes-csr.json 
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "New York",
"O": "Kubernetes",
"OU": "Kubernetes",
"ST": "NY"
}
]
}
EOF

johndoe@management-vm$ cfssl gencert \
-ca=../ca.pem \
-ca-key=../ca-key.pem \
-config=../ca-config.json \
-hostname=${API_HOSTNAME} \
-profile=kubernetes \
kubernetes-csr.json | cfssljson -bare kubernetes

At this point, only one certificate is missing—the service account certificate. This certificate is not for any normal user or Kubernetes component specifically. Service account certificates are used by the API server to sign tokens that are used for service accounts.

We will be storing these key pairs in the same directory as the API certs, so we will just create the json and run the cfssl gencert command, as shown in the following command:

johndoe@management-vm$ cat << EOF > service-account-csr.json 
{
"CN": "service-accounts",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "US",
"L": "New York",
"O": "Kubernetes",
"OU": "Kubernetes",
"ST": "NY"
}
]
}
EOF

johndoe@management-vm$ cfssl gencert \
-ca=../ca.pem \
-ca-key=../ca-key.pem \
-config=../ca-config.json \
-profile=kubernetes \
service-account-csr.json | cfssljson -bare service-account