This is the last article in this series. We learned about the basic concepts of access control and the specific operations of authentication and authorization. In this article, we will learn more about service account in access control.
Kubernetes has the concepts of user and service account, which can be used to access resources. Users are associated with keys and certificates to authenticate API requests and use one of the configuration schemes to authenticate any requests initiated outside the cluster. The most common scheme is to request authentication through X.509 certificates. For information about creating certificates and associating certificates with users, see the Kubernetes authentication tutorial.
Keep in mind that Kubernetes does not maintain database or user and password configuration files. Instead, it wants to manage outside the cluster. Through the concept of authentication module, Kubernetes can delegate authentication to third parties, such as OpenID or Active Directory.
Although X.509 certificates can be used to authenticate external requests, service account can be used to authenticate processes running in the cluster. In addition, service account is associated with pod s that make internal calls to API server s.
Each Kubernetes installation has a default service account associated with each running pod. Similarly, to enable pod to invoke internal API Server endpoints, there is a Cluster IP service called Kubernetes that, together with the default service account, enables internal processes to invoke API endpoints.
kubectl get serviceAccounts
NAME SECRETS AGE default 1 122m
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 123m
Note that this service account points to the secret embedded in each pod. This secret contains the tokens required by API Server.
kubectl get secret
NAME TYPE DATA AGE default-token-4rpmv kubernetes.io/service-account-token 3 123m
When we started scheduling the pod and accessing it, everything became clear. We will use the curl command to start a BusyBox-based pod.
kubectl run -i --tty --rm curl-tns --image=radial/busyboxplus:curl
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. If you don't see a command prompt, try pressing enter. [ root@curl-tns-56c6d54585-6v2xp:/ ]$
When we are in the BusyBox shell, let's try to access API Server endpoints.
[ root@curl-tns-56c6d54585-6v2xp:/ ]$ curl https://kubernetes:8443/api
Because the request lacks an authentication token, no result is produced. Let's see how to retrieve tokens that can be embedded in HTTP headers.
As discussed earlier, the token is installed as a secret in the pod. Check / var / run / secrets / kubernetes. IO / service account to find the token.
[ root@curl-tns-56c6d54585-6v2xp:/ ]$ cd /var/run/secrets/kubernetes.io/serviceaccount
[ root@curl-tns-56c6d54585-6v2xp:/tmp/secrets/kubernetes.io/serviceaccount ]$ ls ca.crt namespace token
Let's set some environment variables to simplify the curl command.
CA_CERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
The curl command below requests services in the default namespace. Let's see if we can get a response from API Server.
[ root@curl-tns-56c6d54585-6v2xp:~ ]$ curl --cacert $CA_CERT -H "Authorization: Bearer $TOKEN" "https://kubernetes/api/v1/namespaces/$NAMESPACE/services/"
{ "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "services is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"services\" in API group \"\" in the namespace \"default\"", "reason": "Forbidden", "details": { "kind": "services" }, "code": 403 }
However, the default service account does not have sufficient permissions to retrieve services in the same namespace.
Keep in mind that Kubernetes follows a closed and open convention, which means that users and service account s do not have any permissions by default.
To satisfy this request, we need to create a role binding that associates the default service account with the appropriate role. This step is similar to the way we bind roles to Bob, who gives him the right to list pod s.
Exit pod and run the following command to create a role binding for the default service account.
kubectl create rolebinding default-view \ --clusterrole=view \ --serviceaccount=default:default \ --namespace=default
rolebinding.rbac.authorization.k8s.io/default-view created
The above command associates the default service account with the cluster role view, which enables pod to list resources.
If you're curious, and want to see all the available cluster roles, run the command: kubectl get cluster roles.
Let's start BusyBox pod again and access API Server.
kubectl run -i --tty --rm curl-tns --image=radial/busyboxplus:curl
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. If you don't see a command prompt, try pressing enter. [ root@curl-tns-56c6d54585-2cx44:/ ]$
CA_CERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
curl --cacert $CA_CERT -H "Authorization: Bearer $TOKEN" "https://kubernetes/api/v1/namespaces/$NAMESPACE/services/"
{ "kind": "ServiceList", "apiVersion": "v1", "metadata": { "selfLink": "/api/v1/namespaces/default/services/", "resourceVersion": "11076" }, "items": [ { "metadata": { "name": "kubernetes", "namespace": "default", "selfLink": "/api/v1/namespaces/default/services/kubernetes", "uid": "b715a117-6be1-4de0-8830-45bddcda701c", "resourceVersion": "151", "creationTimestamp": "2019-08-13T09:45:27Z", "labels": { "component": "apiserver", "provider": "kubernetes" } }, "spec": { "ports": [ { "name": "https", "protocol": "TCP", "port": 443, "targetPort": 8443 } ], "clusterIP": "10.96.0.1", "type": "ClusterIP", "sessionAffinity": "None" }, "status": { "loadBalancer": { } } } ] }
You are free to create additional bindings for the default service account to check how RBAC extends to pod.
This concludes the series on Kubernetes authentication and authorization. We discuss the basic concepts of authentication, authorization and Service account, hoping to help you.