5.5 KiB
Generating user certificates
-
The most popular ways to authenticate users with Kubernetes are:
-
TLS certificates
-
JSON Web Tokens (OIDC or ServiceAccount tokens)
-
-
We're going to see how to use TLS certificates
-
We will generate a certificate for an user and give them some permissions
-
Then we will use that certificate to access the cluster
Heads up!
-
The demos in this section require that we have access to our cluster's CA
-
On a managed cluster: the CA is very rarely exposed by the provider
-
On a self-hosted cluster: the CA should be available somewhere
(it may or may not be easy to find, though!)
-
We may or may not be able to use the CSR API instead
Locate the CA key and cert
-
On a cluster deployed with
kubeadm:the files will be in
/etc/kubernetes/pki(on any control plane node) -
On a cluster deployed with something like k3s or k0s:
Check the docs to know where the CA files are
(and for extra credit, submit a PR to update this slide!)
-
On a cluster deployed manually (like "dessine-moi un cluster"):
the files will be wherever you did put them
Let's set environment variables
-
To normalize the commands in the next slides:
CA_KEY=/.../ca.key CA_CRT=/.../ca.crt
How it works
-
The API server is configured to accept all certificates signed by a given CA
-
The certificate contains:
-
the user name (in the
CNfield) -
the groups the user belongs to (as multiple
Ofields)
-
.lab[
- On clusters deployed with
kubeadm, this will show the location of the CA cert:sudo grep client-ca /etc/kubernetes/manifests/kube-apiserver.yaml
]
This should output a flag like the following one:
--client-ca-file=/etc/kubernetes/pki/ca.crt
Generating a key and CSR for our user
-
These operations could be done on a separate machine
-
We only need to transfer the CSR (Certificate Signing Request) to the CA
(we never need to expose the private key)
.lab[
-
Generate a private key:
openssl genrsa 4096 > user.key -
Generate a CSR:
openssl req -new -key user.key -subj /CN=jerome/O=devs/O=ops > user.csr
]
Generating a signed certificate
-
This has to be done on the machine holding the CA private key
(copy the
user.csrfile if needed)
.lab[
-
Verify the CSR paramters:
openssl req -in user.csr -text | head -
Generate the certificate:
sudo openssl x509 -req \ -CA $CA_CRT -CAkey $CA_KEY \ -in user.csr -days 1 -set_serial 1234 > user.crt
]
If you are using two separate machines, transfer user.crt to the other machine.
Adding the key and certificate to kubeconfig
-
We have to edit our
.kube/configfile -
This can be done relatively easily with
kubectl config
.lab[
- Create a new
userentry in our.kube/configfile:kubectl config set-credentials jerome \ --client-key=user.key --client-certificate=user.crt
]
The configuration file now points to our local files.
We could also embed the key and certs with the --embed-certs option.
(So that the kubeconfig file can be used without user.key and user.crt.)
Using the new identity
-
At the moment, we probably use the admin certificate generated by
kubeadm(with
CN=kubernetes-adminandO=system:masters) -
Let's edit our context to use our new certificate instead!
.lab[
-
Edit the context:
kubectl config set-context --current --user=jerome -
Try any command:
kubectl get pods
]
Does it work, or do we get a permission error?
On a normal cluster
-
We should get a message like the following one:
Error from server (Forbidden): pods is forbidden: User "jerome" cannot list resource "pods" in API group "" in the namespace "default" -
This means:
your user key and cert are valid (
User "jerome")......but you don't have permission to get pods yet
-
We now need to grant permissions (e.g. with Roles and Rolebindings)
On a cluster deployed manually
-
If we haven't enabled RBAC, then it will work
(because without RBAC, any valid certificate gives full access to the API)
-
We could (should?) enable RBAC!
-
But then we'll need to generate keys and certs for all API clients
(including, but not limited to, control plane components and kubelets)
Granting permissions
-
If RBAC is enabled, we can give some permissions to our new user
-
The following example assumes a
kubeadmcluster -
Let's add some read-only permissions to the
devsgroup (for instance)
.lab[
-
Switch back to our admin identity:
kubectl config set-context --current --user=kubernetes-admin -
Grant permissions:
kubectl create clusterrolebinding devs-can-view \ --clusterrole=view --group=devs
]
Testing the new permissions
-
As soon as we create the ClusterRoleBinding, all users in the
devsgroup get access -
Let's verify that we can e.g. list pods!
.lab[
-
Switch to our user identity again:
kubectl config set-context --current --user=jerome -
Test the permissions:
kubectl get pods
]
kubeadm kubeconfig user
-
On
kubeadmclusters, there is a command to automate key and certificate generation -
kubeadm kubeconfig userwill issue a key, certificate, and output the kubeconfig file -
It will access CA key and cert in
/etc/kubernetes/pki/directly
???
:EN:- Authentication with user certificates :FR:- Identification par certificat TLS