In this blog, we are going to look at what is Service Account on Kubernetes is and how it works.
Every Namespace has a default Service Account, and every container of the Pod uses this default Service Account to get authenticated to use the API server.
kubectl get serviceaccounts --all-namespaces
If you want to attach a Service Account to a Pod, both should be in the same Namespace.
When we create a Pod without mentioning the Service Account then the Pod will take the default Service Account, and the default Service Account will be automatically created on each Namespace.
Step 1: Create a Service Account
To create a Service Account using the imperative method, we can use the following command.
kubectl create serviceaccount test-sa
Once the Service Account is successfully created, we can list them.
kubectl get serviceaccount
We can create a Service Account using the YAML manifest.
cat << EOF > test-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa
namespace: default
labels:
app: nginx
annotations:
description: "Example service account for Kubernetes application"
EOF
kubectl apply -f test-sa.yaml
Step 2: Attaching the Service Account
Let’s create a manifest for Pod deployment.
kubectl run test-pod --image nginx --dry-run=client -o yaml > test-pod.yaml
This is the actual content of the manifest that we have created.
kubectl apply -f test-pod.yaml
The Pod is created, describe the Pod and view the Service Account details.
kubectl describe pod test-pod
We haven’t mentioned anything about the Service Account so it chooses the default Service Account, but this Service Account doesn’t have permission to do anything.
This is because, in Kubernetes, every Pod should attach with a Service Account and this is mandatory.
For testing purposes, I have installed the Kubectl utility on this Pod, and trying to contact the Kubernetes API server from the Pod.
kubectl exec -it test-pod -- kubectl get nodes
This error shows that the default
The service Account cannot contact the API Server to get the information.
Now I am going to attach the Service Account test-sa
that we created earlier, before attaching it to the Pod I am assigning permission using Cluster Role and Cluster Role Binding.
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: read-all-resources
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-all-resources-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: read-all-resources
subjects:
- kind: ServiceAccount
name: test-sa
namespace: default
EOF
Now, I am modifying the test-pod.yaml
manifest to add the Service Account test-sa
.
After deploying the modified manifest, describe the Pod to get more details.
Here, you can see that the Server Account has changed.
I am again trying to contact the API Server from the Pod
kubectl exec -it test-pod -- kubectl get nodes
This time I am getting a response to my query because I have attached permission with the service account.