Kubernetes cluster hardening is about securing your environment by protecting nodes, pods, APIs, and network settings. Use tools like RBAC, encryption, and vulnerability scans to reduce risks, maintain system integrity, and stay compliant. It’s like giving your cluster a security upgrade to keep it safe and reliable.
In this article, we’ll cover:
1- Using Role-Based Access Control (RBAC) to minimize exposure.
2- Exercising caution with service accounts—disable defaults and limit permissions for new ones.
3- Restricting access to the Kubernetes API.
4- Upgrading Kubernetes regularly to avoid vulnerabilities.
Using Role-Based Access Control (RBAC)
By default, all workloads in your Kubernetes cluster have full access—meaning they can list, create, and delete workloads and other resources. If a single pod gets compromised, an attacker could potentially take down your entire cluster. This is where RBAC (Role-Based Access Control) comes to the rescue. With RBAC, you can restrict access for workloads, granting only the permissions they absolutely need. This follows the principle of least privilege, minimizing the risk of damage if something goes wrong.
To implement RBAC, there are four key resources:
1- Role: A namespaced resource that defines permissions within a specific namespace.
2- ClusterRole: A non-namespaced resource that defines permissions across the entire cluster or within specific namespaces.
3- RoleBinding: Links a Role or ClusterRole to users or workloads within a specific namespace.
4- ClusterRoleBinding: Links a ClusterRole to users or workloads across the entire cluster.
Here’s the key difference:
A Role can only be used with a RoleBinding and applies to a single namespace.
A ClusterRole can be used with either a RoleBinding (applying to a single namespace) or a ClusterRoleBinding (applying to the entire cluster).
For example, if you use a ClusterRole with a ClusterRoleBinding, the workload will have permissions across all namespaces. But if you use it with a RoleBinding, the permissions will only apply to the namespace where the binding is created.
Here’s an example to help clarify how this works:
Let’s say you want to create a Role that allows a workload to read pods and secrets in the default namespace. You can define the Role like this:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" refers to the core API group
resources: ["pods", "secrets"] # Specifies the resources (pods and secrets)
verbs: ["get", "watch", "list"] # Defines the allowed actions (read-only access)
In this example:
The Role is scoped to the default
namespace.
It grants get
, watch
, and list
permissions on pods
and secrets
.
This ensures the workload can only read these resources—nothing more.
To make this Role effective, you’d then bind it to a user, group, or service account using a RoleBinding. This way, you’re enforcing the principle of least privilege, giving the workload only the access it truly needs.
Exercise caution when using service accounts
Service accounts in Kubernetes are designed to give workloads an identity. However, by default, if you don’t set up RBAC (Role-Based Access Control), workloads will automatically mount the default service account, which often has full permissions across the cluster. This is a major security risk—if a pod is compromised, an attacker could gain unrestricted access to your entire cluster.
To prevent this, you should:
1- Disable automounting of the default service account for pods that don’t need it.
2- Create dedicated service accounts for your workloads.
3- Bind these service accounts to Roles or ClusterRoles with only the permissions they actually need.
By following these steps, you can enforce the principle of least privilege and significantly reduce the risk of unauthorized access.
Restrict access to the Kubernetes API.
Restricting access to your Kubernetes API is absolutely critical. Making it publicly accessible is like leaving your front door wide open—attackers will constantly probe for vulnerabilities to exploit and potentially take control of your cluster. To protect it, there are several key strategies:
1- RBAC and Service Accounts: As mentioned earlier, use Role-Based Access Control (RBAC) and dedicated service accounts to enforce the principle of least privilege.
2- Strong Authentication Mechanisms: Implement robust authentication methods like client certificates or OIDC (OpenID Connect) to ensure only authorized users and workloads can access the API.
3- Network Restrictions: Limit the IPs that can communicate with the API server. Even better, move the API server to a private network and use a VPN with a bastion host for secure access.
4- Enable Logging: Turn on audit logs to monitor API activity. This helps you detect and respond to unauthorized access attempts or suspicious behavior.
By combining these measures, you can significantly reduce the attack surface and keep your Kubernetes cluster secure.
Upgrading Kubernetes
Upgrading Kubernetes is a cornerstone of maintaining a secure cluster. Each new version delivers critical security patches that protect against known vulnerabilities and emerging threats, reducing the risk of breaches. By staying current, you ensure that deprecated APIs and weak configurations are replaced with stronger, more secure alternatives. Regular upgrades also align your cluster with the latest security best practices, such as improved RBAC policies and enhanced encryption. Falling behind on updates leaves your cluster exposed to attacks and compliance gaps. In short, upgrading Kubernetes isn’t just a maintenance task—it’s a vital defense mechanism for safeguarding your infrastructure.