Exercise 4: Service Accounts and RBAC
Task 1: Create Service Accounts and RBAC Roles
RBAC is used to control who can access what resources in your Kubernetes cluster. Let’s set up some RBAC rules:
Create a namespace for our RBAC example:
kubectl create namespace rbac-demo
kubectl create namespace rbac-demo
Create a service account:
kubectl create serviceaccount developer -n rbac-demo
kubectl create serviceaccount developer -n rbac-demo
Create a role that allows read-only access to pods:
$podReaderRoleYaml = @" apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: rbac-demo name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] "@ $podReaderRoleYaml | kubectl apply -f -
cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: rbac-demo name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] EOF
Create a role binding to assign the role to the service account:
$roleBindingYaml = @" apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods namespace: rbac-demo subjects: - kind: ServiceAccount name: developer namespace: rbac-demo roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io "@ $roleBindingYaml | kubectl apply -f -
cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods namespace: rbac-demo subjects: - kind: ServiceAccount name: developer namespace: rbac-demo roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io EOF
Task 2: Test RBAC Permissions
Create a pod to test RBAC:
kubectl run nginx --image=nginx -n rbac-demo
kubectl run nginx --image=nginx -n rbac-demo
Create a pod that uses the developer service account:
$rbacTestPodYaml = @" apiVersion: v1 kind: Pod metadata: name: rbac-test namespace: rbac-demo spec: serviceAccountName: developer containers: - name: curl image: k8sonazureworkshoppublic.azurecr.io/curlimages/curl command: ["sleep", "3600"] "@ $rbacTestPodYaml | kubectl apply -f -
cat << EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: rbac-test namespace: rbac-demo spec: serviceAccountName: developer containers: - name: curl image: k8sonazureworkshoppublic.azurecr.io/curlimages/curl command: ["sleep", "3600"] EOF
Wait for the pod to be running:
kubectl wait --for=condition=Ready pod/rbac-test -n rbac-demo
kubectl wait --for=condition=Ready pod/rbac-test -n rbac-demo
Test that the service account can list pods:
kubectl exec -it rbac-test -n rbac-demo -- sh -c 'curl https://kubernetes.default.svc/api/v1/namespaces/rbac-demo/pods -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" -k'
kubectl exec -it rbac-test -n rbac-demo -- sh -c 'curl https://kubernetes.default.svc/api/v1/namespaces/rbac-demo/pods -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" -k'
This should return a filtered list showing the names of pods in the namespace.
Test that the service account cannot create pods:
kubectl exec -it rbac-test -n rbac-demo -- sh -c 'TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) && curl -s -k -H "Authorization: Bearer $TOKEN" -X POST -H "Content-Type: application/json" -d "{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"name\":\"test-pod\"},\"spec\":{\"containers\":[{\"name\":\"nginx\",\"image\":\"nginx\"}]}}" https://kubernetes.default.svc/api/v1/namespaces/rbac-demo/pods'
kubectl exec -it rbac-test -n rbac-demo -- sh -c 'TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) && curl -s -k -H "Authorization: Bearer $TOKEN" -X POST -H "Content-Type: application/json" -d "{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"name\":\"test-pod\"},\"spec\":{\"containers\":[{\"name\":\"nginx\",\"image\":\"nginx\"}]}}" https://kubernetes.default.svc/api/v1/namespaces/rbac-demo/pods'
This should return an error indicating that the operation is forbidden.
Task 3: Clean Up
Delete the namespace and all resources created:
kubectl delete namespace rbac-demo
kubectl delete namespace rbac-demo