保护 Azure Kubernetes 服务 (AKS) 中的 Pod 的最佳做法

在 Azure Kubernetes 服务 (AKS) 中开发和运行应用程序时,Pod 的安全性是需要考虑的一个重要方面。 设计应用程序时,应以所需权限最少为原则。 客户最看重的是私人数据的安全。 你不会希望将数据库连接字符串、密钥或机密和证书等凭据暴露给外部世界,因为攻击者可能利用这些机密进行恶意攻击。 请勿将这些凭据添加到代码中,或将其嵌入容器映像中。 这样会有暴露的风险,并且会限制凭证的轮换能力,因为轮换时需要重建容器映像。

这篇有关最佳做法的文章重点介绍如何保护 AKS 中的 Pod。 学习如何:

  • 使用 Pod 安全性上下文来限制对进程和服务,或权限提升的访问权限
  • 使用 Microsoft Entra 工作负载 ID 向其他 Azure 资源进行身份验证
  • 从数字保管库(如 Azure Key Vault)请求和检索凭据

还可阅读有关群集安全性容器映像管理的最佳做法。

保护 Pod 对资源的访问权限

最佳做法指南 - 要作为其他用户或组运行,并限制对基础节点进程和服务的访问权限,请定义 Pod 安全性上下文设置。 请分配所需的最少权限。

为使应用程序正常运行,Pod 应作为已定义的用户或组运行,而不是根用户或组。 通过 Pod 或容器的 securityContext,可定义 runAsUser 或 fsGroup 等设置,以承担相应权限 。 仅分配所需的用户或组权限,不要使用安全性上下文来承担其他权限。 runAsUser、特权提升和其他 Linux 功能设置仅在 Linux 节点和 Pod 上可用。

作为非根用户运行时,容器无法绑定到 1024 下的特权端口。 此时可使用 Kubernetes 服务掩盖应用程序正在特定端口上运行这一事实。

Pod 安全性上下文还可定义用于访问进程和服务的其他功能或权限。 可设置以下常见安全性上下文定义:

  • allowPrivilegeEscalation 定义 Pod 是否可承担根特权。 设计应用程序,将此设置始终设为 false。
  • Linux 功能可使 Pod 访问基础节点进程。 请小心分配这些功能。 请分配所需的最少权限。 有关详细信息,请参阅 Linux 功能
  • SELinux 标签是一个 Linux 内核安全模块,允许你定义服务、进程和文件系统访问权限的访问策略。 同样,请分配所需的最少权限。 有关详细信息,请参阅 Kubernetes 中的 SELinux 选项

以下示例 Pod YAML 清单设置了安全性上下文设置,给出了以下定义:

  • Pod 以 ID 为 1000 的用户身份和 ID 为 2000 的部分组运行
  • 无法提升特权,无法使用 root
  • 允许 Linux 功能访问网络接口和主机的实时(硬件)时钟
apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    fsGroup: 2000
  containers:
    - name: security-context-demo
      image: mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine
      securityContext:
        runAsUser: 1000
        allowPrivilegeEscalation: false
        capabilities:
          add: ["NET_ADMIN", "SYS_TIME"]

与群集操作员共同确定所需安全性上下文设置。 尝试设计应用程序,以尽量减少其他权限并访问 Pod 要求。 群集操作员还可实施其他安全功能来限制使用 AppArmor 和 seccomp(安全计算)进行的访问。 有关详细信息,请参阅保护容器对资源的访问

避免凭据暴露

最佳操作指南 - 不要在应用程序代码中定义凭据。 使用 Azure 资源的托管标识,让 Pod 请求访问其他资源。 还应使用数字保管库(如 Azure Key Vault)来存储和检索数字密钥和凭据。 Pod 托管标识仅适用于 Linux Pod 和容器映像。

要避免凭据在应用程序代码中暴露,请勿使用固定或共享凭据。 不应直接在代码中包含凭证或密钥。 如果凭据暴露,则需更新并重新部署应用程序。 更好的做法是,为 Pod 提供自己的标识,让它自行进行身份验证,或自动从数字保管库中检索凭据。

使用 Microsoft Entra 工作负载 ID

工作负载标识是 Pod 上运行的应用程序使用的标识,可以针对支持它的其他 Azure 服务(例如存储或 SQL)进行身份验证。 它与 Kubernetes 本机功能集成,以便与外部标识提供者联合。 在此安全模型中,AKS 群集充当令牌颁发者,Microsoft Entra ID 则使用 OpenID Connect 发现公共签名密钥,并在用它交换 Microsoft Entra 令牌前验证服务帐户令牌的真实性。 工作负载可以通过使用 Azure SDK 的 Azure 标识客户端库或 Microsoft 身份验证库 (MSAL),使用投影到其卷的服务帐户令牌交换 Microsoft Entra 令牌。

有关工作负载标识的详细信息,请参阅《配置 AKS 群集以将 Microsoft Entra 工作负载 ID 用于应用程序

将 Azure 密钥保管库与 Secrets Store CSI 驱动程序结合使用

使用 Microsoft Entra 工作负载 ID,可以针对支持的 Azure 服务进行身份验证。 若自己的服务或应用程序没有 Azure 资源托管标识,仍可使用凭据或密钥进行身份验证。 可使用数字保管库来存储这些机密内容。

当应用程序需要凭据时,它们会与数字保管库通信,检索最新的机密内容,然后连接到所需的服务。 此数字保管库可以是 Azure Key Vault。 下图显示了使用 Pod 托管标识从 Azure Key Vault 检索凭据的简化工作流:

Simplified workflow for retrieving a credential from Key Vault using a pod managed identity

使用 Key Vault,可存储并定期轮换凭据、存储帐户密钥或证书等机密。 可使用适用于 Secrets Store CSI 驱动程序的 Azure 密钥保管库提供程序将 Azure 密钥保管库与 AKS 群集集成。 Secrets Store CSI 驱动程序允许 AKS 群集以本机方式检索密钥保管库中的机密内容,并仅将其安全地提供给发出请求的 Pod。 与群集操作员一起将 Secrets Store CSI 驱动程序部署到 AKS 工作器节点上。 可使用 Microsoft Entra 工作负载 ID 来请求访问密钥保管库的权限,并通过机密存储 CSI 驱动程序检索所需的机密内容。

后续步骤

本文重点介绍了如何保护 Pod。 若要实施其中某些做法,请参阅以下文章: