Deploying a Kubernetes cluster is relatively easy, even for beginners. However, maintaining its functionality is a different story. One of the key tasks here is managing access rights to prevent cluster issues. In this guide, we'll explore the most effective way to restrict access, minimizing the chances of cluster disruptions due to accidental configuration changes by inexperienced users. But first, let's cover some basics.
Kubernetes access control is based on the concept of roles and permissions, known as Role-Based Access Control (RBAC). RBAC allows Kubernetes administrators to define who has access to which resources and operations within the cluster.
The following key entities are used for configuring Role-Based Access Control in Kubernetes:
Roles: Define what actions are permitted on specific resources (e.g., read, write, delete).
RoleBindings: Link roles to specific users, service accounts, or groups.
ServiceAccounts: Used to authenticate applications and services within the cluster.
With RBAC, administrators can control access to various Kubernetes resources, such as pods, services, and storage, based on the needs and roles of users or services. RBAC provides a flexible access management system that helps ensure security and control over the cluster.
RBAC allows you to set access controls at the Kubernetes cluster level (using ClusterRole
and ClusterRoleBinding
) or limit them within a specific namespace (using Role
and RoleBinding
).
To create a Role
and RoleBinding
in Kubernetes, you need to create YAML files defining these objects. Below are specific examples. First, here's a code example for defining a Role
(let's call it getlistwatch.yaml
):
kind: Role
metadata:
namespace: default
name: getlistwatch
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
Now, here's an example for defining a RoleBinding
(let's call it getlistwatch-bind.yaml
):
kind: RoleBinding
metadata:
name: getlistwatch-bind
namespace: default
subjects:
- kind: User
name: username # Replace 'username' with the actual user's name
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: getlistwatch
apiGroup: rbac.authorization.k8s.io
You can apply these objects using the kubectl apply -f
command. For our examples, it would look like this:
kubectl apply -f getlistwatch.yaml
kubectl apply -f getlistwatch-bind.yaml
In these examples, we created a Role
named getlistwatch
, which allows getting, listing, and watching pod resources in the cluster. We then created a RoleBinding
named getlistwatch-bind
, which links this role to a specific user. After applying these files, the user will be granted permission to perform the specified operations on pod resources in the cluster.
It's worth noting that this user will not be able to perform any other actions in the cluster unless other roles are assigned to them, which should be checked separately.
There are three primary methods:
Basic authentication with configuration passed through the API.
Client certificate authentication, certified by the Kubernetes certification authority.
Authentication through Bearer-token or JWT.
The first method is rarely used today, so let's move on to the second.
In Kubernetes certificate authentication, each user or service receives its own certificate, which is used for authentication when attempting to access the Kubernetes cluster. The process usually involves the following steps:
Generating Certificates: The cluster administrator generates certificates for each user/service using a certificate authority or certificate creation tools. For example, RSA private keys can be created, followed by certificate signing requests sent to the certification authority.
Configuring Authentication: The administrator adds the generated certificates to the Kubernetes configuration, specifying which users/services have access to which resources in the cluster. This is done through kubeconfig, generated for each user/service, with the signed certificate added.
Creating Roles: At this stage, a Role is created and then linked to the user/service through a RoleBinding
(as shown in the code above).
Now, when attempting to access the cluster, the user/service must provide their certificate for verification. Kubernetes uses this certificate to authenticate and determine access permissions. If the certificate is successfully verified, the user/service is granted the appropriate permissions to perform operations in the cluster. There are also automation tools for this process, such as bash scripts or Ansible.
This method allows you to create a set of standard roles but introduces the challenge of managing access for numerous users/services and the complexity of certificate revocation. Therefore, in many cases, it's better and safer to use third-party authentication services like DEX and Keycloak, which provide secure authentication via OIDC (OpenID Connect).
One of the key advantages of DEX is its ease of use. However, setting up DEX requires the creation of certificates for both DEX and Gangway, which work in tandem as they communicate through TLS. When deployed within a Kubernetes cluster, entities such as dex.example.com and gangway.example.com will be created, for which certificates are needed. Don't forget to monitor certificate expiration dates programmatically or through cert-manager, as they are time-limited. Cert-manager can even automatically renew them. DEX is installed via Helm Chart; all its settings are contained in a ConfigMap.
One of Keycloak's advantages is that it has its own web interface, unlike DEX. It also supports a larger number of backends and can work with more than just Kubernetes. Additionally, Keycloak is ideal for managing user access to multiple applications, as it's designed to work as an SSO (Single Sign-On) server. However, this comes at the cost of a higher learning curve, as even experienced developers unfamiliar with Keycloak will need to study its extensive documentation first.
After the user opens the Gangway form, they will be redirected to the DEX/Keycloak authorization page.
The application checks the correctness of the entered data.
If the data is correct, DEX/Keycloak returns authentication tokens to Gangway. This process is automated and invisible to the user.
The user can then download the generated kubeconfig with access settings based on the received data.
Kubeconfig is needed to send requests directly to the Kubernetes server, where DEX/Keycloak checks the validity of the tokens.
To conclude, here are some factors to help you choose between Kubernetes certificates, DEX, and Keycloak:
Choose certificate authentication if the project is small and has few users, as tracking them in this method can be inconvenient.
Choose DEX if you need access settings only for the cluster, without additional backends.
Choose Keycloak if you need to configure access for multiple unrelated applications for individual users.