强化集群安全性

本文档介绍如何强化 GKE on Bare Metal 集群的安全性。

使用 SELinux 保护您的容器

您可以启用 Red Haat Enterprise Linux (RHEL) 支持的 SELinux 来保护容器。如果您的主机运行的是 RHEL,并且您想要为集群启用 SELinux,则必须在所有主机中启用 SELinux。如需了解详情,请参阅使用 SELinux 保护容器

使用 seccomp 限制容器

GKE on Bare Metal 1.11 版及更高版本提供安全计算模式 (seccomp)。运行具有 seccomp 配置文件的容器可提高集群的安全性,因为它会限制允许容器对内核进行的系统调用。这样可以降低内核漏洞被利用的可能性。

默认的 seccomp 配置文件包含容器可以进行的系统调用列表。不允许列表中的任何系统调用。在 GKE on Bare Metal 的 1.11 版中,seccomp 默认处于启用状态。这意味着所有系统容器和客户工作负载都使用容器运行时的默认 seccomp 配置文件运行。即使是未在配置文件中指定 seccomp 配置文件的容器和工作负载也受 seccomp 限制的约束。

如何在整个集群或特定工作负载上停用 seccomp

您只能在集群创建或集群升级期间停用 seccompbmctl update 不能用于停用此功能。如果要在集群内停用 seccomp,请将以下 clusterSecurity 部分添加到集群的配置文件中:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: example
  namespace: cluster-example
spec:
...
  clusterSecurity:
    enableSeccomp: false
...

万一您的某些工作负载需要执行 seccomp 默认阻止的系统调用,您不必对整个集群停用 seccomp。您可以改为选择在 unconfined mode 中运行的特定工作负载。在 unconfined mode 中运行工作负载有助于释放工作负载,使其不受 seccomp 配置文件对集群其余部分的限制。

如需在 unconfined mode 中运行容器,请将以下 securityContext 部分添加到 Pod 清单:

apiVersion: v1
kind: Pod
....
spec:
  securityContext:
    seccompProfile:
      type: Unconfined
....

不要以 root 用户身份运行容器

默认情况下,容器中的进程以 root 身份执行。这会带来潜在的安全问题,因为如果某个进程脱离容器,该进程将在宿主机上作为 root 运行。因此,建议以非根用户身份运行所有工作负载。

以下部分介绍了以非根用户身份运行容器的两种方式。

方法 1:在 Dockerfile 中添加 USER 指令

此方法使用 Dockerfile 来确保容器不会以 root 用户身份运行。在 Dockerfile 中,您可以指定容器中的进程应以哪个用户的身份运行。Dockerfile 的以下代码段展示了如何执行此操作:

....

#Add a user with userid 8877 and name nonroot
RUN useradd −u 8877 nonroot

#Run Container as nonroot
USER nonroot
....

在此示例中,Linux 命令 useradd -u 在容器内创建名为 nonroot 的用户。此用户的用户 ID (UID) 为 8877

Dockerfile 中的下一行运行 USER nonroot 命令。此命令指定从映像的时间点开始,命令以用户 nonroot 的身份运行。

向 UID 8877 授予权限,以便容器进程可以为 nonroot 正确执行。

方法 2:在 Kubernetes 清单文件中添加 securityContext 字段

此方法使用 Kubernetes 清单文件来确保容器不会以 root 用户身份运行。系统会为 Pod 指定安全设置,并且这些安全设置会反过来应用于 Pod 中的所有容器。

以下示例展示了给定 Pod 的清单文件摘录:

apiVersion: v1
kind: Pod
metadata:
  name: name-of-pod
spec:
  securityContext:
    runAsUser: 8877
    runAsGroup: 8877
....

runAsUser 字段指定对于 Pod 中的任何容器,所有进程均使用用户 ID 8877 运行。runAsGroup 字段指定这些进程具有主要组 ID (GID) 8877。请记得向 UID 8877 授予必要且足够的权限,以便容器进程能够正常执行。

这可确保容器内的进程以 UID 8877 的身份运行,该 UID 比根用户具有更少的特权。

GKE on Bare Metal 中的系统容器有助于安装和管理集群。这些容器使用的 UID 和 GID 可以通过集群规范中的 startUIDRangeRootlessContainers 字段进行控制。startUIDRangeRootlessContainers 是可选字段,如果未指定,则值为 2000startUIDRangeRootlessContainers 允许的值为 1000-57000startUIDRangeRootlessContainers 值只能在升级期间更改。系统容器使用 startUIDRangeRootlessContainersstartUIDRangeRootlessContainers + 2999 范围内的 UID 和 GID。

以下示例展示了集群资源的清单文件摘录:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: name-of-cluster
spec:
 clusterSecurity:
    startUIDRangeRootlessContainers: 5000
...

选择 startUIDRangeRootlessContainers 的值,这样系统容器使用的 UID 和 GID 空间就不会与分配给用户工作负载的 UID 和 GID 空间重叠。

如何停用无根模式

从 GKE on Bare Metal 版本 1.10 开始,默认情况下,Kubernetes 控制平面容器和系统容器以非根用户身份运行。GKE on Bare Metal 为这些用户分配 2000-4999 范围内的 UID 和 GID。但是,如果这些 UID 和 GID 已分配给在您的环境中运行的进程,则这种分配方式可能会导致问题。

从 GKE on Bare Metal 版本 1.11 开始,您可以在升级集群时停用无 root 模式。停用无根模式后,Kubernetes 控制平面容器和系统容器会以根用户身份运行。

如需停用无根模式,请执行以下步骤:

  1. 将以下 clusterSecurity 部分添加到集群的配置文件中:

    apiVersion: baremetal.cluster.gke.io/v1
    kind: Cluster
    metadata:
      name: example
      namespace: cluster-example
    spec:
    ...
      clusterSecurity:
        enableRootlessContainers: false
    ...
    
  2. 升级集群。如需了解详情,请参阅升级集群

限制工作负载自行修改的能力

某些 Kubernetes 工作负载(尤其是系统工作负载)有权执行自行修改。例如,某些工作负载会自行纵向自动扩缩。虽然很方便,但这会使得已入侵节点的攻击者能够在集群中进行进一步的操作。例如,攻击者可能会使节点上的工作负载自行更改,以将其作为在同一命名空间内具有更高权限的服务账号运行。

理想情况下,不应在一开始就授予工作负载修改自身的权限。如果确实需要自行修改,您可以通过应用 Gatekeeper 或 Policy Controller 限制条件来限制这些权限,例如您可以使用 Gatekeeper 开源库中提供的 NoUpdateServiceAccount,此外该库还提供了许多其他有用的安全政策。

部署政策时,通常需要允许管理集群生命周期的控制器绕过政策。这样控制器才能更改集群,例如应用集群升级。例如,如果您在 GKE on Bare Metal 上部署 NoUpdateServiceAccount 政策,则必须在 Constraint 中设置以下参数:

parameters:
  allowedGroups:
  - system:masters
  allowedUsers: []

停用 kubelet 只读端口

从 1.15.0 版开始,GKE on Bare Metal 默认停用端口 10255,即 kubelet 只读端口。任何配置为从这个不安全的 kubelet 端口 10255 读取数据的客户工作负载都应迁移使用安全的 kubelet 端口 10250。

只有使用 1.15.0 或更高版本创建的集群才会默认停用此端口。即使集群升级到 1.15.0 或更高版本后,使用版本低于 1.15.0 创建的集群仍可访问 kubelet 只读端口 10255

之所以进行此更改,是因为 kubelet 通过端口 10255 泄露了低敏感度信息,该端口未经过身份验证。包括在节点上运行的所有 Pod 的完整配置信息,这些信息可能被攻击者利用。它还会泄露指标和状态信息,这些信息可以提供业务敏感的数据洞见。

CIS Kubernetes 基准建议停用 kubelet 只读端口。

维护

监控安全公告并升级集群是集群启动并运行后要实施的重要安全措施。

监控安全公告

GKE 安全团队会针对严重级别为“高”和“严重”的漏洞发布安全公告

这些公告遵循常见的 Google Cloud 漏洞编号方案,并链接到 Google Cloud 主公告页面和 GKE on Bare Metal 版本说明。

使用此 XML Feed 订阅 GKE on Bare Metal 及相关产品的安全公告。 订阅

如果需要客户操作才能解决这些严重程度为高和严重的漏洞,Google 会通过电子邮件与客户联系。此外,Google 可能还会通过支持渠道就支持合同事宜联系客户。

如需详细了解 Google 如何管理 GKE 和 GKE Enterprise 的安全漏洞和补丁,请参阅安全修补

升级集群

Kubernetes 经常引入新的安全功能并提供安全补丁程序。GKE on Bare Metal 版本包含 Kubernetes 安全增强功能,可解决可能会影响集群的安全漏洞。

您负责确保 GKE on Bare Metal 集群处于最新状态。请查看各个版本的版本说明。 为了最大限度地降低集群的安全风险,请计划每月更新到新的补丁版本,每四个月更新一次次要版本。

升级集群的众多优势之一是会自动刷新集群 kubeconfig 文件。kubeconfig 文件会向集群验证用户身份。使用 bmctl 创建集群时,kubeconfig 文件会添加到集群目录。默认名称和路径为 bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig。在升级集群时,集群的 kubeconfig 文件会自动续订。否则,kubeconfig 文件会在创建一年后过期。

如需了解如何升级集群,请参阅升级集群

将 VPC Service Controls 与 Cloud Interconnect 或 Cloud VPN 搭配使用

Cloud Interconnect 提供低延迟、高可用性的连接,让您可以在本地裸机和 Google Cloud Virtual Private Cloud (VPC) 网络之间可靠地传输数据。如需详细了解 Cloud Interconnect,请参阅专用互连预配概览

Cloud VPN 通过 IPsec VPN 连接,将您的对等网络安全地连接到 Virtual Private Cloud (VPC) 网络。如需详细了解 Cloud VPN,请参阅 Cloud VPN 概览

VPC Service Controls 可与 Cloud Interconnect 或 Cloud VPN 配合工作,为您的集群提供额外的安全保障。VPC Service Controls 有助于降低数据渗漏的风险。使用 VPC Service Controls,您可以将项目添加到服务边界,从而防止资源和服务受到源自边界外部的请求的影响。如需详细了解服务边界,请参阅服务边界详情和配置

如需全面保护 GKE on Bare Metal,您需要使用受限 VIP 并将以下 API 添加到服务边界:

  • Artifact Registry API (artifactregistry.googleapis.com)
  • Resource Manager API (cloudresourcemanager.googleapis.com)
  • Compute Engine API (compute.googleapis.com)
  • Connect Gateway API (connectgateway.googleapis.com)
  • Google Container Registry API (containerregistry.googleapis.com)
  • GKE Connect API (gkeconnect.googleapis.com)
  • GKE Hub API (gkehub.googleapis.com)
  • GKE On-Prem API (gkeonprem.googleapis.com)
  • Identity and Access Management (IAM) API (iam.googleapis.com)
  • Cloud Logging API (logging.googleapis.com)
  • Cloud Monitoring API (monitoring.googleapis.com)
  • Config Monitoring for Ops API (opsconfigmonitoring.googleapis.com)
  • Service Control API (servicecontrol.googleapis.com)
  • Cloud Storage API (storage.googleapis.com)

当您使用 bmctl 创建或升级集群时,请使用 --skip-api-check 标志绕过调用 Service Usage API (serviceusage.googleapis.com)。VPC Service Controls 不支持 Service Usage API。