Kubernetes: Authorization Part2- RBAC
Kubernetes resources can be classified as either namespaced or non-namespaced. You can use the
kubectl api-resources
command to obtain a list of resources available in the Kubernetes API, along with their namespace scope. To grant permissions to entities within a namespace, you can use Role. To grant permissions that span across the entire cluster, you can use ClusterRole. After defining these roles, you can bind them to specific entities using RoleBinding for Role and ClusterRoleBinding for ClusterRole.
Namespaced vs. Non-namespaced Resources
Kubernetes resources can be divided into two categories: namespaced and non-namespaced.
Namespaced resources are scoped to a specific namespace, which is a logical partition within a cluster that organizes and isolates resources. Each namespaced resource is unique within its namespace. Even though multiple resources in different namespaces may have the same name, they are separate and distinct resources with their own configurations and associated resources. For example, you could have two Pods with the name “web” in two different namespaces “production” and “staging”. Despite the same name, each pod is distinct and has its own configuration and associated resources in its respective namespace.
Non-namespaced resources are cluster-wide, meaning they are not bound to a particular namespace. Each non-namespaced resource is unique across the entire cluster. For example, the Node resource is non-namespaced. Each Kubernetes cluster has a set of nodes that are used to host and run containers. Since nodes are non-namespaced, there can only be one instance of each node resource in the entire cluster.
Kubectl api-resources command
The kubectl api-resources
command provides information about resources available in the Kubernetes API, including whether they are namespaced or not.
$ kubectl api-resources
The “NAMESPACED” column in the output indicates whether a resource is namespaced or not. If it’s “true”, the resource is namespaced, and if it’s “false”, it’s non-namespaced.
Part of namespaced resources:
NAME SHORTNAMES APIVERSION NAMESPACED KIND
configmaps cm v1 true ConfigMap
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
pods po v1 true Pod
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
Part of non-namespaced resources:
NAME SHORTNAMES APIVERSION NAMESPACED KIND
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumes pv v1 false PersistentVolume
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
storageclasses sc storage.k8s.io/v1 false StorageClass
RBAC
In Kubernetes, Role and ClusterRole are used to define a set of permissions that can be granted to entities (such as users, groups, or service accounts) within a namespace or across the entire cluster, respectively. On the other hand, RoleBinding and ClusterroleBinding are used to bind these roles to specific entities.
Role and RoleBinding(namespaced scope)
A Role is a set of permissions defined within a namespace that can be granted to entities within that namespace. For example, a role might allow a user to create or update pods within a namespace. A RoleBinding is used to bind a role to one or more entities, such as a user, group, or service account.
However, there may be scenarios where you need to define permissions for resources across multiple namespaces or for the entire cluster. In such cases, using a Role is not sufficient.
ClusterRole and ClusterRoleBinding(cluster-wide scope)
A ClusterRole is similar to a Role, but is defined at the cluster level, meaning it applies to all namespaces within the cluster. For example, a Clusterrole might allow a user to view all pods in the cluster. A ClusterRoleBinding is used to bind a clusterrole to an entity, such as a user, group, or service account, across all namespaces in the cluster.
Short Name
There are no short names for Role, RoleBinding, ClusterRole, and ClusterRoleBinding resources.
RBAC with YAML
Role and RoleBinding
role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: <role_name>
namespace: <namespace_name>
rules:
- apiGroups: ["<group_name>"] # "" for the core API group
resources: ["<namespaced_resource>"]
verbs: ["<verb1>", "<verb2>", ..., "<verbN>"]
If you are unfamiliar with apiGroups, consider reviewing “the Kubernetes documentation on Core and Named API Groups“.
role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: <rolebinding_name>
# The namespace of the RoleBinding determines where the permissions are granted.
# This only grants permissions within the "<namespace_name>" namespace.
namespace: <namespace_name>
subjects:
- kind: <User or Group or ServiceAccount>
name: <user_name or group_name or service_account_name>
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: <role_name>
apiGroup: rbac.authorization.k8s.io
example:
# developer-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: developer
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create"]
# developer-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-rolebinding
namespace: dev
subjects:
- kind: User
name: dev-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
You can use resourceNames
field to specify the name of the resource that the Role applies to.
role-specify-resource-name.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: <role_name>
namespace: <namespace_name>
rules:
- apiGroups: ["<group_name>"] # "" for the core API group
resources: ["<namespaced_resource>"]
resourceNames: ["<resource_name1>", "<resource_name2>", ..., "<resource_nameN>"]
verbs: ["<verb1>", "<verb2>", ..., "<verbN>"]
ClusterRole and ClusterRoleBinding
cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <cluster_role_name>
# "namespace" omitted since ClusterRoles are not namespaced
rules:
- apiGroups: ["<group_name>"] # "" for the core API group
resources: ["<resource>"]
verbs: ["<verb1>", "<verb2>", ..., "<verbN>"]
cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: <cluster_role_binding_name>
subjects:
- kind: <User or Group or ServiceAccount>
name: <user_name or group_name or service_account_name>
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: <cluster_role_name>
apiGroup: rbac.authorization.k8s.io
example:
# admin-cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: admin-cluster-role
rules:
- apiGroups: [""]
resources: ["pods", "services", "deployments"]
verbs: ["get", "list", "watch", "update", "create"]
# admin-cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-cluster-role-binding
subjects:
- kind: User
name: admin-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: admin-cluster-role
apiGroup: rbac.authorization.k8s.io
You can add a resourceNames
field to specify the name of the resource that the ClusterRole applies to.
cluster-role-with-resource-name.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <clusterrole_name>
# "namespace" omitted since ClusterRoles are not namespaced
rules:
- apiGroups: ["<group_name>"] # "" for the core API group
resources: ["<resource>"]
resourceNames: ["<resource_name1>", "<resource_name2>", ..., "<resource_nameN>"]
verbs: ["<verb1>", "<verb2>", ..., "<verbN>"]
Commands
- Create a new Role in the specified namespace, granting the specified verbs on the specified resources.
$ kubectl create role <role-name>
--verb=<verb>
--resource=<resource>
--namespace=<namespace>
2. Create a new RoleBinding in the specified namespace, binding the specified Role to the specified user.
$ kubectl create rolebinding <rolebinding-name>
--role=<role-name>
--user=<user-name>
--namespace=<namespace>
3. Create a new ClusterRole, granting the specified verbs on the specified resources across the entire cluster.
$ kubectl create clusterrole <clusterrole-name>
--verb=<verb>
--resource=<resource>
4. Create a new ClusterRoleBinding, binding the specified ClusterRole to the specified user across the entire cluster.
$ kubectl create clusterrolebinding <clusterrolebinding-name>
--clusterrole=<clusterrole-name>
--user=<user-name>
5. Check if the current user has the required permissions to perform a specific action on a particular resource within a specific namespace.
$ kubectl auth can-i <verb> <resource> --namespace <namespace_name>
6. Check if a user, group, or service account has the required permissions to perform a specific action on a particular resource within a specific namespace.
- User
$ kubectl auth can-i <verb> <resource> --namespace <namespace_name>
--as <user-name>
- Group
$ kubectl auth can-i <verb> <resource> --namespace <namespace_name>
--as-group <group-name>
- Service account
$ kubectl auth can-i <verb> <resource> --namespace <namespace_name>
--as system:serviceaccount:<namespace>:<service-account-name>
Return a“yes” or “no” answer, indicating whether the user has the necessary permissions.
These are my personal notes for CKA exam preparation on Kubernetes. Please feel free to correct me if you notice any errors. 😊
Related Stories:
Reference: