Saturday, July 7, 2018

Creating an admin account on Kubernetes

I spent a bunch of time Googling how to do this so I figured it could help someone else if posted the steps to add an admin account on a Kubernetes cluster managed with kops.

k8s has service accounts but that's not what you want to create an admin account — equivalent to having root privileges on the cluster.  Instead you simply need to create a certificate/key pair for the user and sign it with the master's CA (certificate authority).

In this example we'll create an account for user foobar.
  1. Create a private key:
    openssl genrsa -out foobar.key 2048
    For extra security you can also opt for 4096 bits for the key but for some reason kops defaults to 2048 right now.
  2. Create a CSR (Certificate Signing Request)
    openssl req -new -key foobar.key -out foobar.csr -subj '/CN=foobar/O=system:masters'
    The CN (Common Name) contains the user name and the O (Organization Name) must be system:masters to be a super-user.
  3. Fetch the master's private key from S3, from the bucket kops was configured to use:
    aws s3 sync $KOPS_STATE_STORE/$NAME/pki pki
    Here the variables $KOPS_STATE_STORE and $NAME are the ones referred to in the kops documentation. For example:
    aws s3 sync s3://prefix-example-com-state-store/ pki
    All the PKI files will be downloaded from S3 into the local pki directory.
  4. Issue the certificate using the master's CA: openssl x509 -req -in foobar.csr -CA pki/issued/ca/*.crt -CAkey pki/private/ca/*.key -CAcreateserial -out foobar.crt -days 3650
At this point you could give the private key (foobar.key) and the certificate (foobar.crt) to the user, but if you want to be a bit nicer and generate a self-contained kubectl config for them, here's how:
kubectl --kubeconfig=kcfg config \
  set-credentials $NAME --client-key=foobar.key --client-certificate=foobar.crt --embed-certs=true
kubectl --kubeconfig=kcfg config \
  set-cluster $NAME --embed-certs=true --server= --certificate-authority pki/issued/ca/*.crt
kubectl --kubeconfig=kcfg config \
  set-context $NAME --cluster=$NAME --user=$NAME
kubectl --kubeconfig=kcfg config \
  use-context $NAME
You can then hand over the kcfg file to the user and they could use it directly as their ~/.kube/config if they don't already have one.

Don't forget to rm -rf pki to delete the files you downloaded from S3.