KTHW - Set-up the CA and certificates

July 12, 2020 - Reading time: 5 minutes
  • Client certificates Used for authentication from any kube-* service to the Kube API LB.

  • Kube API Server Certificate Signed certificate for the API LB

  • Service Account Key Pair Certificate used to sign service account tokens.

Generate the CA

## Details of CA that I want to create 
cloud_user@pzolo6c:~/kthw$ cat ca-csr.json | jq .
  "CN": "Kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  "names": [
      "C": "US",
      "L": "Portland",
      "O": "Kubernetes",
      "OU": "CA",
      "ST": "Oregon"
## Certificate details 
cloud_user@pzolo6c:~/kthw$ cat ca-config.json | jq .
  "signing": {
    "default": {
      "expiry": "8760h"
    "profiles": {
      "kubernetes": {
        "usages": [
          "key encipherment",
          "server auth",
          "client auth"
        "expiry": "8760h"
## Generate a JSON with CSR, cert and key and then write to a file 
cloud_user@pzolo6c:~/kthw$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
2020/07/12 20:30:32 [INFO] generating a new CA key and certificate from CSR
2020/07/12 20:30:32 [INFO] generate received request
2020/07/12 20:30:32 [INFO] received CSR
2020/07/12 20:30:32 [INFO] generating key: rsa-2048
2020/07/12 20:30:32 [INFO] encoded CSR
2020/07/12 20:30:32 [INFO] signed certificate with serial number 113170212320509007336156775422336010737695630373
cloud_user@pzolo6c:~/kthw$ openssl x509 -in ca.pem -text -noout | grep -e Issuer -e Subject -e Before -e After -e Sign -e TRUE
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = Oregon, L = Portland, O = Kubernetes, OU = CA, CN = Kubernetes
            Not Before: Jul 12 20:26:00 2020 GMT
            Not After : Jul 11 20:26:00 2025 GMT
        Subject: C = US, ST = Oregon, L = Portland, O = Kubernetes, OU = CA, CN = Kubernetes
        Subject Public Key Info:
                Certificate Sign, CRL Sign
            X509v3 Subject Key Identifier:
    Signature Algorithm: sha256WithRSAEncryption

Generate Client certs

The certificates will be created using a csr.json file for the client, and specifying the newqly created ca.pem and ca-key.pem

# Admin client 
cloud_user@pzolo6c:~/kthw$ jq .CN admin-csr.json
cloud_user@pzolo6c:~/kthw$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
# Workers client 
cloud_user@pzolo6c:~/kthw$ WORKER0_IP=
cloud_user@pzolo6c:~/kthw$ WORKER1_IP=
cloud_user@pzolo6c:~/kthw$ jq .CN pzolo*.mylabserver.com-csr.json
cloud_user@pzolo6c:~/kthw$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -hostname=${WORKER0_IP},${WORKER0_HOST} -profile=kubernetes ${WORKER0_HOST}-csr.json | cfssljson -bare ${WORKER0_HOST}
cloud_user@pzolo6c:~/kthw$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -hostname=${WORKER1_IP},${WORKER1_HOST} -profile=kubernetes ${WORKER1_HOST}-csr.json | cfssljson -bare ${WORKER1_HOST}
# Controller Manager Client Certificate
cloud_user@pzolo6c:~/kthw$ jq .CN kube-controller-manager-csr.json
cloud_user@pzolo6c:~/kthw$ 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 Client Certificate 
cloud_user@pzolo6c:~/kthw$ jq .CN kube-proxy-csr.json
cloud_user@pzolo6c:~/kthw$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
# Kube Scheduler Client Certificate 
cloud_user@pzolo6c:~/kthw$ jq .CN kube-scheduler-csr.json
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
# Service account certificates 
cloud_user@pzolo6c:~/kthw$ jq .CN service-account-csr.json
cloud_user@pzolo6c:~/kthw$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes service-account-csr.json | cfssljson -bare service-account

Generate the API LB server cert

This certificate has a long list of hostname, because it's the entry point for all clients.

# is a kubernetes IP that some service clients may use. The rest are IP and hostnames for the controllers and the API LB 
cloud_user@pzolo6c:~/kthw$ CERT_HOSTNAME=,,localhost,kubernetes.default,,,,pzolo1c.mylabserver.com,pzolo2c.mylabserver.com,pzolo3c.mylabserver.com
# Kube Proxy API LB Server certificate 
cloud_user@pzolo6c:~/kthw$ jq .CN kubernetes-csr.json
cloud_user@pzolo6c:~/kthw$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -hostname=${CERT_HOSTNAME} -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes

Distribute the certs

cloud_user@pzolo6c:~/kthw$ scp ca.pem pzolo4c.mylabserver.com-key.pem pzolo4c.mylabserver.com.pem wrk01:~/
cloud_user@pzolo6c:~/kthw$ scp ca.pem pzolo5c.mylabserver.com-key.pem pzolo5c.mylabserver.com.pem wrk02:~/
cloud_user@pzolo6c:~/kthw$ scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem service-account-key.pem service-account.pem ctl01:~/
cloud_user@pzolo6c:~/kthw$ scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem service-account-key.pem service-account.pem ctl02:~/