Securing the Kubernetes API server

kubernetes
Reading Time: 5 minutes

In this blog, we are going to learn how applications running in pods can talk to the API server to retrieve or change the state of resources deployed in the cluster. To authenticate with the API server, you used the ServiceAccount token mounted into the pod. In this blog,you’ll learn what ServiceAccounts are and how to config-ure their permissions, as well as permissions for other subjects using the cluster.

Understanding authentication

we can say that the API server can be configure with one or more authentication plugins (and the same is true for authorization plugins). When a request is received by the API server, it goes through the list of authentication plugins, so they can each examine the request and try to determine who’s sending the request. The first plugin that can extract that information from the request returns the username, user ID, and the groups the client belongs to back to the API server core. The API server stops invoking the remaining authentication plugins and continues onto the authorization phase.


Several authentication plugins are available. They obtain the identity of the client using the following methods:

  • From the client certificate
  • From an authentication token passed in an HTTP header
  • Basic HTTP authentication
  • Others
  • The authentication plugins are enabled through command-line options when startingthe API server.

Users and groups

An authentication plugin returns the username and group(s) of the authenticated user. Kubernetes doesn’t store that information anywhere; it uses it to verify whether the user is authorized to perform an action or not.

UNDERSTANDING USERS

Kubernetes distinguishes between two kinds of clients connecting to the API server:

  • Actual humans (users)
  • Pods (more specifically, applications running inside them)

Both these types of clients are authenticate using the aforementioned authentication plugins. Users are meant to be managed by an external system, such as a Single Sign On (SSO) system, but the pods use a mechanism called service accounts, which are created and stored in the cluster as ServiceAccount resources. In contrast, no resource
represents user accounts, which means you can’t create, update, or delete users through the API server.


We won’t go into any details of how to manage users, but we will explore Service-Accounts in detail, because they’re essential for running pods. For more information on how to configure the cluster for authentication of human users, cluster administrators should refer to the Kubernetes Cluster Administrator guide at http://
kubernetes.io/docs/admin.

UNDERSTANDING GROUPS

Both human users and ServiceAccounts can belong to one or more groups. We’ve said that the authentication plugin returns groups along with the username and user ID.Groups are used to grant permissions to several users at once, instead of having to grant them to individual users.

Groups returned by the plugin are nothing but strings, representing arbitrary group names, but built-in groups have special meaning:

  • The system:unauthenticated group is used for requests where none of the authentication plugins could authenticate the client.
  • The system:authenticated group is automatically assigne to a user who was authenticated successfully.
  • The system:serviceaccounts group encompasses all ServiceAccounts in the system.
  • The system:serviceaccounts: includes all ServiceAccounts in a specific namespace.

Introducing ServiceAccounts

Let’s explore ServiceAccounts up close. You’ve already learned that the API server requires clients to authenticate themselves before they’re allow to perform operations on the server. And you’ve already seen how pods can authenticate by sending the contents of the file /var/run/secrets/kubernetes.io/serviceaccount/token , which
is mount into each container’s filesystem through a secret volume.But what exactly does that file represent? Every pod is associate with a Service-Account, which represents the identity of the app running in the pod. The token file
holds the ServiceAccount’s authentication token. When an app uses this token to connect to the API server, the authentication plugin authenticates the ServiceAccount and passes the ServiceAccount’s username back to the API server core. Service-Account usernames are formatt like this:

system:serviceaccount:<namespace>:<service account name>

The API server passes this username to the configure authorization plugins, which determine whether the action the app is trying to perform is allow to be performe by the ServiceAccount.

ServiceAccounts are nothing more than a way for an application running inside a pod to authenticate itself with the API server. As already mentioned, applications do that by passing the ServiceAccount’s token in the request.

UNDERSTANDING THE SERVICE ACCOUNT RESOURCE

ServiceAccounts are resources just like Pods, Secrets, ConfigMaps, and so on, and are scope to individual namespaces. A default ServiceAccount is automatically create for each namespace (that’s the one your pods have used all along).
You can list ServiceAccounts like you do other resources:

Creating ServiceAccounts

We’ve said every namespace contains its own default ServiceAccount, but additional ones can be create if necessary. But why should you bother with creating Service-Accounts instead of using the default one for all your pods?


The obvious reason is cluster security. Pods that don’t need to read any cluster metadata should run under a constrained account that doesn’t allow them to retrieve or modify any resources deployed in the cluster. Pods that need to retrieve resource metadata should run under a ServiceAccount that only allows reading those objects’
metadata, whereas pods that need to modify those objects should run under their own ServiceAccount allowing modifications of API objects.

Let’s see how you can create additional ServiceAccounts, how they relate to Secrets, and how you can assign them to your pods.

CREATING A SERVICE ACCOUNT

Creating a ServiceAccount is incredibly easy, thanks to the dedicated kubectl create serviceaccount command. Let’s create a new ServiceAccount called foo :

Now, you can inspect the ServiceAccount with the describe command, as shown in the following listing.

You can see that a custom token Secret has been create and associated with the ServiceAccount. If you look at the Secret’s data with kubectl describe secret foo-token-qzq7j , you’ll see it contains the same items (the CA certificate, namespace, and token) as the default ServiceAccount’s token does (the token itself will obviously be different), as shown in the following listing.

Conclusion

Despite growing adoption, security remains the top concern when it comes to containers and Kubernetes. The good news is that there are many things you can do to make your implementation of containers more secure. This introduction to securing Kubernetes outlines many of the steps you can take to get start with container security.

Written by 

Adesh shukla is a DevOps Intern at Knoldus Inc. His practice area is DevOps. He is always open to learn new things.. His hobbies is playing cricket.