保护集群

本文档涵盖了与保护集群免受意外或恶意访问相关的主题,并提供了关于整体安全性的建议。

开始之前

  • 你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与你的集群通信。建议在至少有两个节点的集群上运行本教程,且这些节点不能作为控制平面主机。如果你还没有集群,可以通过 minikube 创建一个,或者使用以下 Kubernetes 演练场之一。

    要检查版本,请输入 kubectl version

控制对 Kubernetes API 的访问

由于 Kubernetes 完全由 API 驱动,控制和限制谁可以访问集群以及他们被允许执行哪些操作是第一道防线。

对所有 API 流量使用传输层安全协议 (TLS)

Kubernetes 默认要求集群中的所有 API 通信均通过 TLS 加密。大多数安装方法都允许创建必要的证书并分发给集群组件。请注意,某些组件和安装方法可能会通过 HTTP 开启本地端口,管理员应熟悉每个组件的设置,以识别潜在的未加密流量。

API 认证

在安装集群时,请为 API 服务器选择一种符合通用访问模式的认证机制。例如,小型、单用户集群可能希望使用简单的证书或静态 Bearer 令牌方法;大型集群可能希望集成现有的 OIDC 或 LDAP 服务器,以便将用户划分为不同的组。

所有 API 客户端都必须经过认证,即使是属于基础设施的客户端(如节点、代理、调度器和卷插件)也不例外。这些客户端通常是服务账户 (Service Accounts) 或使用 x509 客户端证书,它们在集群启动时自动创建,或是作为集群安装的一部分进行设置。

有关更多信息,请查阅认证参考文档

API 授权

一旦通过认证,每个 API 调用也必须通过授权检查。Kubernetes 提供了一个集成的基于角色的访问控制 (RBAC) 组件,将传入的用户或组与绑定到角色的权限集进行匹配。这些权限结合了动词(get, create, delete)与资源(pods, services, nodes),并且可以是命名空间范围的,也可以是集群范围的。集群提供了一组现成的角色,根据客户端希望执行的操作,这些角色提供了合理的默认职责分离。建议您将 NodeRBAC 授权器结合使用,并配合 NodeRestriction 准入插件。

与认证一样,简单且广泛的角色可能适用于较小的集群;但随着越来越多的用户与集群交互,可能有必要将团队划分到不同的命名空间 (namespaces) 中,并分配更受限制的角色。

在授权方面,了解对一个对象的更新如何导致其他地方的操作非常重要。例如,用户可能无法直接创建 Pod,但允许他们创建 Deployment(这会代表他们创建 Pod)将让他们间接创建这些 Pod。同样,从 API 中删除一个节点会导致调度到该节点的 Pod 被终止,并在其他节点上重新创建。现有的默认角色在灵活性和常见用例之间取得了平衡,但应仔细审查更受限制的角色,以防止意外的权限提升。如果现有的角色无法满足您的需求,您可以根据特定的用例自定义角色。

有关更多信息,请查阅授权参考部分

如果您的集群使用动态资源分配 (DRA),请审查 DRA 合成子资源授权(resourceclaims/bindingresourceclaims/driver),并仅向每个组件授予所需的最低权限动词。详细信息请参阅加固指南 - 动态资源分配以及在集群中加固动态资源分配

控制对 Kubelet 的访问

Kubelet 暴露了 HTTPS 端点,这些端点允许对节点和容器进行强大的控制。默认情况下,Kubelet 允许对此 API 进行未经认证的访问。

生产集群应启用 Kubelet 认证和授权。

有关更多信息,请查阅 Kubelet 认证/授权参考

运行时控制工作负载或用户的能力

Kubernetes 中的授权是有意设计为高层级的,专注于对资源的粗粒度操作。更强大的控制方式以策略 (Policies) 的形式存在,用于限制这些对象在集群、自身以及其他资源上的行为方式,具体取决于用例。

限制集群上的资源使用

资源配额 (Resource quota) 限制授予命名空间的资源数量或容量。这通常用于限制命名空间可以分配的 CPU、内存或持久磁盘总量,也可以控制每个命名空间中可以存在的 Pod、服务或卷的数量。

限制范围 (Limit ranges) 限制上述某些资源的最大或最小值,以防止用户请求不合理的高或低值(对于像内存这样通常被预留的资源),或者在未指定限制时提供默认限制。

控制容器运行时的权限

Pod 定义包含一个安全上下文 (security context),允许它请求以节点上的特定 Linux 用户身份运行(例如 root)、运行特权容器或访问主机网络,以及其他原本可能使其在宿主机上不受限制运行的控制。

您可以配置 Pod 安全准入,以在命名空间中强制使用特定的 Pod 安全标准,或检测违规行为。

通常,大多数应用程序工作负载只需要对主机资源的有限访问权限,以便它们可以在不需要访问主机信息的情况下作为 root 进程(uid 0)成功运行。然而,考虑到 root 用户拥有的权限,您应该编写应用程序容器以非 root 用户身份运行。同样,希望防止客户端应用程序逃逸容器的管理员应应用基准 (Baseline)受限 (Restricted) Pod 安全标准。

防止容器加载不需要的内核模块

Linux 内核会在某些情况下(例如连接硬件或挂载文件系统时)自动从磁盘加载内核模块。对 Kubernetes 而言,特别值得关注的是,即便是非特权进程也可以通过简单地创建特定类型的套接字,触发某些与网络协议相关的内核模块加载。这可能允许攻击者利用管理员认为未使用的内核模块中的安全漏洞。

为防止特定模块被自动加载,您可以从节点中卸载它们,或添加规则来阻止它们。在大多数 Linux 发行版上,可以通过创建类似 /etc/modprobe.d/kubernetes-blacklist.conf 的文件来完成,内容如下:

# DCCP is unlikely to be needed, has had multiple serious
# vulnerabilities, and is not well-maintained.
blacklist dccp

# SCTP is not used in most Kubernetes clusters, and has also had
# vulnerabilities in the past.
blacklist sctp

为了更通用地阻止模块加载,您可以使用 Linux 安全模块(如 SELinux)完全拒绝容器的 module_request 权限,从而在任何情况下都阻止内核为容器加载模块。(Pod 仍然能够使用已手动加载的模块,或由内核代表某些更高级权限的进程加载的模块。)

限制网络访问

命名空间的网络策略 (network policies) 允许应用程序作者限制其他命名空间中的哪些 Pod 可以访问其命名空间内的 Pod 和端口。目前,许多受支持的 Kubernetes 网络提供商都已经支持网络策略。

配额和限制范围还可用于控制用户是否可以请求 NodePort 或负载均衡服务。在许多集群中,这可以控制这些用户的应用程序在集群外部是否可见。

可能还存在基于插件或环境的额外保护措施,例如节点级防火墙、物理隔离集群节点以防止交叉干扰,或使用高级网络策略。

限制对云元数据 API 的访问

云平台(AWS、Azure、GCE 等)通常会在本地向实例暴露元数据服务。默认情况下,运行在实例上的 Pod 可以访问这些 API,其中可能包含该节点的云凭据,或 kubelet 凭据等供应数据。这些凭据可用于在集群内进行提升权限,或访问同一账户下的其他云服务。

在云平台上运行 Kubernetes 时,请限制实例凭据的权限,使用网络策略限制 Pod 对元数据 API 的访问,并避免使用供应数据来传递 Secret。

控制 Pod 可以访问的节点

默认情况下,没有关于哪些节点可以运行 Pod 的限制。Kubernetes 提供了一套丰富的策略来控制 Pod 在节点上的放置,以及最终用户可用的基于污点的 Pod 放置和驱逐。对于许多集群,使用这些策略来分离工作负载是一种作者可以采用或通过工具强制执行的惯例。

作为管理员,可以使用 Beta 版本的准入插件 PodNodeSelector 来强制命名空间内的 Pod 默认或要求使用特定的节点选择器。如果最终用户无法更改命名空间,这将能极大限制特定工作负载中所有 Pod 的放置位置。

保护集群组件免受威胁

本节描述了一些保护集群免受威胁的通用模式。

限制对 etcd 的访问

对 API 的 etcd 后端的写权限相当于获得了整个集群的 root 权限,而读权限也可用于快速提升权限。管理员应始终在 API 服务器到其 etcd 服务器之间使用强凭据,例如通过 TLS 客户端证书进行双向认证。通常建议将 etcd 服务器隔离在仅允许 API 服务器访问的防火墙之后。

注意

允许集群内的其他组件以读或写权限访问主 etcd 实例的完整键空间,等同于授予 cluster-admin 访问权限。强烈建议为非主组件使用独立的 etcd 实例,或使用 etcd ACL 来限制对部分键空间的读写访问。

启用审计日志

审计日志记录器 (audit logger) 是一项 Beta 功能,用于记录 API 执行的操作,以便在发生威胁时进行事后分析。建议启用审计日志记录,并将审计文件归档在安全的服务器上。

限制对 Alpha 或 Beta 功能的访问

Alpha 和 Beta 版本的 Kubernetes 功能正处于活跃开发中,可能存在限制或漏洞,导致安全隐患。请务必评估 Alpha 或 Beta 功能可能带来的价值与其对您安全态势可能构成的风险。如有疑问,请禁用您不使用的功能。

频繁轮换基础设施凭据

Secret 或凭据的生命周期越短,攻击者利用该凭据的可能性就越低。设置较短的证书生命周期并实现自动轮换。使用能够控制已签发令牌有效期的认证提供程序,并尽可能使用较短的有效期。如果您在外部集成中使用服务账户令牌,请计划频繁轮换这些令牌。例如,引导阶段完成后,应撤销用于设置节点的引导令牌或移除其授权。

在启用第三方集成前进行审查

许多 Kubernetes 的第三方集成可能会改变集群的安全配置文件。在启用集成时,务必在授予权限前审查扩展请求的权限。例如,许多安全集成可能会请求查看集群上所有 Secret 的权限,这实际上使该组件成为了集群管理员。如有疑问,请尽量将集成限制在单个命名空间内运行。

如果创建 Pod 的组件能够在 kube-system 等命名空间内执行操作,那么它们也可能具有意想不到的高权限,因为这些 Pod 可以访问服务账户的 Secret,或者在这些服务账户被授予访问宽松的 PodSecurityPolicies 权限时,以提升的权限运行。

如果您使用 Pod 安全准入 并允许任何组件在允许特权 Pod 的命名空间中创建 Pod,这些 Pod 可能能够逃逸容器并利用这种扩大的访问权限来提升特权。

您不应允许不受信任的组件在任何系统命名空间(名称以 kube- 开头的命名空间)中创建 Pod,也不应允许其在任何允许权限提升的命名空间中创建 Pod。

对静态 Secret 进行加密

通常情况下,etcd 数据库将包含可通过 Kubernetes API 访问的任何信息,这可能让攻击者对您的集群状态拥有相当大的可见性。请务必使用经过充分审查的备份和加密解决方案来加密您的备份,并尽可能考虑使用全盘加密。

Kubernetes 支持对 Kubernetes API 中的信息进行可选的静态加密 (encryption at rest)。这确保了当 Kubernetes 存储对象数据(例如 SecretConfigMap 对象)时,API 服务器会写入对象的加密表示。这意味着即使是拥有 etcd 备份数据访问权限的人,也无法查看这些对象的内容。在 Kubernetes 1.36 中,您还可以加密自定义资源;作为 v1.26 版本发布的一部分,Kubernetes 增加了对 CustomResourceDefinitions 定义的扩展 API 的静态加密功能。

接收安全更新警报并报告漏洞

加入 kubernetes-announce 小组以接收关于安全公告的电子邮件。有关如何报告漏洞的更多信息,请参阅安全报告页面。

接下来


最后修改于 2026 年 4 月 7 日下午 4:30 PST:根据 tim 的建议进行更新 (8df4df1ffa)