Kubernetes is an open-source container orchestration platform designed to run distributed services and applications at scale. A K8s or Kubernetes cluster contains several components that are a part of either the Kubernetes control plane or Kubernetes nodes. Over the years, Kubernetes has emerged as the hot topic in the DevOps space and is among the most wanted platforms for developers. As they are widely adopted to support varied use cases, cluster security is becoming a big concern for many organizations. The rising adoption of the platform has resulted in attackers targeting and abusing different parts of the cluster. Since Kubernetes is not immune to potential threats, such as misconfiguration, we need to take robust measures to improve overall cluster security.
$4.3 billion: The projected market for application container technologies in 2022, according to 451 Research. That’s more than double the $2.126 billion the firm has predicted will be spent in 2019, and it also represents a 30% compound annual growth rate from 2017 through 2022.
It is vital to keep your Kubernetes control plane and node components secure, especially when you deploy it for compliance or business-related reasons.
With that said, in this post, we will discuss some of the critical steps to secure your Kubernetes deployments.
Let’s jump right into it.
Fundamentals of a Kubernetes Design
There are three primary aspects to a robust Kubernetes network policy. That is, a Kubernetes cluster should be:
- Extendable: The cluster should be customizable and should not exclusively favor a single provider.
- Easy to Use: Design the cluster to be operable with a few simple commands.
- Secure: The cluster should follow the latest pod security policies and best practices.
Understanding the Components of a Kubernetes Cluster and How to Secure Them
As said, you can categorize Kubernetes clusters into two parts – the control plane and the nodes, or the computing machines.
The control plane is responsible for controlling the cluster. Acting as the nerve center of a Kubernetes cluster, the control plane manages the cluster state and configuration data. The control plane components ensure that your containers run in adequate numbers along with all the necessary resources.
However, the control plane is highly susceptible to abuse from attackers because it is not easy to configure. While many businesses configure their clusters to run a certain way, some loopholes allow attackers to compromise the control plane.
To secure your Kubernetes control plane, check the following components and make sure you perform the listed operations.
etcd
Configuring information and data about the cluster’s state lives in etcd
. It is a key-value store database designed to be fault-tolerant and distributed to be the source of truth about your cluster. To check if etcd
is secure, type the following command:
ps -ef | grep etcd
Then, modify the etcd pod specification file located at /etc/kubernetes/manifests/etcd.yaml
Finally, run the following command to check if encryption is already enabled:
–encryption-provider-config
kube-controller-manager
The kube-controller-manager
is responsible for running the cluster and controlling its functions. It ensures that the correct number of pods are running at all times. In case a pod goes down, the controller immediately notices it and takes the necessary action.
To check if your kube-controller-manager
is configured securely, first run the following command on your master node:
ps -ef | grep kube-controller-manager
In the output, check and modify the following arguments:
- Set
--use-service-account-credentials argument
totrue
. This setting, along with RBAC, ensures that the control loops run with the minimum required permissions. - Set
--service-account-private-key-file argument
such that it uses a separate public/private key pair for signing service account tokens. - Check if the
--root-ca-file
argument exists. Set--root-ca-file
to a cert file containing the root cert for the API Server’s serving cert, which will allow pods to verify the API Server’s serving cert before making a connection. - Set
RotateKubeletServerCertificate
totrue
. Ensure the argument applies when the kubelets get their certificates from the API Server only. - Set
--address
to127.0.0.1
, ensuring that the controller manager service is not bound to non-loopback insecure addresses.
kube-scheduler
The kube-scheduler
takes care of the cluster’s health. It determines whether your cluster needs new containers and provisions them accordingly, thereby ensuring that you meet your pod’s resource needs at all times.
To check if kube-scheduler
is configured securely, run the following command on your master node:
ps -ef | grep kube-scheduler
In the output, check and modify the following arguments wherever necessary:
- Set
--profiling
tofalse
to reduce the attack surface. - Set
--address
to127.0.0.1
, ensuring that the controller manager service is not bound to non-loopback insecure addresses.
kube-apiserver
The kube-apiserver
is the front-end of the control plane that handles external and internal requests. The kube-apiserver
determines the validates requests and sends them for processing. Try hitting the kube-apiserver
from an external IP to see if it’s secure. If the kube-apiserver
responds, it means other machines can also do the same unless you have restricted the API server to your IP. To ensure that your kube-apiserver
is not public and exposed to the world, limit access to your Kubernetes cluster on GKE through the master authorized network settings by running the following commands:
gcloud container clusters create --enable-master-authorized-networks --master-authorized-networks=CIDR
ps -ef | grep kube-apiserver
How to configure RBAC in your Kubernetes cluster?
Configuring RBAC correctly goes a long way in keeping your cluster from being compromised. With RBAC, you can restrict pods and users to the CRUD operations they can perform within a cluster. It allows for a granular view of what cluster components a user or pod can access and can help limit the attack surface of your cluster.
You can enable RBAC in your Kubernetes cluster via the kube-apiserver
at startup with the flag: –authorization-mode=RBA
C
A malicious user can easily disable RBAC. To see if RBAC is disabled, run this command:
ps -ef | grep kube-apiserver
Another way to ensure RBAC is securely configured is to manually impersonate users or user groups via user impersonation. User impersonation allows admins to debug and validate an authorization policy by temporarily simulating another user. It is also good practice to document unrecognized users and track their activity within the cluster.
Securing node components
If the control plane is considered the nerve center, the node components are the Kubernetes cluster’s muscle. These nodes are responsible for running and controlling all the containers and pods in a cluster. While there is no necessity to have worker nodes, it’s best to have at least one worker node running and controlling all the containers and pods on the same node as the control plane make things complex.
The primary components of a node are the container runtime engine, the kubelet, and kube-proxy
.
- The container runtime engine runs containers in your cluster.
- The
kubelet
is a tiny agent in charge of making sure your nodes and containers are running. - The
kube-proxy
facilitates Kubernetes networking services, handling network communications outside and inside the cluster.
To secure your node components, make sure you check these components for what’s listed below.
Container runtime engine
Each compute node in a Kubernetes cluster has a container runtime engine. Most Kubernetes applications use Docker as a container runtime engine, although Kubernetes supports other runtime engines such as containerd and CRI-O. Securely configuring your container runtime engine is down to following security best practices issues by the engine you use. Configuring your engine as advised by your provider makes sure that your Kubernetes containers are safe from attacks.
Kubelet
The kubelet is an agent that runs on each of your cluster’s nodes, ensuring that all containers are running. It is also in charge of making configuration changes whenever necessary. A misconfigured kubelet can open a backdoor for attackers to your cluster.
You can either use a kubelet configuration file or use arguments on the running kubelet executable to configure your kubelet. You can find your kubelet configuration file by running the following command and looking for the --config
argument:
ps -ef | grep kubelet | grep config
Next, run the following command on each node:
ps -ef | grep kubelet
In the output, check and modify the following arguments wherever necessary:
- Set
--anonymous-auth argument
tofalse
to disallow unauthenticated requests. - Set
--rotate-certificates
totrue
. If you’re using a kubelet configuration file, setRotateKubeletServerCertificate
totrue
. If you aren’t doing so already, ensure that your kubelets get their certificates from the API Server. - Set
--tls-cert-file
and--tls-private-key-file
appropriately. If you’re using a kubelet configuration file, settlsCertFile
andtlsPrivateKeyFile
appropriately so that all connections on the kubelets happen over TLS.
kube-proxy
kube-proxy
is a network proxy that runs on each node in your cluster, maintaining network rules on these nodes. It ensures that your nodes can communicate with internal and external resources as required and allowed.
Securing kube-proxy
is down to ensuring the security and integrity of its kubeconfig
file. To make sure your kube-proxy
file is secure, first find the kubeconfig
file in use by running:
ps -ef | grep kube-proxy
Check --kubeconfig
to find the kube-proxy
config file location and then run the following command on each worker node:
stat -c %a <kube-proxy config file>
From the output, ensure that permissions are set to 644 or stricter to help maintain the file’s integrity.
Next, run the following command on each worker node using the same kube-proxy
config file location:
stat -c %U:%G <kube-proxy config file>
In the output, set permissions to root:root
to prevent any unauthorized access to the file.
Final Words
Keeping your Kubernetes control plane and node components secure is finally down to following the basics. While configuring every single component in your cluster may seem daunting, doing so will ensure that you can safeguard your applications and deployments from unwanted threats and attacks. You can significantly reduce your attack surface and avoid common misconfigurations by following these configuration recommendations.
To know more about Kubernetes best practices, do read Kubernetes Best Practices published by O’Reilly Media. You can sign up and get free access to two full chapters of this book and learn more about building great applications on Kubernetes.