Day 25/40 Days of K8s: Service Account in Kubernetes !! βΈοΈ
π What is a Service account in K8s?
Service accounts in Kubernetes (K8s) are a type of non-human users to authenticate with the Kubernetes API server similar to how user accounts are identities for human users.
Example: Prometheus use service accounts to collect metrics from the cluster, Jenkins use service accounts to deploy applications or manage resources in the cluster.
While Human users need certificates to authenticate with api-server but Service accounts use tokens.
Like human users, service accounts can be bound to roles (Role Binding) or cluster roles (Cluster Role Binding) to define their permissions.
Kubernetes automatically creates a default service account in each namespace. If you do not specify a ServiceAccount when you create a Pod, Kubernetes automatically assigns the ServiceAccount named default in that namespace.
You can list all ServiceAccount resources for current namespace with
kubectl get serviceaccounts
Each namespace have dedicated service account, list ServiceAccount for all namespaces using
kubectl get serviceaccount -A
To create and list a service account
kubectl create sa name kubectl get sa
As you can see, we created a serviceaccount named vivi-sa
and since we didn't specified any namespace while creating, it took default
namespace. Also the default serviceaccount for default
namespace was already there.
β Authentication
Manually create a long-lived API token for a ServiceAccount
If you want to obtain an API token for a ServiceAccount, you create a new Secret with a special annotation, kubernetes.io/service-account.name
Create a secret using this yaml
apiVersion: v1 kind: Secret metadata: name: vivi-secret annotations: kubernetes.io/service-account.name: vivi-sa type: kubernetes.io/service-account-token
This will create a secret named
vivi-secret
of typeapi-token
and assign the secret to serviceaccount namedvivi-sa
Now, we have a token ready for serviceaccount named vivi-sa
, make a curl
API request to the Kubernetes API server using a service account token, and eventually we can add role and role binding for authorization.
curl -k \
-H "Authorization: Bearer <your-api-token>" \
-H "Content-Type: application/json" \
https://<your-k8s-api-server>:6443/api/v1/pods
Determine the URL of your Kubernetes API server.You can find it in ~/.kube/config
β Accessing External Docker Registries
Add ImagePullSecrets to a service account
Use case: To pull Docker images from a private registry, we create a Kubernetes secret that contains the credentials required for authentication.
We then reference this secret in either Pod or serviceaccount YAML using the
imagePullSecrets
field.
Create a Secret using the command
kubectl create secret docker-registry secret-name \
--docker-username=<username> \
--docker-password=<password> \
--docker-email=<email> \
--docker-server=<registry-server>
Add image pull secret to service account
We can edit the serviceaccount by adding lines for imagePullSecrets:
and save it.
kubectl edit serviceaccount/vivi-sa
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2024-07-30T11:57:25Z"
name: vivi-sa
namespace: default
uid: 1ff116ad-9c36-4f71-8460-7f9a27ab351c
imagePullSecrets:
- name: myregistrykey
NOTE: Service account tokens are used for authenticating non-human users (like applications) to the Kubernetes API server.
When you create a service account in a namespace, Kubernetes automatically generates a default token associated with that service account which is tied to the lifecycle of the Service Account. This token can be mounted into Pods and used for authentication.
But, to create a persistent token for a Service Account that does not expire and can be used consistently, you can create a Secret manually and annotate with service account name.
imagePullSecrets for new Pods
Purpose: For authenticating with container registries, especially private ones, to allow Pods to pull images.
We can include the
imagePullSecrets
field directly in the Pod. Alternatively, we can attachimagePullSecrets
to a service account. This means that every Pod that uses this service account will automatically use the specified image pull secrets for pulling images.
Let's create a new Pod in the current namespace default
and using the vivi-sa
ServiceAccount
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
spec:
serviceAccountName: vivi-sa
containers:
- name: nginx
image: nginx
Now, The Pod named nginx
, created with the service account vivi-sa
, is automatically utilizing the secret named myregistrykey
as its imagePullSecrets
.
When the Pod is created, Kubernetes uses the specified
imagePullSecrets
to authenticate with the Docker registry and pull the image.* Simultaneously, the service account token is automatically mounted into the Pod, allowing the application to authenticate with the Kubernetes API.
Verify service account token by bashing into the container,
The token is mounted inside the Pod at the path /var/run/secrets/kubernetes.io/serviceaccount
and is ready to authenticate with api-server.
β Role and RoleBinding to grant access(Authorization)
Verify if the serviceaccount can get the list of pods or not
kubectl get pods --as vivi-sa
Let's create a Role and Rolebinding
kubectl create role vivi-role \ --verb=list,get,watch \ --resource=pod kubectl create rolebinding vivi-rb \ --role=vivi-role \ --user=vivi-sa
Verify to confirm that serviceaccount now have access to list the pods
β Common Questions
Is the service account namespace-level?
Yes, service accounts are scoped to the namespace level. Each namespace can have its own set of service accounts, including a default service account.
How will the Prometheus Pod in a namespace gather metrics from all nodes if it is namespace-scoped?
While Prometheus runs in a specific namespace, it can be configured to scrape metrics from all nodes and other services running in the cluster, regardless of their namespaces.
Prometheus collects metrics from all nodes in a Kubernetes cluster by utilizing Node Exporters deployed as DaemonSets on each node. It uses service discovery, along with annotations, to automatically locate and scrape these metrics. The target Pods behind the services expose their metrics at the
/metrics
endpoint, and annotations are used to inform Prometheus which services or Pods should be scraped. This setup enables Prometheus to effectively monitor the entire cluster, regardless of the namespace in which it is deployed.
#Kubernetes #ServiceAccount #RBAC #Authorization #Role #RoleBinding #ClusterRole #ClusterRoleBinding #40DaysofKubernetes #CKASeries
Subscribe to my newsletter
Read articles from Gopi Vivek Manne directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Gopi Vivek Manne
Gopi Vivek Manne
I'm Gopi Vivek Manne, a passionate DevOps Cloud Engineer with a strong focus on AWS cloud migrations. I have expertise in a range of technologies, including AWS, Linux, Jenkins, Bitbucket, GitHub Actions, Terraform, Docker, Kubernetes, Ansible, SonarQube, JUnit, AppScan, Prometheus, Grafana, Zabbix, and container orchestration. I'm constantly learning and exploring new ways to optimize and automate workflows, and I enjoy sharing my experiences and knowledge with others in the tech community. Follow me for insights, tips, and best practices on all things DevOps and cloud engineering!