Beginning here with a disclaimer: Much of what you will read here is usually handled by your service provider.
As mentioned in a previous post you will probably not be asked to setup your K8s cluster from scratch. A service provider will provide you with a cluster.
The access permissions will also usually be handled by the service provider using IAM rules. In the end, though, the IAM rules must result in the creation of Roles and RoleBindings attached to the context of an IAM role.
Lets start with a few definitions.
Authentication
Any system which provides Role Based Access Control, must do Authentication as the first step of a 2 step process.
Authentication is the process of identifying a User or in other words, how do I know that you are You ?
Authorization
Now that I know who you are I need to allow you to do only the things that you are allowed to do. This is Authorization.
Account Types
There are 2 account types supported by Kubernetes.
- User Account: This type of account is for Humans. Probably used in conjunction with kubectl. Usually made such that all namespaces are available but additional config is required to give access to particular resources.
- Service Account: Meant for programmatic access to kube APIs. The authentication method is much simpler, usually Token based. They are usually restricted to namespaces. Every namespace, by default, has a default service account.
While the User Account is usually created by the Kubernetes provider, the service account is created by the Kubernetes system itself.
Alice’s Enlightenment
Going back to our previous post, you may remember that Alice and Bob hated each other. They were constantly bickering about the problems caused by the other’s team. You, as their boss, want this to stop, so you created namespaces, but engineers were still able to look across namespaces.
You have a chat with Alice and she realizes that she could earn valuable brownie points by just restricting her team from accessing Bob’s namespace. Lets see how she went about it.
Step 1 User Authentication
User Accounts are authenticated using certificates. Your Kubectl config (usually in <home dir>/.kube/config
stores the details of your certificates and private keys to use for authentication. Public-Key Private Key cryptography is a rabbit-hole you need to go down on your own. (Maybe in another post)
Here is my config file
apiVersion: v1
clusters:
- cluster:
certificate-authority: /home/param/.minikube/ca.crt
server: https://192.168.99.100:8443
name: minikube
contexts:
- context:
cluster: minikube
user: employee
name: employee-context
- context:
cluster: minikube
user: minikube
name: minikube
current-context: employee-context
kind: Config
preferences: {}
users:
- name: employee
user:
client-certificate: /home/param/.certs/employee.crt
client-key: /home/param/.certs/employee.key
- name: minikube
user:
client-certificate: /home/param/.minikube/client.crt
client-key: /home/param/.minikube/client.key
Note a couple of things
certificate-authority: this is the credential of the server which will validate the certificate sent by the kubectl client.
server: is the url of the API server
contexts: This is the kubectl contexts available for users
users: The user credentials to use for a user
In short, we need a client-certificate and client-key authorized (signed) by the certificate-authority for each user. Each user is connected to a context which is what we need to specify to kubectl.
Creating Client-Certificate
Create a private key for the user
$ openssl genrsa -out employee.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
...............+++++
.............................+++++
e is 65537 (0x010001)
Create a Certificate Signing Request
Usually you will send your public key and a few other details to a Certificate Authority to receive your signed certificate. The standard format for that is CSR (Certificate Signing Request).
To generate a CSR from a private key we do
sudo openssl req -new -key employee.key -out employee.csr -subj "/CN=employee/O=alice"
Create Signed Certificate
As the Certificate Authority for Minikube is on our laptop and we have access to its credentials in ~/.minikube/ca.crt
we can create a self signed certificate using the following command
openssl x509 -req -in employee.csr -CA ~/.minikube/ca.crt -CAkey ~/.minikube/ca.key -CAcreateserial -out employee.crt -days 500
Setting up Kubectl to use this certificate
At the end of this we should have employee.crt and employee.key. Now we can tell kubectl to use these files as credentials. Lets setup the context employee context for user employee using the following command
$ kubectl config set-credentials employee --client-certificate=/home/employee/.certs/employee.crt --client-key=/home/employee/.certs/employee.key
User "employee" set.
Now create the context for this user.
kubectl config set-context employee-context --cluster=minikube --user=employee
Now you should see the new context available to you using the kubectl command…
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
employee-context minikube employee
* minikube minikube minikube
Lets switch to the new context
kubectl config use-context employee-context
(Or use kubectx command)
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* employee-context minikube employee
minikube minikube minikube
(note the *
now points to employee-context
).
Authentication success but …
Lets get pod information using this context.
$ kubectl get pods
Error from server (Forbidden): pods is forbidden: User "employee" cannot list resource "pods" in API group "" in the namespace "default"
Oh NO! this user is forbidden from accessing anything! That’s because we have only authenticated the user so far. Kubernetes knows the user now, but doesn’t know what they are allowed to access. So they are not allowed to access anything. Next step Authorization. We will read about that in the next post.
Learnings
Authentication is the system finding out who your are.
Authorization is the system allowing you to do what you are allowed to do.
Authentication ultimately needs creation of credentials for users.
In a Managed Kubernetes cluster the Authentication credentials are created by the service provider and injected into your kubectl config in
~/.kube/config
file.Service providers use IAM permissions to configure Authorization in the Cluster.
There is RabbitHole waiting for you called Public Key/Private Key cryptography.
Authentication is useless without Authorization
Conclusion
This post is about Authentication, in the next post we talk about Authorization. Thankfully Authorization occurs within the ambit of Kubernetes. Its as easy as creating Resources.