KUBERNETES RBAC | Role-Based Access Control, Creating ServiceAccounts & UserAccounts
1) What is RBAC?
Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within your organization.
RBAC authorization uses the rbac.authorization.k8s.io API group to drive authorization decisions, allowing you to dynamically configure policies through the Kubernetes API.
The RBAC API declares four kinds of Kubernetes object: Role, ClusterRole, RoleBinding and ClusterRoleBinding.
2) What are the advantages of using Rbac in Kubernetes?
Granular Access Control: RBAC allows you to define fine-grained access policies for users, groups, or service accounts. You can specify who can perform specific actions on particular resources, such as creating, reading, updating, or deleting pods, services, deployments, etc.
Centralized Management: Kubernetes RBAC provides a centralized way to manage access control policies. Instead of managing access at the application level, RBAC allows you to set permissions for all resources in the cluster from a single configuration point.
Separation of Responsibilities: With RBAC, you can define different roles for different teams or individuals based on their responsibilities.
Least Privilege Principle: RBAC follows the principle of least privilege, which means users or service accounts are granted only the permissions they need to perform their tasks, and nothing more.
3) What is ServiceAccount?
Kubernetes offers two distinct ways for clients that run within your cluster, or that otherwise have a relationship to your cluster’s control plane to authenticate to the API server.
A service account provides an identity for processes that run in a Pod, and maps to a ServiceAccount object. When you authenticate to the API server, you identify yourself as a particular user. Kubernetes recognises the concept of a user, however, Kubernetes itself does not have a User API.
In summary, it is used to authorize pods.
For example, let’s create a ServiceAccount. We will use next examples this serviceaccount.
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: example-account
EOFThen let’s list the ServiceAccount.
kubectl get sa
kubectl get serviceaccounts/example-account -o yaml4) Role and ClusterRole
An RBAC Role or ClusterRole contains rules that represent a set of permissions. Permissions are purely additive (there are no “deny” rules).
A Role always sets permissions within a particular namespace; when you create a Role, you have to specify the namespace it belongs in.
ClusterRole, by contrast, is a non-namespaced resource. The resources have different names (Role and ClusterRole) because a Kubernetes object always has to be either namespaced or not namespaced; it can’t be both.
ClusterRoles have several uses. You can use a ClusterRole to:
- define permissions on namespaced resources and be granted access within individual namespace(s)
- define permissions on namespaced resources and be granted access across all namespaces
- define permissions on cluster-scoped resources
If you want to define a role within a namespace, use a Role; if you want to define a role cluster-wide, use a ClusterRole.
There are 4 types of ClusterRoles:
cluster-admin: Cluster wide super user.admin: Full access within a Namespace.edit: Read/write within a Namespace.view: Read-only within a Namespace.
For example, Let’s examine the edit ClusterRole.
kubectl get clusterrolekubectl describe clusterrole editAs you can see, We can see what authority it contains on objects. You can also review other default ClusterRoles.
Let’s do some example;
Let’s create a Role named “role.yaml”.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: example-role
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"] # We can add the resources we want.
verbs: ["get", "watch", "list"] # We can add the verbs we want.kubectl apply -f role.yaml
kubectl get roleWe can use the Default ClusterRole as well as create the ClusterRole we want.
Let’s create a ClusterRole named “ClusterRole.yaml”.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: example-ClusterRole
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Secret
# objects is "secrets"
resources: ["secrets", "services"] # We can add the resources we want.
verbs: ["get", "watch", "list"] # We can add the verbs we want.kubectl apply -f ClusterRole.yaml
kubectl get clusterrole5) RoleBinding and ClusterRoleBinding
A role binding grants the permissions defined in a role to a user or set of users. It holds a list of subjects (users, groups, or service accounts), and a reference to the role being granted. A RoleBinding grants permissions within a specific namespace whereas a ClusterRoleBinding grants that access cluster-wide.
A RoleBinding may reference any Role in the same namespace. Alternatively, a RoleBinding can reference a ClusterRole and bind that ClusterRole to the namespace of the RoleBinding. If you want to bind a ClusterRole to all the namespaces in your cluster, you use a ClusterRoleBinding.
Let’s do some example;
Create a RoleBinding named “RoleBinding.yaml”.
apiVersion: rbac.authorization.k8s.io/v1
# You need to already have a Role named "example-role" in that namespace.
kind: RoleBinding
metadata:
name: example-role-binding
namespace: default
subjects:
# You can specify more than one "subject"
- kind: ServiceAccount # Could be User, Group etc.
name: default # "name" is case sensitive
namespace: default
roleRef:
# "roleRef" specifies the binding to a Role / ClusterRole
kind: Role #this must be Role or ClusterRole
name: example-role # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.ioThe summary of the RoleBinding object above is as follows: Pods belonging to the Default ServiceAccount can only display pods in the Cluster. The authorized pod cannot access objects such as Service, secrets, configMap etc. It can only access other pods.
kubectl apply -f RoleBinding.yaml
kubectl get rolebindingLet’s create a ClusterRoleBinding named “ClusterRoleBinding.yaml”.
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
name: example-cluster-role-binding
subjects:
- kind: ServiceAccount
name: example-account # Name is case sensitive
namespace: default
roleRef:
kind: ClusterRole
name: example-ClusterRole
apiGroup: rbac.authorization.k8s.ioLet’s create a pod to which this role is assigned.
apiVersion: v1
kind: Pod
metadata:
name: prometheus-deployment
spec:
containers:
- name: prometheus
image: prom/prometheus
ports:
- containerPort: 9090
serviceAccountName: example-accountExample summary, prometheus pod will only be able to see secrets and services objects. It will not have any authority over other objects.
kubectl apply -f ClusterRoleBinding.yaml
kubectl get clusterrolebinding6) What is UserAccount?
There are two types of users in a Kubernetes cluster: Service Accounts and User Accounts. User Accounts are used to authorize users. We can say that Service Accounts are used to authorize pods.
Let’s create a user.
Kubernetes User creation is done with Certificate. Then, authorization is defined for this created certificate. First, let’s create a certificate with OPENSSL.
Create a “Key”. As an example, get username=mesut
openssl genrsa -out mesut.key 2048Create a “Certificate Signing Request”. req: Request, csr: Certificate signing request , CN: Username, O: Groups
openssl req -new -key mesut.key -out mesut.csr -subj "/CN=mesut/O=DevOps"Let’s create the Certificate Signing Request we created with the kubernetes object.
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: mesut
spec:
groups:
- system:authenticated
request: $(cat mesut.csr | base64 | tr -d "\n")
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
EOFList CertificateSigningRequest.
CertificateSigningRequest status is in pending. It needs to be approved.
kubectl certificate approve mesut
kubectl get certificatesigningrequests.certificates.k8s.ioWe have to decode this Certificate.
kubectl get certificatesigningrequests.certificates.k8s.io mesut -o jsonpath={'.status.certificate'} | base64 --decodeWe save this certificate as “.crt”.
kubectl get certificatesigningrequests.certificates.k8s.io mesut -o jsonpath={'.status.certificate'} | base64 --decode >> mesut.crtThe certificate has been created. Now let’s add it as context.
kubectl config set-credentials mesut --client-certificate=mesut.crt --client-key=mesut.keyLet’s create Context for kubeconfig.
context_name = you can give any name you want,
cluster_name = you have to give your cluster name.
username = enter your username
# kubectl config set-context context_name --cluster=cluster_name -- user=username
kubectl config set-context mesut-kube --cluster=minikube --user=mesutList contexts and users.
kubectl config get-contexts
kubectl config get-usersContext change and list pods.
kubectl config use-context mesut-kube
kubectl get podsAs you can see, the “mesut” user couldn’t view the pods because It didn’t have any authority. Let’s give it some authority.
Switch to admin context.
kubectl config use-context minikubeCreate Role named “UserRole.yaml”
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: user-role
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods", "services"] # We can add the resources we want.
verbs: ["get", "watch", "list"] # We can add the verbs we want.Create Role named “UserRoleBinding.yaml”
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: user-role-binding
namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
name: mesut # "name" is case sensitive
namespace: default
roleRef:
# "roleRef" specifies the binding to a Role / ClusterRole
kind: Role #this must be Role or ClusterRole
name: user-role # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.iokubectl apply -f UserRole.yaml -f UserRoleBinding.yamlSwitch to context.
kubectl config use-context mesut-kubeTry to list.
kubectl get pods
kubectl get services
kubectl get secrets
kubectl get deploymentAs you can see, the “mesut” user can only view pod and service objects. Cannot view other objects and does not have edit permissions on any objects.
To delete users and context.
kubectl config delete-user mesut
kubectl config delete-context mesut-kubeThank you for reading…
References
