Kubernetes RBAC
RBAC
Kubernetes RBAC is a powerful security feature that allows administrators to control who can access the Kubernetes API and what actions they can perform. You can use it to implement the principle of “least privilege,” which means that users should have the minimum levels of access necessary to perform their tasks. This approach minimizes the potential for accidental or malicious misuse of the Kubernetes system.
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.
Core Components of Kubernetes RBAC
Role
- Roles define a set of permissions within a specific namespace.
- They define which actions (verbs) can be performed on which resources (nouns) within that namespace. A role, for example, might enable a user to list and retrieve pods in a specific namespace. 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
- It has 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
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).
- A RoleBinding grants permissions within a specific namespace whereas a ClusterRoleBinding grants that access cluster-wide.
Documentation and Websites Referred
Service Account
- A service account provides an identity for processes that run in a Pod, and maps to a ServiceAccount object.
- Token associated to a SA is stored at
/var/run/secrets/kubernetes.io/serviceaccount/token inside a pod - We can configure a SA not to mount a secret in pod using
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot
automountServiceAccountToken: false
EOFkubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: build-robot
automountServiceAccountToken: false
EOF Step 1: Create a new Service Account:
kubectl create serviceaccount externalStep 2: Create a new POD with External Service Account
kubectl run external-pod --image=nginx --dry-run=client -o yamlAdd following contents under .spec
serviceAccountName: externalFinal File will look like this:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: external-pod
name: external-pod
spec:
serviceAccountName: external
containers:
- image: nginx
name: external-pod
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
EOFkubectl apply -f pod-sa.yamlStep 3: Verification
kubectl get pods
kubectl get pod external -o yamlStep 4: Fetch the Token of a POD
kubectl exec -it external-pod -- bash
cat /var/run/secrets/kubernetes.io/serviceaccount/tokenStep 5: Make a Request to Kubernetes using Token
curl -k <K8S-SERVER-URL>
curl -k <K8S-SERVER-URL>/api/v1 --header "Authorization: Bearer <TOKEN-HERE>"Create user with certificate
Step 1: Create a new private key and CSR
mkdir /root/certificates
cd /root/certificatesopenssl genrsa -out john.key 2048
openssl req -new -key john.key -out john.csr -subj "/CN=john/O=finance"Step 2: Decode the csr
cat john.csr | base64 | tr -d '\n'Step 3: Generate the Kubernetes Signing Request
nano csr-requests.yamlkubectl apply -f - <<EOF
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: john-csr
spec:
groups:
- system:authenticated
request: ADD-YOUR-CSR-HERE
signerName: kubernetes.io/kube-apiserver-client
usages:
- digital signature
- key encipherment
- client auth
EOFStep 4: Apply the Signing Requests:
kubectl apply -f csr-requests.yamlYou can optionally verify with kubectl get csr
Step 5: Approve the csr
kubectl certificate approve john-csrStep 6: Download the Certificate from csr
kubectl get csr john-csr -o jsonpath='{.status.certificate}' | base64 -d > john.crtStep 7: Create a new context
kubectl config set-credentials john --client-certificate=john.crt --client-key=john.keyStep 8: Set new Context
kubectl config set-context john-context --cluster [YOUR-CLUSTER-HERE] --user=johnStep 9: Use Context to Verify
kubectl --context=john-context get podsStep 10: Create RBAC Role Allowing List PODS Operation
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list"]
EOFStep 11: Create a New Role Binding
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
EOFStep 12: Verify Permissions
kubectl --context=john-context get podsStep 13: Delete Resources Created in this Lab
NameSpace Access Control
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: teama
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "create"]
EOFteama-rolebinding.yaml
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: teama
subjects:
- kind: User
name: john
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
EOFClusterRole & ClusterRoleBinding
Step 1: Delete Role and Role Binding
Step 2: Create a Cluster Role
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list"]
EOF- Check clusterrole
kubectl get clusterrole
kubectl describe clusterrole pod-readerStep 3: Create a Cluster Role Binding for a ServiceAccount named external in default namespace (make sure to create sa in right namespace)
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: list-pods-global
subjects:
- kind: User
name: system:serviceaccount:default:external
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-reader
apiGroup: rbac.authorization.k8s.io
EOF- Check Clusterrolebindings
kubectl get clusterrolebinding
kubectl describe clusterrolebinding list-pods-globalStep 4: Verify Permissions
curl -k <K8S-SERVER-URL>/api/v1/namespaces/default/pods --header "Authorization: Bearer <TOKEN-HERE>"Step 5: Create a new Namespace
kubectl create namespace externalcurl -k <K8S-SERVER-URL>/api/v1/namespaces/external/pods --header "Authorization: Bearer <TOKEN-HERE>"Step 6: Delete Cluster Role Binding
- Verify if you receive forbidden error.
curl -k <K8S-SERVER-URL>/api/v1/namespaces/external/pods --header "Authorization: Bearer <TOKEN-HERE>"Step 7: Create Role Binding with ClusterRole
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: system:serviceaccount:default:external
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: pod-reader
apiGroup: rbac.authorization.k8s.io
EOFStep 8: Verification
curl -k <K8S-SERVER-URL>/api/v1/namespaces/external/pods --header "Authorization: Bearer <TOKEN-HERE>"curl -k <K8S-SERVER-URL>/api/v1/namespaces/default/pods --header "Authorization: Bearer <TOKEN-HERE>"- You can also assign cluster-Admin role using below
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
EOFRole with Imperative commands
Create a Role named “pod-reader” that allows users to perform get, watch and list on pods:
kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=podsCreate a Role named “pod-reader” with resourceNames specified:
kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpodCreate a Role named “foo” with apiGroups specified:
kubectl create role foo --verb=get,list,watch --resource=replicasets.appsCreate a Role named “foo” with subresource permissions:
kubectl create role foo --verb=get,list,watch --resource=pods,pods/statusCreate a Role named “my-component-lease-holder” with permissions to get/update a resource with a specific name:
kubectl create role my-component-lease-holder --verb=get,list,watch,update --resource=lease --resource-name=my-componentCLusterROle
Create a ClusterRole named “pod-reader” that allows user to perform get, watch and list on pods:
kubectl create clusterrole pod-reader --verb=get,list,watch --resource=podsCreate a ClusterRole named “pod-reader” with resourceNames specified:
kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpodCreate a ClusterRole named “foo” with apiGroups specified:
kubectl create clusterrole foo --verb=get,list,watch --resource=replicasets.appsCreate a ClusterRole named “foo” with subresource permissions:
kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/statusRolebindings with Imperative commands
kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myappkubectl create rolebinding my-sa-view \
--clusterrole=view \
--serviceaccount=my-namespace:my-sa \
--namespace=my-namespaceKubernetes RBAC Setup
- Authentication
- Authorization
Role Binding
The rolebinding.yaml file defines a role binding named read-pods that binds the pod-reader role to the user jack in the default namespace.
Cluster Role
The clusterrole.yaml file contains the configuration for creating a cluster role named secret-reader. This cluster role allows the user to perform actions like get, watch, and list on secrets resources.
Role Binding (Namespace-level)
The rolebinding.yaml file defines a role binding named read-secrets that binds the secret-reader cluster role to the user dev in the development namespace.
Cluster Role Binding
The clusterrolebinding.yaml file contains the configuration for creating a cluster role binding named read-secrets-global. This cluster role binding binds the secret-reader cluster role to the user riya globally.
SecurityContext
- A Kubernetes security context is a set of security settings that are applied at the pod or container level.
- It provides you with the ability to define privilege and access controls for pods or containers.
- Example 1
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-context
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
containers:
- name: sec-ctx-demo
image: busybox
command: [ "sh", "-c", "sleep 1h" ]
EOF- Check the user id assigned
kubectl exec -it pod-context sh
id- Example 2
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
fsGroup: 2000
volumes:
- name: sec-ctx-vol
emptyDir: {}
containers:
- name: sec-ctx-demo
image: busybox
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: sec-ctx-vol
mountPath: /data/demo
EOF- Check the permission of /data/demo
kubectl exec -it security-context-demo sh
cd /data
ls -l