Due to the continuous development of Kubernetes, both the features and API continually evolve. To cope with the continuous evolution and to ensure compatibility over a long period of time, API conversioning is implemented. The components of the API version are the API path and the API levels. The API levels that are included in the specification are beta, alpha and stable. The alpha version provides a test bed of Kubernetes features. This version is not enabled by default and it is important to understand that this version may have bugs and some of its features may be excluded in future versions. The beta version differs from the alpha version because some testing has been done on the code but it is important to be aware it may have some bugs and features will be preserved in future versions. Although a production environment is not the best use case for beta version, it can still be used in a non-critical environment. The stable API has undergone testing and it can be used in a production environment.
Naming a stable API
To simplify extensibility API groups have been introduced. When using a JSON specification, a REST path and an apiVersion field specify an API group. Available API groups are core, extensions and batch. The API provides the same level of cluster access provided by the kubectl command. This is a dangerous situation that necessitates the need for authentication and authorization. Authentication is concerned with determining the identity of a user while authorization is concerned with controlling what users can do.
An API call begins via an http(s) client request which is followed by authentication and authorization. The API server uses either a secure or unsecured port to serve requests. When using an unsecured port, the default address is localhost and the default port is 8080 but the two parameters can be changed. Due to absence of TLS, requests do not pass through the authentication and authorization plugins. When using a secure port by default, port 6443 is used but it can be changed. TLS communication is supported in this mode of authentication. This mode allows specifying a certificate and a private SSL key.
All requests that are served through a secure port will be processed by authentication, authorization and admission control modules. Due to the processing provided when serving requests on this port it is advisable to use this port. By requiring clients to verify the certificate provided by the server, you are able to ensure the connection is encrypted and it does not face the risk of eavesdropping. When setting up the api-server, it is very important to ensure that the unsecured port can only be accessed through a localhost and network connections only use HTTPS.
When using minikube, a custom certificate and key are generated and they need to be loaded in the HTTPS client when making requests. A simpler way to access the API is through a proxy and this approach will be demonstrated in this article. It is important to be aware kubernetes does not have any features to support user management therefore these capabilities need to be implemented externally.
The three authentication approaches available in Kubernetes are listed below.
• Client certificates
• HTTP basic auth
• Bearer token
The simplest authentication approach is HTTP basic auth. This approach is enabled by starting the api-server and specifying a path to a csv file containing a password, user name and user id. In the csv file, you can include a fourth column that specifies group names. In basic auth, an authorization header consisting of an username, a password and an encoding level has to be included in all REST calls. An authorization header is generated by specifying a user and a password in the format shown below.
echo -n "user:password" | base64
To use a token authentication approach the api-server needs to be started and a path to a token file specified. The token file is specified as a csv file containing a token, a user, a user id and a group. The group is not required and if there are multiple groups they are separated using commas. An example of generating a token is shown in the command below:
echo `dd if=/dev/urandom bs=128 count=1 2>/dev/null |base64 |tr -d"=+/" | ddbs=32
After receiving the token, you include it in the token file alongside other parameters. When using a token approach an authorization header specifying a token is passed. An example of this specification is shown below:
Authorization: Bearer 3XQ8W6IAourkXOLH2yfpbGFXftbH0vn
To use client certificates approach the api-server needs to be started by specifying a path to a certificate file. The certificate file has one or multiple certificate authorities that validate the certificates presented by clients.
Another approach that can be used to authenticate users is OpenID which is founded on the Oauth protocol. When using OpenID, the identity of a user relies on an authorization server and user profile information. The major cloud infrastructure providers offer OpenID support. OpenID differs from OAuth2 because of the token field that is additionally returned. The token is signed by the server and its fields hold user information. Identity verification happens by the authenticator receiving a token from OAuth2ken in the form of a bearer token. The id_token holds all the information required for a successful authentication so there is no need to rely on an external provider. The token value is passed to kubectl either through a –token flag or included in kubeconfig file. Because there is no need to rely on an external provider every request is stateless which enhances scalability.
After a user has been successfully authenticated, the next step is to ensure they can only perform allowed operations which is referred to as authorization. There are several authorization approaches supported by kubernetes and they are listed below.
• Role based control
• Attribute based control
• Always deny
By default, kubernetes uses AlwaysAllow authorization which does not restrict any request. An authorization approach is specified via an –authorization—mode switch as shown below
kube-apiserver --authorization-mode <mode>
The mode is any one of the authorization approaches.
In this article, the importance of API versioning was discussed and the components used to construct an API version number were explained. The process of an API call was discussed and secured and unsecured connections. The different approaches to implement authentication and authorization were also discussed.