Kubernetes is a great tool for orchestrating containers. What it’s not so great at doing (at least not if you stick with the default Kubernetes configuration) is securing the Kubernetes environment.
That’s why it’s critical to take extra steps to secure a Kubernetes environment. These steps involve modifying default configurations in ways that can improve Kubernetes security, as well as enabling extra tools that make Kubernetes environments more secure.
In this article, we’ll walk through the basic steps you can take to make a Kubernetes environment more secure by taking advantage of the following:
Role-based authentication, authorization and admission
Pod security policy
Firewall and network security policy
Securing host machine
Logging and monitoring
Just to set clear expectations, I’ll note that we’re not discussing the security of your containers themselves; that is a separate topic. Nor should this article be read as a be-all, end-all guide to Kubernetes security. Instead, I will explain simple core steps that organizations should take to make Kubernetes more secure than it comes out-of-the-box.
Role-Based Authentication, Authorization and Admission (RBAC)
Ensuring control over who has access to a production system (and specifically what users have access to) is important to ensure a secure environment. RBAC defines which types of actions are permitted, depending on the user and their role.
RBAC policies are enabled by default in Kubernetes 1.6. With earlier versions, you have to enable them yourself by disabling anonymous authentications using the –anonymous-auth=false flag.
RBAC also allows administrators to set up Rules (a set of operations that can be carried out on a group of resources), Roles (rules applicable to within a single namespace in the cluster), Cluster Role (rules applicable to more than one namespace usually applicable to the entire cluster), Role Binding (used to bind resources to the created roles), and Cluster Role Binding (bind an entire cluster to a set of cluster roles.)
kubectl get clusterrolebinding and kubectl get rolebinding can be used to check the current set of binding a cluster is using.
Create a role –
kubectl create role read-logs -resource=pods
Setting Rules –
## Rules that allow user Read pod subject - apiGroups: ["logs"] resources: ["pods"] verbs: ["get", "list", "watch"] ## Rules that allow user Read and write pod subject - apiGroups: ["logs", "apps"] resources: ["echo-pod"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
If an unauthorized user or system gets access to your Kubernetes API server, the user can change system settings, manipulate, or take control of the entire cluster. RBAC generally allows cluster-wide permissions, and it should generally be avoided in favor of namespace-specific permissions. It is much more secure to grant access only as needed.
Pod Security Policy
Kubernetes pod security policies are a set of guidelines that define how pods in a cluster should interact, and also ensure that only authorized pods run in the cluster. In a multi-environment like a typical cluster, running different applications on the cluster creates the risk of one compromised application damaging or affecting others. A policy to guide internal communication helps to:
- Prevent pods from running with root privileges
- Restrict containers in pods from running as the root user
- Prevent pods from accessing host ports
- Restrict volume type access
- What network traffic is allowed for a cluster
- Network segmentations and guidelines
- Encryption policies traffic with TLS.
- If possible, be sure you are running a security-hardening framework, such as SELinux.
- Use role-based access control to set least-necessary privileges for access to the Kubernetes environment and any resources it uses.
- Minimize network connections. (Keep in mind that this means avoiding not just unnecessary public-facing connections, but also internal ones, which could be abused by a malicious service.)
kind: PodSecurityPolicy spec: privileged: false defaultAllowPrivilegeEscalation: false requiredDropCapabilities: - ALL runAsUser: rule: 'MustRunAsNonRoot' hostNetwork: false hostIPC: false hostPID: false fsGroup: rule: 'MustRunAs' hostPorts: - min: 1 max: 65535 readOnlyRootFilesystem: false
Firewalls and Network Policy
Kubernetes by default exposes a few ports; therefore, such ports should be restricted from public (anonymous) access (e.g. 6443/TCS 4149/TCP, etc). Unused ports should not be exposed, and where non-authenticated services are used, restrict access to whitelisted sources.
Network policies help to specify:
A well-crafted policy can stop attackers from running malicious programs inside the pods. Restricting the addresses, ports, and pods that can be contacted also restricts the available ports for attackers to explore.
You can also closely specify which pod in a cluster speaks to which at a specified port, of which any compromising request will be rejected, as shown below.
kind: NetworkPolicy spec: allowIncoming: from: - pods: resource: frontend toPorts: - port: 80 protocol: TCP podSelector: resource: Python-NLP
Securing the Host Machine
Obviously, your Kubernetes environment is only as secure as the server that hosts it.
Kubernetes host servers can come in many forms. You might be using simple bare-metal or virtual servers to host your cluster. Or you might be running Kubernetes using a cloud service. Given the different architectures available, there is no one-size-fits-all approach for Kubernetes host security, and in some cases (specifically, when you are running your own infrastructure), you have a lot more control over security settings on the host than in others (such as in the cloud, where you are more or less stuck with whatever host settings the cloud provider gives you).
However, as a general best practice, consider the following pointers for maximizing Kubernetes host security:
Logging and Monitoring
Logging and monitoring are important for many reasons, and security is chief among them. Collecting monitoring metrics from your Kubernetes environment can give you early warning about possible breaches. For example, if you notice an unusual uptick in network activity, or a sudden change in the number of container instances you are running, that could signal an intrusion or an intrusion attempt.
Likewise, log data serves as an important source of insight for investigating security incidents after they occur. In addition, logs can periodically help you to assess the overall security of your Kubernetes environment in order to make improvements. It can alert you to things like ports that unauthorized parties are routinely trying to access, or help you find data volumes that are no longer being used, and should therefore be shut down in order to reduce your attack surface.
Kubernetes is not designed to be a security tool. Keeping it secure requires you to take extra steps on multiple fronts — from locking down access control, to enforcing pod security policies, to hardening the host server and leveraging monitoring and log data. The precise approach that you take to each of these tasks will vary depending on your specific architecture, but at a basic level, the essential thing is to remember that you need to take extra steps to secure Kubernetes, because Kubernetes doesn’t secure itself.