With the rapid development of Kubernetes, concepts such as depolying, Scaling and Managing Containeried applications have been widely spread among development, oAM and other related personnel. No matter how new the concept is, an engineering technique needs to be considered for safety before it can be applied to a large scale production environment. Therefore, production environment security deployment is one of the most important issues in Kubernetes. The underlying logic of Kubernetes authentication and authorization management of user and application requests is also the core knowledge that relevant staff should master most.

This series of documents is about the authentication and authorization of external requests for resources within the Kubernetes cluster, and how to use roles and Role Binding to control access to resources within the Kubernetes cluster.

  • Kubernetes Permission control Overview
  • Permission control – Understand Kubernetes authentication by example
  • Permission control – Understand Kubernetes authorization by example
  • Permission Control – Explore Kubernetes’ Service Accounts

The following examples are all running on the latest version of the Kubernetes cluster, but you can also use the local Minikube as an experimental environment

API server-Kubernetes gateway

Kubernetes all resources (Nodes, Labels, Pods, Deployments, Services, Secrets, Configmaps, Ingress, etc.) are objects, Kubernetes controls access to these resources through API services. CRUD operations on Kubernetes resources are performed using the REST API interface exposed to external users.

API Server is one of the core modules in Kubernetes, acting as a cluster gateway. Kubernetes internal modules (such as Kubelet, Scheduler, Controller) are scheduled and tuned via API services. The Distributed key-value pair database (ETCD) is also accessible only through API Server.

Kubectl is known as the Swiss Army knife of cluster management. All requests to Kubernetes are eventually sent to the Api Server. Other similar tools or modules operate on Kubernetes resource objects via API Server.

The Kubernetes cluster uses API Server to validate the request before the Kubernetes object is operated on. The client sending the request uses X.509 authentication to encrypt the sent request. The CA certificate and client certificate that are encrypted using X.509 authentication are obtained locally by Kubectl.

ApiVersion: v1 clusters: - cluster: certificate authority - data: data + OMITTED server: https://35.203.146.149:6443 name: kubernetes-the-hard-way contexts: - context: cluster: kubernetes-the-hard-way user: admin name: kubernetes-the-hard-way current-context: kubernetes-the-hard-way kind: Config preferences: {} users: - name: admin user: client-certificate: /Volumes/BOOTCAMP/dev/gcp/gcloud-k8s-config/script/admin.pem client-key: /Volumes/BOOTCAMP/dev/gcp/gcloud-k8s-config/script/admin-key.pemCopy the code

Ca.pem (which I did not configure in Kubectl Config for security reasons) requires a CA certificate for the local authentication authority. Obviously, Kubectl encrypts requests through certificates and keys in the context configuration.

Can we send a request to the API Server using curl? Of course you can!

In addition to requiring the associated CA-encrypted file, we also embed the token base64 encoded into the header of the request body.

kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'
Copy the code

export CLUSTER_NAME="kubernetes-the-hard-way"
Copy the code
APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")
Copy the code

The following command will obtain the token in the default service account:

TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 -D)
Copy the code

You can now use the curl command to request the API server:

curl -X GET \
	--cacert /Volumes/BOOTCAMP/dev/gcp/gcloud-k8s-config/script/ca.pem \
	--header "Authorization: Bearer $TOKEN" \
	$APISERVER/version
Copy the code

Kubernetes three-layer model of permission control

As mentioned above, all external users or Pods need to authenticate API Server before they can manipulate Kubernetes internal objects.

When a valid request reaches the API Server, the system uses layer 3 authentication to verify whether it has operation rights on the requested resource.

1. Authentication

After the request is authenticated by TLS, API Server will authenticate it using one or more authentication modules already enabled in Kubernetes. Related authentication modules are specified when the cluster is created. Multiple authentication modules are placed in a queue. The next authentication module will authenticate the authentication module only after the previous authentication module succeeds.

The authentication modules in Kubernetes include Client Certificates, Password, Plain Tokens, Bootstrap Tookens and JWT Tokens. Clinet Certifiactes is the default and most common authentication module in the cluster. For more information about the authentication module, you can refer to the module documentation.

Kubernetes does not maintain a dedicated user table or a portrait of authenticated users. Instead, Kubernetes authenticates x.509 authentication files or tokens passed to the authentication module. With this in mind, it is easy to understand how Kubernetes integrates OpenID,Github and even LDAP protocols into Kubernetes authentication system.

2.Authorization

Once the API request is authenticated, the next step verifies that the request is authorized to operate on Kubernetes internal resources, which occurs in the second step of the request validation process.

In authorization validation, Kubernetes will focus on the user name of the request, the behavior of the request, and the objects that the request will affect. The user name is extracted from the header of the request, the request behavior is the Http behavior corresponding to the CRUD operation (GET, PUT, DELETE, etc.), and the objects that the request will affect are the internal Pods, Services, etc.

Kubernetes’ authorization policy for resource objects follows a closed-to-open philosophy, which means that the relevant authorization policy must be configured if you want to access the resource.

Like authentication, the act of authorization can be configured through one or more authorization modules, such as ABAC, RBAC, and Webhook. The authorization module is already integrated into Kubernetes API Server when the administrator creates the cluster. If the Kubernetes cluster has multiple authorization modules enabled, API Server validates the request one by one using authorization modules. The request will not be authenticated until all modules have been authenticated, otherwise the request will be rejected (Http status code 403). For more information about the authorization module, you can refer to the module documentation.

3.Admission Control

After the request passes through authentication and authorization, it finally comes to access control, which, like authentication and authorization, is a plug-in module.

Unlike authentication and authorization, access control may modify the requested resource object. In addition to reading resource objects, access controls can have an effect on requests to create, delete, update, and broker resource objects. For example, access control intercepts requests to create storage volumes (PVC) and specifies the storage type of the PVC resource. You can also force a re-pull of the image when creating a Pod. Refer to the Kubernetes documentation for more access control modules.

Once a request is rejected by any controller, it is immediately rejected by Kubernetes during access controller processing. A request can operate resource objects only after it passes all access controllers.

In the next article, I will further explain how to create and authenticate users.

Translation of the articleA Primer on Kubernetes Access Control”, which was slightly abridged