This document describes how to harden the security of your Google Distributed Cloud clusters.
Secure your containers using SELinux
You can secure your containers by enabling SELinux, which is supported for Red Hat Enterprise Linux (RHEL) and CentOS. If your host machines are running RHEL or CentOS and you want to enable SELinux for your cluster, you must enable SELinux in all of your host machines. See secure your containers using SELinux for details.
Don't run containers as root
user
By default, processes in containers execute as root
. This poses a potential
security problem, because if a process breaks out of the container, that process
runs as root on the host machine. It's therefore advisable to run all your
workloads as a non-root user.
The following sections describe two ways of running containers as a non-root user.
Method #1: add USER
instruction in Dockerfile
This method uses a Dockerfile
to ensure that containers don't run as a root
user. In a Dockerfile
, you can specify which user the process inside a container
should be run as. The following snippet from a Dockerfile
shows how to do this:
....
#Add a user with userid 8877 and name nonroot
RUN useradd −u 8877 nonroot
#Run Container as nonroot
USER nonroot
....
In this example, the Linux command useradd -u
creates a user called nonroot
inside the container. This user has a user ID (UID) of 8877
.
The next line in the Dockerfile
runs the command USER nonroot
. This command
specifies that from this point on in the image, commands are run as the user
nonroot
.
Grant permissions to UID 8877
so that the container processes can execute
properly for nonroot
.
Method #2: add securityContext fields in Kubernetes manifest file
This method uses a Kubernetes manifest file to ensure that containers don't run
as a root
user. Security settings are specified for a Pod, and those security
settings are in turn applied to all containers within the Pod.
The following example shows an excerpt of a manifest file for a given Pod:
apiVersion: v1
kind: Pod
metadata:
name: name-of-pod
spec:
securityContext:
runAsUser: 8877
runAsGroup: 8877
....
The runAsUser
field specifies that for any containers in the Pod, all
processes run with user ID 8877
. The runAsGroup
field specifies that these
processes have a primary group ID (GID) of 8877
. Remember to grant the
necessary and sufficient permissions to UID 8877
so that the container
processes can execute properly.
This ensures that processes within a container are run as UID 8877
, which has
fewer privileges than root.
System containers in Google Distributed Cloud use UIDs and GIDs in the range 2000-4999. Therefore, use UIDs and GIDs that aren't in this reserved range when you assign permissions to user workloads.
Restrict the ability for workloads to self-modify
Certain Kubernetes workloads, especially system workloads, have permission to self-modify. For example, some workloads vertically autoscale themselves. While convenient, this can allow an attacker who has already compromised a node to escalate further in the cluster. For example, an attacker could have a workload on the node change itself to run as a more privileged service account that exists in the same namespace.
Ideally, workloads should not be granted the permission to modify themselves in the first place. When self-modification is necessary, you can limit permissions by applying Gatekeeper or Policy Controller constraints, such as NoUpdateServiceAccount from the open source Gatekeeper library, which provides several useful security policies.
When you deploy policies, it is usually necessary to allow the controllers that
manage the cluster lifecycle to bypass the policies. This is necessary so that
the controllers can make changes to the cluster, such as applying cluster
upgrades. For example, if you deploy the NoUpdateServiceAccount
policy on
Google Distributed Cloud, you must set the following parameters in the Constraint
:
parameters:
allowedGroups:
- system:masters
allowedUsers: []
Maintenance
Monitoring security bulletins and upgrading your clusters are important security measures to take once your clusters are up and running.
Monitor security bulletins
The GKE Enterprise security team publishes security bulletins for high and critical severity vulnerabilities.
These bulletins follow a common Google Cloud vulnerability numbering
scheme and are linked from the main Google Cloud bulletins page and the
Google Distributed Cloud release notes. Use this XML feed to subscribe to security
bulletins for Google Distributed Cloud and related products:
https://cloud.google.com/feeds/anthos-gke-security-bulletins.xml
When customer action is required to address these high and critical vulnerabilities, Google contacts customers by email. In addition, Google might also contact customers with support contracts through support channels.
For more information about how Google manages security vulnerabilities and patches for GKE and GKE Enterprise, see Security patching.
Upgrade clusters
Kubernetes regularly introduces new security features and provides security patches. Google Distributed Cloud releases incorporate Kubernetes security enhancements that address security vulnerabilities that may affect your clusters.
You are responsible for keeping your GKE clusters up to date. For each release, review the release notes. To minimize security risks to your GKE clusters, plan to update to new patch releases every month and minor versions every three months.
One of the many advantages of upgrading a cluster is that it automatically
refreshes the cluster's kubeconfig file. The kubeconfig file authenticates a
user to a cluster. The kubeconfig file is added to your cluster directory when
you create a cluster with bmctl
. The default name and path is
bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig
.
When you upgrade a cluster, that cluster's kubeconfig file is automatically
renewed. Otherwise, the kubeconfig file expires one year after it was created.
For information about how to upgrade your clusters, see upgrade your clusters.