Microk8s and K3S have RBAC enabled and configured by default. Microk8s configuration has AlwaysAllow policy, so even if you create and assign RBAC role for new user, microk8s will still allow full access. In K3S it is different and RBAC role will be applied.

Create User Key

openssl genrsa -out <user-name>.key 2048

Creates user’s private key.

Create Certificate Signing Request

openssl req -new -key <user-name>.key -out <user-name>.csr -subj "/CN=<user-name>/O=<user-group>"

Using users private/public key pair and request Certificate Authority to sign and verify the user.

Sign the CSR using cluster credentials

openssl x509 -req -in <user-name>.csr \
  -CA /var/lib/rancher/k3s/server/tls/client-ca.crt \
  -CAkey /var/lib/rancher/k3s/server/tls/client-ca.key \
  -CAcreateserial \
  -out <user-name>.crt \
  -days 365

Creates full package .crt, certificate trusted by the API server. Together with the private key, this creates user’s credentials. We will embed this pair into kubeconfig file.

Create Users kubeconfig

# Create cluster section
kubectl config set-cluster k3s-cluster \
  --server=https://127.0.0.1:6443 \
  --certificate-authority=/var/lib/rancher/k3s/server/tls/server-ca.crt \
  --embed-certs=true \
  --kubeconfig=<user-name>.kubeconfig

# Create user section
kubectl config set-credentials <user-name> \
  --client-certificate=<user-name>.crt \
  --client-key=<user-name>.key \
  --embed-certs=true \
  --kubeconfig=<user-name>.kubeconfig

# Create context section
kubectl config set-context <user-name>-context \
  --cluster=k3s-cluster \
  --user=<user-name> \
  --kubeconfig=<user-name>.kubeconfig

RBAC Cluster Role Example

Allow user just to list namespaces. This has to be cluste role because namespaces are cluster wide objects. In general role would be related to namespace and namespace objects.

Cluster Role

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: namespace-reader
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "list"]

Cluster Role Binding

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: namespace-reader-binding
subjects:
- kind: User
  name: <user-name>         # must match CN in the certificate
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: namespace-reader
  apiGroup: rbac.authorization.k8s.io

Test new kubeconfig

kubectl config use-context <user-name>-context --kubeconfig=<user-name>.kubeconfig
kubectl --kubeconfig=<user-name>.kubeconfig auth whoami