集群网络是 Kubernetes 的一个核心概念。容器、Pod、服务和外部服务之间的通信必须被考虑在内。默认情况下,很少有网络策略来隔离资源,防止集群被破坏时的横向移动或升级。资源隔离和加密是限制网络行为者在集群内转移和升级的有效方法。

关键点

  • 使用网络策略和防火墙来隔离资源。
  • 确保控制平面的安全。
  • 对流量和敏感数据(例如 Secret)进行静态加密。

命名空间

Kubernetes 命名空间是在同一集群内的多个个人、团队或应用程序之间划分集群资源的一种方式。默认情况下,命名空间不会被自动隔离。然而,命名空间确实为一个范围分配了一个标签,这可以用来通过 RBAC 和网络策略指定授权规则。除了网络隔离之外,策略可以限制存储和计算资源,以便在命名空间层面上对 Pod 进行更好的控制。

默认有三个命名空间,它们不能被删除:

  • kube-system(用于 Kubernetes 组件)
  • kube-public(用于公共资源)
  • default(针对用户资源)

用户 Pod 不应该放在 kube-systemkube-public 中,因为这些都是为集群服务保留的。可以用 YAML 文件,如 附录 D:命名空间示例 ,可以用来创建新的命名空间。不同命名空间中的 Pod 和服务仍然可以相互通信,除非有额外的隔离措施,如网络策略。

网络策略

网络策略控制 Pod、命名空间和外部 IP 地址之间的流量。默认情况下,没有网络策略应用于 Pod 或命名空间,导致 Pod 网络内的入口和出口流量不受限制。通过适用于 Pod 或 Pod 命名空间的网络策略,Pod 将被隔离。一旦一个 Pod 在网络策略中被选中,它就会拒绝任何适用的策略对象所不允许的任何连接。

要创建网络策略,需要一个支持 NetworkPolicy API 的网络插件。使用 podSelector 和 / 或 namespaceSelector 选项来选择 Pod。附录 E 中展示了一个网络策略的例子。网络策略的格式可能有所不同,这取决于集群使用的容器网络接口(CNI)插件。管理员应该使用选择所有 Pod 的默认策略来拒绝所有入口和出口流量,并确保任何未选择的 Pod 被隔离。然后,额外的策略可以放松这些允许连接的限制。

外部 IP 地址可以使用 ipBlock 在入口和出口策略中使用,但不同的 CNI 插件、云提供商或服务实现可能会影响 NetworkPolicy 处理的顺序和集群内地址的重写。

资源政策

除了网络策略,LimitRangeResourceQuota 是两个可以限制命名空间或节点的资源使用的策略。LimitRange 策略限制了特定命名空间内每个 Pod 或容器的单个资源,例如,通过强制执行最大计算和存储资源。每个命名空间只能创建一个 LimitRange 约束,如 附录 F LimitRange 示例中所示。Kubernetes 1.10 和更新版本默认支持 LimitRange

LimitRange 策略不同的是,ResourceQuotas 是对整个命名空间的资源使用总量的限制,例如对 CPU 和内存使用总量的限制。如果用户试图创建一个违反 LimitRangeResourceQuota 策略的 Pod,则 Pod 创建失败。附录 G 中显示了一个 ResourceQuota 策略的示例。

控制平面加固

控制平面是 Kubernetes 的核心,使用户能够查看容器,安排新的 Pod,读取 Secret,在集群中执行命令。由于这些敏感的功能,控制平面应受到高度保护。除了 TLS 加密、RBAC 和强大的认证方法等安全配置外,网络隔离可以帮助防止未经授权的用户访问控制平面。Kubernetes API 服务器运行在 6443 和 8080 端口上,这些端口应该受到防火墙的保护,只接受预期的流量。8080 端口,默认情况下,可以在没有 TLS 加密的情况下从本地机器访问,请求绕过认证和授权模块。不安全的端口可以使用 API 服务器标志 --insecure-port=0 来禁用。Kubernetes API 服务器不应该暴露在互联网或不信任的网络中。网络策略可以应用于 kube-system 命名空间,以限制互联网对 kube-system 的访问。如果对所有命名空间实施默认的拒绝策略,kube-system 命名空间仍然必须能够与其他控制平面和工作节点进行通信。

下表列出了控制平面的端口和服务。

表 2:控制平面端口

端口 方向 端口范围 目的
TCP Inbound 6443 or 8080 if not disabled Kubernetes API server
TCP Inbound 2379-2380 etcd server client API
TCP Inbound 10250 kubelet API
TCP Inbound 10251 kube-scheduler
TCP Inbound 10252 kube-controller-manager
TCP Inbound 10258 cloud-controller-manager(可选)

Etcd

etcd 后端数据库是一个关键的控制平面组件,也是集群中最重要的安全部分。

etcd 后端数据库存储状态信息和集群 Secret。它是一个关键的控制平面组件,获得对 etcd 的写入权限可以使网络行为者获得对整个集群的 root 权限。Etcd 只能通过 API 服务器访问,集群的认证方法和 RBAC 策略可以限制用户。etcd 数据存储可以在一个单独的控制平面节点上运行,允许防火墙限制对 API 服务器的访问。管理员应该设置 TLS 证书以强制执行 etcd 服务器和 API 服务器之间的 HTTPS 通信。etcd 服务器应被配置为只信任分配给 API 服务器的证书。

Kubeconfig 文件

kubeconfig 文件包含关于集群、用户、命名空间和认证机制的敏感信息。Kubectl 使用存储在工作节点的 $HOME/.kube 目录下的配置文件,并控制平面本地机器。网络行为者可以利用对该配置目录的访问,获得并修改配置或凭证,从而进一步破坏集群。配置文件应该被保护起来,以防止非故意的改变,未经认证的非 root 用户应该被阻止访问这些文件。

工作节点划分

工作节点可以是一个虚拟机或物理机,这取决于集群的实现。由于节点运行微服务并承载集群的网络应用,它们往往是被攻击的目标。如果一个节点被破坏,管理员应主动限制攻击面,将工作节点与其他不需要与工作节点或 Kubernetes 服务通信的网段分开。防火墙可用于将内部网段与面向外部的工作节点或整个 Kubernetes 服务分开,这取决于网络的情况。机密数据库或不需要互联网访问的内部服务,这可能需要与工作节点的可能攻击面分离。

下表列出了工作节点的端口和服务。

表 3:工作节点端口

端口 方向 端口范围 目的
TCP Inbound 10250 kubelet API
TCP Inbound 30000-32767 NodePort Services

加密

管理员应配置 Kubernetes 集群中的所有流量 —— 包括组件、节点和控制计划之间的流量(使用 TLS 1.2 或 1.3 加密)。

加密可以在安装过程中设置,也可以在安装后使用 TLS 引导(详见 Kubernetes 文档 )来创建并向节点分发证书。对于所有的方法,必须在节点之间分发证书,以便安全地进行通信。

Secret

默认情况下,Secret 被存储为未加密的 base64 编码的字符串,并且可以被任何有 API 权限的人检索。

Kubernetes Secret 维护敏感信息,如密码、OAuth 令牌和 SSH 密钥。与在 YAML 文件、容器镜像或环境变量中存储密码或令牌相比,将敏感信息存储在 Secret 中提供了更大的访问控制。默认情况下,Kubernetes 将 Secret 存储为未加密的 base64 编码字符串,任何有 API 权限的人都可以检索到。可以通过对 secret 资源应用 RBAC 策略来限制访问。

可以通过在 API 服务器上配置静态数据加密或使用外部密钥管理服务(KMS)来对秘密进行加密,该服务可以通过云提供商提供。要启用使用 API 服务器的 Secret 数据静态加密,管理员应修改 kube-apiserver 清单文件,以执行使用 --encryption-provider-config 参数执行。附录 H 中显示了一个 encryption-provider-config 的例子:加密实例。使用 KMS 提供者可以防止原始加密密钥被存储在本地磁盘上。要用 KMS 提供者加密 Secret,encryption-provider-config 文件中应指定 KMS 提供者,如附录 I 的 KMS 配置示例所示。

在应用了 encryption-provider-config 文件后,管理员应该运行以下命令来读取和加密所有的 Secret。

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

保护敏感的云基础设施

Kubernetes 通常被部署在云环境中的虚拟机上。因此,管理员应该仔细考虑 Kubernetes 工作节点所运行的虚拟机的攻击面。在许多情况下,在这些虚拟机上运行的 Pod 可以在不可路由的地址上访问敏感的云元数据服务。这些元数据服务为网络行为者提供了关于云基础设施的信息,甚至可能是云资源的短期凭证。网络行为者滥用这些元数据服务进行特权升级。Kubernetes 管理员应通过使用网络策略或通过云配置策略防止 Pod 访问云元数据服务。由于这些服务根据云供应商的不同而不同,管理员应遵循供应商的指导来加固这些访问载体。