Creating Kubernetes User Accounts and Configuring Access with RBAC
This guide explains the process for creating a standard user account in a Kubernetes cluster using OpenSSL for certificate generation, configuring kubectl context, and assigning permissinos via RBAC.
Prerequisites
Prepare a directory for the certificate authority files.
mkdir /etc/k8s-certs/
cp /opt/kubernetes/ssl/ca.pem /etc/k8s-certs/
cp /opt/kubernetes/ssl/ca-key.pem /etc/k8s-certs/
Step 1: Generate User Certificate
- Create a private key for the user.
(umask 077; openssl genrsa -out app-user.key 2048) - Generate a Certificate Signing Request (CSR). The
Ofield defines the group, andCNdefines the username.openssl req -new -key app-user.key -out app-user.csr -subj "/O=app-team/CN=app-user" - Sign the certificate using the cluster's CA.
openssl x509 -req -in app-user.csr -CA /etc/k8s-certs/ca.pem -CAkey /etc/k8s-certs/ca-key.pem -CAcreateserial -out app-user.crt -days 365
Step 2: Configure kubectl Context
Construct a kubeconfig file using kubectl config commands. The --kubeconfig flag specifies a new file, otherwise settings are added to ~/.kube/config. The --embed-certs flag includes certificate data directly in the config.
- Set the cluster connection details.
kubectl config set-cluster prod-cluster \ --server=https://10.0.1.100:6443 \ --certificate-authority=/etc/k8s-certs/ca.pem \ --embed-certs=true \ --kubeconfig=/home/app-user/kubeconfig - Set the user credentials.
kubectl config set-credentials app-user \ --client-certificate=app-user.crt \ --client-key=app-user.key \ --embed-certs=true \ --kubeconfig=/home/app-user/kubeconfig - Create a context that associates the user with the cluster.
kubectl config set-context app-user@prod-cluster \ --cluster=prod-cluster \ --user=app-user \ --kubeconfig=/home/app-user/kubeconfig - Set this new context as the active one.
kubectl config use-context app-user@prod-cluster --kubeconfig=/home/app-user/kubeconfig - Set up the local environment for the user.
useradd -m app-user mkdir -p /home/app-user/.kube cp /home/app-user/kubeconfig /home/app-user/.kube/config chown -R app-user:app-user /home/app-user/.kube
At this point, running kubectl get pods will fail because the user lacks authorization.
Step 3: Assign Permissions with RBAC
Grant access using Role-Based Access Control (RBAC).
Namespace-Scoped Role and Binding
First, create a Role that defines permissions within a specific namespace (e.g., default).
# role-pod-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-viewer
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
Apply it: kubectl apply -f role-pod-reader.yaml
Next, bind the app-user to this Role.
# binding-user-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-user-pod-viewer
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-viewer
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: app-user
Apply it: kubectl apply -f binding-user-role.yaml
The user can now list pods in the default namespace: kubectl get pods.
Cluster-Scoped Role and Binding
To grant permissions across all namespaces, use a ClusterRole and ClusterRoleBinding.
Create a ClusterRole for cluster-wide pod reading.
# clusterrole-global-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: global-pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
Apply it: kubectl apply -f clusterrole-global-reader.yaml
Bind the user to this ClusterRole.
# clusterbinding-user-global.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: app-user-global-reader
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: global-pod-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: app-user
Apply it: kubectl apply -f clusterbinding-user-global.yaml
The user can now list pods in all namespaces: kubectl get pods --all-namespaces.
Quick Permission Assignment
You can use a one-liner to bind an existing ClusterRole (like view or admin) to a user in a namespace.
kubectl create rolebinding app-user-dev-admin \
--clusterrole=admin \
--user=app-user \
--namespace=development
Example of an Extended ClusterRole
The following ClusterRole definition grants broader permissions across multiple resource types.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: extended-manager
rules:
- apiGroups: [""]
resources: ["pods", "configmaps", "namespaces"]
verbs: ["*"]
- apiGroups: ["", "apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods/exec", "pods/log"]
verbs: ["get", "create"]