Skip to content

Instantly share code, notes, and snippets.

@ziozzang
Forked from detiber/README.md
Created October 24, 2019 08:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ziozzang/d31718b1c0b296bbb9b3ea4900047924 to your computer and use it in GitHub Desktop.
Save ziozzang/d31718b1c0b296bbb9b3ea4900047924 to your computer and use it in GitHub Desktop.
Using CFSSL as an external CA for kubeadm

CFSSL as an external CA for non-ha kubeadm intialized clusters

Using cfssl to Create an External CA Infrastructure

Install cfssl

# This requires an existing Go environment with GOPATH set
go get -u github.com/cloudflare/cfssl/cmd/...

Create the root CA

mkdir root-ca
cd root-ca
cat << EOF > root-ca-config.json
{
    "signing": {
        "profiles": {
            "intermediate": {
                "usages": [
                    "signature",
                    "digital-signature",
                    "cert sign",
                    "crl sign"
                ],
                "expiry": "26280h",
                "ca_constraint": {
                    "is_ca": true,
                    "max_path_len": 0,
                    "max_path_len_zero": true
                }
            }
        }
    }
}
EOF
cat << EOF > root-ca-csr.json
{
    "CN": "my-root-ca",
    "key": {
        "algo": "rsa",
        "size": 4096
    },
    "ca": {
        "expiry": "87600h"
    }
}
EOF
cfssl genkey -initca root-ca-csr.json | cfssljson -bare ca
cd ..

The root CA files should be kept offline and only used for creating intermediate CAs.

Create the Kubernetes Intermediate CA

mkdir kubernetes-ca
cd kubernetes-ca
cat << EOF > kubernetes-ca-csr.json
{
    "CN": "kubernetes-ca",
    "key": {
        "algo": "rsa",
        "size": 4096
    },
    "ca": {
        "expiry": "26280h"
    }
}
EOF
cfssl genkey -initca kubernetes-ca-csr.json | cfssljson -bare kubernetes-ca
cfssl sign -ca ../root-ca/ca.pem -ca-key ../root-ca/ca-key.pem -config ../root-ca/root-ca-config.json -profile intermediate kubernetes-ca.csr | cfssljson -bare kubernetes-ca
cfssl print-defaults config kubernetes-ca-config.json
cd ..

Create the Kubernetes Front Proxy Intermediate CA

mkdir kubernetes-front-proxy-ca
cd kubernetes-front-proxy-ca
cat << EOF > kubernetes-front-proxy-ca-csr.json
{
    "CN": "kubernetes-front-proxy-ca",
    "key": {
        "algo": "rsa",
        "size": 4096
    },
    "ca": {
        "expiry": "26280h"
    }
}
EOF
cfssl genkey -initca kubernetes-front-proxy-ca-csr.json | cfssljson -bare kubernetes-front-proxy-ca
cfssl sign -ca ../root-ca/ca.pem -ca-key ../root-ca/ca-key.pem -config ../root-ca/root-ca-config.json -profile intermediate kubernetes-front-proxy-ca.csr | cfssljson -bare kubernetes-front-proxy-ca
cfssl print-defaults config kubernetes-front-proxy-ca-config.json
cd ..

Create the etcd Intermediate CA

mkdir etcd-ca
cd etcd-ca
cat << EOF > etcd-ca-config.json
{
    "signing": {
        "profiles": {
            "server": {
                "expiry": "8700h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "8700h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            },
            "peer": {
                "expiry": "8700h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}
EOF
cat << EOF > etcd-ca-csr.json
{
    "CN": "etcd-ca",
    "key": {
        "algo": "rsa",
        "size": 4096
    },
    "ca": {
        "expiry": "26280h"
    }
}
EOF
cfssl genkey -initca etcd-ca-csr.json | cfssljson -bare etcd-ca
cfssl sign -ca ../root-ca/ca.pem -ca-key ../root-ca/ca-key.pem -config ../root-ca/root-ca-config.json -profile intermediate etcd-ca.csr | cfssljson -bare etcd-ca
cd ..

To completely delegate the CAs to kubeadm (and the resulting cluster):

  • copy etcd-ca.pem to /etc/kubernetes/pki/etcd/ca.crt
  • copy etcd-ca-key.pem to /etc/kubernetes/pki/etcd/ca.key
  • copy kubernetes-ca.pem to /etc/kubernetes/pki/ca.crt
  • copy kubernetes-ca-key.pem to /etc/kubernetes/pki/ca.key
  • copy kubernetes-front-proxy-ca.pem to /etc/kubernetes/pki/front-proxy-ca.crt
  • copy kubernetes-front-proxy-ca-key.pem to /etc/kubernetes/pki/front-proxy-ca.key

To manually generate the certificates:

  • copy kubernetes-ca/kubernetes-ca.pem to /etc/kubernetes/pki/ca.crt

  • copy kubernetes-front-proxy-ca/kubernetes-front-proxy-ca.pem to /etc/kubernetes/pki/front-proxy-ca.crt

  • copy etcd-ca/etcd-ca.pem to /etc/kubernetes/pki/etcd/ca.crt

  • copy etcd-server.pem to /etc/kubernetes/pki/etcd/server.crt

  • copy etcd-server-key.pem to /etc/kubernetes/pki/etcd/server.key

  • copy etcd-peer.pem to /etc/kubernetes/pki/etcd/peer.crt

  • copy etcd-peer-key.pem to /etc/kubernetes/pki/etcd/peer.key

  • copy etcd-healthcheck-client.pem to /etc/kubernetes/pki/etcd/healthcheck-client.crt

  • copy etcd-healthcheck-client-key.pem to /etc/kubernetes/pki/etcd/healthcheck-client.key

  • copy apiserver.pem to /etc/kubernetes/pki/apiserver.crt

  • copy apiserver-key.pem to /etc/kubernetes/pki/apiserver.key

  • copy apiserver-kubelet-client.pem to /etc/kubernetes/pki/apiserver-kubelet-client.crt

  • copy apiserver-kubelet-client-key.pem to /etc/kubernetes/pki/apiserver-kubelet-client.key

  • copy apiserver-etcd-client.pem to /etc/kubernetes/pki/apiserver-etcd-client.crt

  • copy apiserver-etcd-client-key.pem to /etc/kubernetes/pki/apiserver-etcd-client.key

  • copy sa.pub to /etc/kubernetes/pki/sa.pub

  • copy sa.key to /etc/kubernetes/pki/sa.key

  • copy admin.conf to /etc/kubernetes/admin.conf

  • copy kubelet.conf to /etc/kubernetes/kubelet.conf

  • copy controller-manager.conf to /etc/kubernetes/controller-manager.conf

  • copy scheduler.conf to /etc/kubernetes/scheduler.conf

Generate the etcd server keypair

cat << EOF > etcd-server-csr.json
{
  "CN": "kube-etcd",
  "hosts": [
    "ubuntu",
    "192.168.121.230",
    "localhost",
    "127.0.0.1"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
EOF
cfssl gencert -ca=etcd-ca/etcd-ca.pem -ca-key=etcd-ca/etcd-ca-key.pem --config=etcd-ca/etcd-ca-config.json -profile=server etcd-server-csr.json | cfssljson -bare etcd-server

Generate the etcd peer keypair

cat << EOF > etcd-peer-csr.json
{
  "CN": "kube-etcd-peer",
  "hosts": [
    "ubuntu",
    "192.168.121.230",
    "localhost",
    "127.0.0.1"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
EOF
cfssl gencert -ca=etcd-ca/etcd-ca.pem -ca-key=etcd-ca/etcd-ca-key.pem --config=etcd-ca/etcd-ca-config.json -profile=peer etcd-peer-csr.json | cfssljson -bare etcd-peer

Generate the etcd healthcheck client keypair

cat << EOF > etcd-healthcheck-client-csr.json
{
  "CN": "kube-etcd-healthcheck-client",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
      {
          "O": "system:masters"
      }
  ]
}
EOF
cfssl gencert -ca=etcd-ca/etcd-ca.pem -ca-key=etcd-ca/etcd-ca-key.pem --config=etcd-ca/etcd-ca-config.json -profile=client etcd-healthcheck-client-csr.json | cfssljson -bare etcd-healthcheck-client

Generate the apiserver keypair

cat << EOF > apiserver-csr.json
{
  "CN": "kube-apiserver",
  "hosts": [
    "ubuntu",
    "192.168.121.230",
    "10.96.0.1",
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster",
    "kubernetes.default.svc.cluster.local"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
EOF
cfssl gencert -ca=kubernetes-ca/kubernetes-ca.pem -ca-key=kubernetes-ca/kubernetes-ca-key.pem --config=kubernetes-ca/kubernetes-ca-config.json -profile=www apiserver-csr.json | cfssljson -bare apiserver

Generate the apiserver-kubelet-client keypair

cat << EOF > apiserver-kubelet-client-csr.json
{
  "CN": "kube-apiserver-kubelet-client",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "O": "system:masters"
    }
  ]
}
EOF
cfssl gencert -ca=kubernetes-ca/kubernetes-ca.pem -ca-key=kubernetes-ca/kubernetes-ca-key.pem --config=kubernetes-ca/kubernetes-ca-config.json -profile=client apiserver-kubelet-client-csr.json | cfssljson -bare apiserver-kubelet-client

Create the SA keypair

openssl genrsa -out sa.key 2048
openssl rsa -in sa.key -pubout -out sa.pub

Create the front-proxy client keypair

cat << EOF > front-proxy-client-csr.json
{
  "CN": "front-proxy-client",
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
EOF
cfssl gencert -ca=kubernetes-front-proxy-ca/kubernetes-front-proxy-ca.pem -ca-key=kubernetes-front-proxy-ca/kubernetes-front-proxy-ca-key.pem --config=kubernetes-front-proxy-ca/kubernetes-front-proxy-ca-config.json -profile=client front-proxy-client-csr.json | cfssljson -bare front-proxy-client

Create the apiserver etcd client keypair

cat << EOF > apiserver-etcd-client-csr.json
{
  "CN": "kube-apiserver-etcd-client",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
      {
          "O": "system:masters"
      }
  ]
}
EOF
cfssl gencert -ca=etcd-ca/etcd-ca.pem -ca-key=etcd-ca/etcd-ca-key.pem --config=etcd-ca/etcd-ca-config.json -profile=client apiserver-etcd-client-csr.json | cfssljson -bare apiserver-etcd-client

Create the admin kubeconfig

cat << EOF > admin-csr.json
{
  "CN": "kubernetes-admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "O": "system:masters"
    }
  ]
}
EOF
cfssl gencert -ca=kubernetes-ca/kubernetes-ca.pem -ca-key=kubernetes-ca/kubernetes-ca-key.pem --config=kubernetes-ca/kubernetes-ca-config.json -profile=client admin-csr.json | cfssljson -bare admin
KUBECONFIG=admin.conf kubectl config set-cluster default-cluster --server=https://192.168.121.230:6443 --certificate-authority kubernetes-ca/kubernetes-ca.pem --embed-certs
KUBECONFIG=admin.conf kubectl config set-credentials default-admin --client-key admin-key.pem --client-certificate admin.pem --embed-certs
KUBECONFIG=admin.conf kubectl config set-context default-system --cluster default-cluster --user default-admin
KUBECONFIG=admin.conf kubectl config use-context default-system

Create the kubelet kubeconfig

cat << EOF > kubelet-csr.json
{
  "CN": "system:node:ubuntu",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "O": "system:nodes"
    }
  ]
}
EOF
cfssl gencert -ca=kubernetes-ca/kubernetes-ca.pem -ca-key=kubernetes-ca/kubernetes-ca-key.pem --config=kubernetes-ca/kubernetes-ca-config.json -profile=client kubelet-csr.json | cfssljson -bare kubelet
KUBECONFIG=kubelet.conf kubectl config set-cluster default-cluster --server=https://192.168.121.230:6443 --certificate-authority kubernetes-ca/kubernetes-ca.pem --embed-certs
KUBECONFIG=kubelet.conf kubectl config set-credentials system:node:ubuntu --client-key kubelet-key.pem --client-certificate kubelet.pem --embed-certs
KUBECONFIG=kubelet.conf kubectl config set-context default-system --cluster default-cluster --user system:node:ubuntu
KUBECONFIG=kubelet.conf kubectl config use-context default-system

Create the controller-manager kubeconfig

cat << EOF > controller-manager-csr.json
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
EOF
cfssl gencert -ca=kubernetes-ca/kubernetes-ca.pem -ca-key=kubernetes-ca/kubernetes-ca-key.pem --config=kubernetes-ca/kubernetes-ca-config.json -profile=client controller-manager-csr.json | cfssljson -bare controller-manager
KUBECONFIG=controller-manager.conf kubectl config set-cluster default-cluster --server=https://192.168.121.230:6443 --certificate-authority kubernetes-ca/kubernetes-ca.pem --embed-certs
KUBECONFIG=controller-manager.conf kubectl config set-credentials default-controller-manager --client-key controller-manager-key.pem --client-certificate controller-manager.pem --embed-certs
KUBECONFIG=controller-manager.conf kubectl config set-context default-system --cluster default-cluster --user default-controller-manager
KUBECONFIG=controller-manager.conf kubectl config use-context default-system

Create the scheduler kubeconfig

cat << EOF > scheduler-csr.json
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  }
}
EOF
cfssl gencert -ca=kubernetes-ca/kubernetes-ca.pem -ca-key=kubernetes-ca/kubernetes-ca-key.pem --config=kubernetes-ca/kubernetes-ca-config.json -profile=client scheduler-csr.json | cfssljson -bare scheduler
KUBECONFIG=scheduler.conf kubectl config set-cluster default-cluster --server=https://192.168.121.230:6443 --certificate-authority kubernetes-ca/kubernetes-ca.pem --embed-certs
KUBECONFIG=scheduler.conf kubectl config set-credentials default-scheduler --client-key scheduler-key.pem --client-certificate scheduler.pem --embed-certs
KUBECONFIG=scheduler.conf kubectl config set-context default-system --cluster default-cluster --user default-scheduler
KUBECONFIG=scheduler.conf kubectl config use-context default-system
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment