Question
The ServiceAccount you are about to create should live in a custom namespace. Start by creating a new namespace with the name apps. Verify that the namespace has been created properly by querying for it.
Create the ServiceAccount named api-access in a new namespace called apps.
Create a ClusterRole with the name api-clusterrole, and the ClusterRoleBinding named api-clusterrolebinding. Map the ServiceAccount from the previous step to the API resources Pods with the operations watch, list, get.
Create a Pod named operator with the image nginx:1.21.1 in the namespace apps. Expose the container port 80. Assign the ServiceAccount api-access to the Pod.
Create another Pod named disposable with the image nginx:1.21.1 in the namespace rm. Do not assign the ServiceAccount to the Pod.
Open an interactive shell to the Pod named operator. Use the command line tool curl to make an API call to list the Pods in the namespace rm. What response do you expect?
Use the command line tool curl to make an API call to delete the Pod disposable in the namespace rm. Does the response differ from the first call?
Answer
Create the namespace:
kubectl create ns apps
Verify:
kubectl get ns apps
Create ServiceAccount in that Namespace:
kubectl -n apps create sa api-access
Verify that the ServiceAccount has been created properly:
kubectl -n apps get sa api-access
Create the ClusterRole imperatively:
kubectl create clusterrole api-clusterrole --verb=watch,list,get --resource=pods
Verify that the ClusterRole has been created properly:
kubectl get clusterrole api-clusterrole
Create the ClusterRoleBinding in same way:
kubectl create clusterrolebinding api-clusterrolebinding --serviceaccount=apps:api-access --clusterrole=api-clusterrole
Verify:
kubectl get clusterrolebinding api-clusterrolebinding
Run the pods, note that rm Namespace sbould be created:
kubectl run operator --image=nginx:1.21.1 --restart=Never --port=80 --serviceaccount=api-access -n apps
kubectl create namespace rm
kubectl run disposable --image=nginx:1.21.1 --restart=Never -n rm
Verify:
kubectl get pod operator -n apps
kubectl get pod disposable -n rm
Get cluster's API IP:
kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'
Get secret access token of the ServiceAccount:
kubectl get secret $(kubectl get serviceaccount api-access -n apps -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' -n apps | base64 --decode
Execute the calls to the API server from within the Pod named operator to list the pods in rm namespace using above two queries:
kubectl exec operator -n apps -- curl $(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')/api/v1/namespaces/rm/pods \
--header "Authorization: Bearer $(kubectl get secret $(kubectl get serviceaccount api-access -n apps -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' -n apps | base64 --decode)" --insecure
can be noticed that the list of pods is possiblekubectl exec operator -n apps -- curl -X DELETE $(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')/api/v1/namespaces/rm/pods/disposable \
--header "Authorization: Bearer $(kubectl get secret $(kubectl get serviceaccount api-access -n apps -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' -n apps | base64 --decode)" --insecure
can be noticed from error message that this is forbidden - the ServiceAccount does not have those rights