Managing RBAC
Introduction
This tutorial will guide you through managing Role-Based Access Control (RBAC) in Kubernetes. We will cover creating users, service accounts, roles, role bindings, and cluster role bindings. Basic familiarity with Kubernetes concepts like pods, namespaces, and deployments is assumed. You should have a working Kubernetes cluster and kubectl configured.
Task 1: Understanding RBAC Concepts
Before diving into the practical steps, let’s briefly review the core concepts of RBAC in Kubernetes:
- Users: Represents a human user or an external identity. Kubernetes doesn’t have its own user management system; it relies on external authentication mechanisms.
- Service Accounts: Represents an identity for processes that run inside pods. Service accounts are managed by Kubernetes.
- Roles: Define a set of permissions within a specific namespace. A role grants access to Kubernetes resources, such as pods, deployments, and services.
- ClusterRoles: Similar to Roles, but they are cluster-wide. They can grant access to cluster-scoped resources and can be referenced from within any namespace.
- RoleBindings: Grants the permissions defined in a Role to a user or a set of users. It operates within a single namespace.
- ClusterRoleBindings: Grants the permissions defined in a ClusterRole to a user or a set of users. It operates cluster-wide.
graph LR
A[User/ServiceAccount] --> B{Authentication}
B --> C{Authorization}
C --> D{RBAC Check}
D -- Granted --> E((Access Resource))
D -- Denied --> F((Access Denied))
Task 2: Creating a Service Account
Service accounts provide an identity for pods. Let’s create a service account in the default namespace.
-
Create a YAML file named
serviceaccount.yamlwith the following content:NODE_TYPE // yamlapiVersion: v1 kind: ServiceAccount metadata: name: example-sa namespace: default -
Apply the configuration:
NODE_TYPE // bashkubectl apply -f serviceaccount.yamlNODE_TYPE // outputserviceaccount/example-sa created -
Verify the service account:
NODE_TYPE // bashkubectl get serviceaccount example-sa -n default -o yamlThis will display the details of the newly created service account.
Service accounts are automatically mounted into pods that don’t specify a different service account.
Task 3: Creating a Role
Now, let’s define a Role that grants permissions to read pods within the default namespace.
-
Create a YAML file named
role.yamlwith the following content:NODE_TYPE // yamlapiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"] -
Apply the configuration:
NODE_TYPE // bashkubectl apply -f role.yamlNODE_TYPE // outputrole.rbac.authorization.k8s.io/pod-reader created -
Verify the role:
NODE_TYPE // bashkubectl get role pod-reader -n default -o yamlThis command will show the details of the
pod-readerrole.Roles are namespace-scoped. This role only applies to thedefaultnamespace.
Task 4: Creating a RoleBinding
A RoleBinding links the Role with the Service Account. Let’s create a RoleBinding to grant the pod-reader role to the example-sa service account.
-
Create a YAML file named
rolebinding.yamlwith the following content:NODE_TYPE // yamlapiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods namespace: default subjects: - kind: ServiceAccount name: example-sa namespace: default roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io -
Apply the configuration:
NODE_TYPE // bashkubectl apply -f rolebinding.yamlNODE_TYPE // outputrolebinding.rbac.authorization.k8s.io/read-pods created -
Verify the RoleBinding:
NODE_TYPE // bashkubectl get rolebinding read-pods -n default -o yamlThis will display the details of the
read-podsRoleBinding.RoleBindings connect subjects (users, groups, service accounts) to roles.
Task 5: Testing the Permissions
To test the permissions, we’ll create a pod that uses the example-sa service account and attempts to list pods. We will need to extract the token associated with the service account and use it to authenticate.
-
Get the service account token:
NODE_TYPE // bashkubectl get serviceaccount example-sa -n default -o jsonpath='{.secrets[0].name}'This will output the name of the secret containing the token (e.g.,
example-sa-token-xxxxx). Let’s assume the token name isexample-sa-token-xxxxx. -
Extract the token:
NODE_TYPE // bashkubectl get secret example-sa-token-xxxxx -n default -o jsonpath='{.data.token}' | base64 -dThis will output the actual token. Store this token in a secure location. Let’s assume the token is
eyJhbGciOiJIUzI1NiIsImtpZCI6Im9Va.... -
Create a
kubeconfigfile for the service account. Replace the cluster details, user details, and token with your actual values. The cluster CA data can be obtained with:kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[0].cluster.certificate-authority-data}'NODE_TYPE // yamlapiVersion: v1 kind: Config clusters: - cluster: certificate-authority-data: <base64 encoded CA data> server: <your cluster endpoint> name: example-cluster contexts: - context: cluster: example-cluster user: example-sa name: example-context current-context: example-context users: - name: example-sa user: token: eyJhbGciOiJIUzI1NiIsImtpZCI6Im9Va... -
Test the access using the new
kubeconfigfile. Save the above yaml assa-kubeconfig.yaml.NODE_TYPE // bashkubectl --kubeconfig=sa-kubeconfig.yaml get pods -n defaultThis command, using the service account’s credentials, should successfully list the pods in the
defaultnamespace.Make sure to replace placeholders with your actual values!
Task 6: Creating a ClusterRole
ClusterRoles are used to define permissions that apply cluster-wide. Let’s create a ClusterRole that allows reading nodes.
-
Create a YAML file named
clusterrole.yamlwith the following content:NODE_TYPE // yamlapiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: node-reader rules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list"] -
Apply the configuration:
NODE_TYPE // bashkubectl apply -f clusterrole.yamlNODE_TYPE // outputclusterrole.rbac.authorization.k8s.io/node-reader created -
Verify the ClusterRole:
NODE_TYPE // bashkubectl get clusterrole node-reader -o yaml
Task 7: Creating a ClusterRoleBinding
Now, let’s create a ClusterRoleBinding to grant the node-reader ClusterRole to a specific user. For this example, we will grant it to the example-sa service account. Note: in a real-world scenario, consider granting this to a dedicated user or group instead of a service account.
-
Create a YAML file named
clusterrolebinding.yamlwith the following content:NODE_TYPE // yamlapiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: read-nodes subjects: - kind: ServiceAccount name: example-sa namespace: default roleRef: kind: ClusterRole name: node-reader apiGroup: rbac.authorization.k8s.io -
Apply the configuration:
NODE_TYPE // bashkubectl apply -f clusterrolebinding.yamlNODE_TYPE // outputclusterrolebinding.rbac.authorization.k8s.io/read-nodes created -
Verify the ClusterRoleBinding:
NODE_TYPE // bashkubectl get clusterrolebinding read-nodes -o yaml -
Test the access using the
sa-kubeconfig.yamlcreated in Task 5:NODE_TYPE // bashkubectl --kubeconfig=sa-kubeconfig.yaml get nodesThis should now successfully list the nodes in the cluster, using the
example-sa’s credentials.
Task 8: Creating a User
Kubernetes relies on external identity providers for authenticating users. You can configure your cluster to use various authentication methods, such as:
- X.509 Client Certificates: Each user has a unique certificate.
- Static Password File: (Not recommended for production)
- Bootstrap Tokens: For initial setup.
- OIDC (OpenID Connect): Integrate with identity providers like Google, Azure AD, etc.
- Webhook Token Authentication: Custom authentication logic.
For this example, we’ll demonstrate how to create a user using client certificates.
-
Generate a Private Key:
NODE_TYPE // bashopenssl genrsa -out jane.key 2048 -
Create a Certificate Signing Request (CSR):
NODE_TYPE // bashopenssl req -new -key jane.key -out jane.csr -subj "/CN=jane/O=example-org"CN(Common Name): Set to the username (jane).O(Organization): Set to an organization identifier (example-org).
-
Sign the CSR with the Kubernetes CA:
This step requires access to the Kubernetes CA certificate and key. Typically, these are located on the control plane nodes. Replace the paths with the actual locations on your system.
NODE_TYPE // bashopenssl x509 -req -in jane.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out jane.crt -days 365Securely store thejane.keyfile. Anyone with this key can impersonate the user. Treat it like a password. -
Configure kubectl to use the certificate:
NODE_TYPE // bashkubectl config set-credentials jane --client-certificate=jane.crt --client-key=jane.key -
Create a context for the user:
NODE_TYPE // bashkubectl config set-context jane-context --cluster=<your cluster name> --user=jane --namespace=defaultReplace
<your cluster name>with the name of your cluster. You can find this in your existingkubectlconfiguration. -
Switch to the new context:
NODE_TYPE // bashkubectl config use-context jane-context
Now, any commands you run will be executed as user jane. Initially, jane has no permissions.
Task 9: Granting Permissions to the User
Let’s grant jane the permission to view pods in the default namespace.
-
Create a RoleBinding:
NODE_TYPE // yamlapiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: jane-pod-reader namespace: default subjects: - kind: User name: jane apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io -
Apply the RoleBinding:
NODE_TYPE // bashkubectl apply -f rolebinding-jane.yaml -
Verify
janecan now list pods:Ensure that the
jane-contextis selected usingkubectl config use-context jane-context.NODE_TYPE // bashkubectl get pods -n defaultJane should now be able to view pods in the
defaultnamespace.Ensure the userjaneis defined correctly in thesubjectssection of the RoleBinding. Thenamemust match the common name (CN) in the user’s certificate.
Conclusion
In this tutorial, you learned how to manage RBAC in Kubernetes. You created service accounts, roles, role bindings, cluster roles, cluster role bindings, and demonstrated how to create and grant permissions to a user. You tested these configurations to ensure they were functioning correctly. Remember that proper RBAC configuration is critical for securing your Kubernetes cluster. Always follow the principle of least privilege, granting only the necessary permissions to users and service accounts.