最佳做法:在 Azure Kubernetes 服务 (AKS) 中实现多租户

本指南提供用于在 Azure Kubernetes 服务 (AKS) 上为多租户配置 Kubernetes 的从业者级实现步骤。 它直接建立在 概念:AKS 中的多租户 中定义的隔离谱系和原语之上。

先决条件

在本指南中实现配置之前,请确保:

  • Azure CLI 2.53.0 或更高版本安装和配置。 若要检查版本,请运行 az version。 若要安装或更新,请参阅 安装 Azure CLI
  • 用于创建 AKS 群集以及群集内 Kubernetes 对象的 Azure 权限(例如,对资源组具有 OwnerContributor 权限,以及具有足够的 Kubernetes 授权来创建命名空间、角色和角色绑定)。
  • 了解 概念概述中定义的多租户基元。

基线群集创建

若要支持现代多租户,必须为集群预配正确的网络插件和数据平面。 以下命令az aks create建立一个基线群集,该群集启用了 Azure CNI 覆盖层和 ACNS Cilium,以实现高级网络隔离。

az aks create \
    --resource-group myResourceGroup \
    --name myMultiTenantCluster \
    --network-plugin azure \
    --network-plugin-mode overlay \
    --network-dataplane cilium \
    --enable-managed-identity \
    --enable-aad \
    --generate-ssh-keys

1. 托管命名空间

问题:默认情况下,所有工作负载都会部署到 default 命名空间中,从而导致命名冲突、缺乏访问边界,以及共享故障影响范围。

解决方案:为每个租户创建专用命名空间。 使用标签标明租户归属,以便进行计费和策略强制执行。

apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a-production
  labels:
    tenant: "tenant-a"
    environment: "production"
    pod-security.kubernetes.io/enforce: "restricted"

AKS 优势:AKS 将命名空间标签直接与Azure Policy和Azure Monitor集成,使你可以按租户筛选符合性状态和遥测数据,而无需额外的工具。

验证隔离

kubectl get namespaces --show-labels

2. 具有 Microsoft Entra ID 的 Kubernetes RBAC

问题:租户需要访问来部署和管理其应用程序,但提供群集范围的管理员访问权限会损害整个环境。

解决方案:使用 Kubernetes RoleRoleBinding 清单文件将 Microsoft Entra ID 组绑定到特定命名空间。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: tenant-a-production
  name: tenant-a-developer-role
rules:
- apiGroups: ["", "apps", "autoscaling"]
  resources: ["pods", "services", "deployments", "replicasets", "horizontalpodautoscalers"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tenant-a-developer-binding
  namespace: tenant-a-production
subjects:
- kind: Group
  name: "00000000-0000-0000-0000-000000000000" # Microsoft Entra ID Group Object ID
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: tenant-a-developer-role
  apiGroup: rbac.authorization.k8s.io

AKS 优势:通过将 Kubernetes RBAC 与Microsoft Entra ID标识集成,可以避免在群集中管理本地用户帐户,并且可以集中Microsoft Entra中的用户生命周期操作。

验证隔离

使用租户组成员的用户登录,然后运行:

kubectl auth can-i create deployments --namespace tenant-a-production

3. ACNS Cilium 网络策略

问题:Kubernetes 默认允许所有 Pod 相互通信。 租户 A 命名空间中受损的 Pod 可能会探测或攻击租户 B 的工作负荷。

解决方案:使用 ACNS Cilium 实现租户命名空间隔离策略,以允许租户工作负荷仅与同一命名空间中的工作负荷通信,除非其他策略明确允许。

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: tenant-a-namespace-isolation
  namespace: tenant-a-production
spec:
  endpointSelector:
    matchLabels: {}
  ingress:
  - fromEndpoints:
    - matchLabels:
        k8s:io.kubernetes.pod.namespace: tenant-a-production
  egress:
  - toEndpoints:
    - matchLabels:
        k8s:io.kubernetes.pod.namespace: tenant-a-production

AKS 优势:ACNS Cilium 策略在 eBPF 层处理流量,相比标准的基于 iptables 的方法,可为多租户网络隔离提供高性能的策略执行。

验证隔离:尝试 curl 从 Pod 传入 tenant-a-productiontenant-b-productionPod,并尝试从 tenant-a-production 另一个命名空间中的工作负荷传出。 除非存在单独的允许策略,否则两个连接都应失败。


4. 资源配额

问题:如果某个租户部署了失控的工作负载,或出现内存泄漏,就可能耗尽节点的全部资源,导致其他租户得不到足够的资源(即“吵闹邻居”问题)。

解决方案:应用 ResourceQuota 限制命名空间总消耗量,并 LimitRange 强制对单个 Pod 强制实施默认请求/限制。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-a-quota
  namespace: tenant-a-production
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    pods: "50"
---
apiVersion: v1
kind: LimitRange
metadata:
  name: tenant-a-limit-range
  namespace: tenant-a-production
spec:
  limits:
  - default:
      cpu: 500m
      memory: 512Mi
    defaultRequest:
      cpu: 100m
      memory: 256Mi
    type: Container

AKS 优势ResourceQuotaLimitRange 在准入时提供可强制执行的租户边界,而集群自动扩缩器会独立地为处于挂起状态且在这些限制内仍可被调度的 Pod 扩缩节点。

验证隔离

kubectl describe quota tenant-a-quota --namespace tenant-a-production

5. Pod 安全准入

问题:租户可能尝试部署特权容器、装载主机文件系统或以根身份运行,这可能会损害基础 AKS 节点。

解决方案:在命名空间级别强制实施 Kubernetes Pod 安全标准(PSS),以阻止特权工作负荷。

apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a-production
  labels:
    pod-security.kubernetes.io/enforce: "restricted"
    pod-security.kubernetes.io/audit: "restricted"
    pod-security.kubernetes.io/warn: "restricted"

AKS 优势:可以使用 Kubernetes 的 Azure Policy,跨所有租户命名空间全局强制实施这些标准,从而防止群集管理员意外创建不安全的命名空间。

验证隔离:尝试将 Pod 部署到 securityContext.privileged: true 命名空间。 API 服务器将拒绝部署。


6. 节点池隔离

问题:对于严格多租户,仅靠逻辑命名空间隔离是不够的。 受到严格监管的租户通常需要更强的计算资源隔离,并降低“噪声邻居”风险。

解决方案:为特定租户创建专用节点池,并使用 Kubernetes 污点和容忍度将工作负载调度到这些节点上。 这改进了计算隔离,但控制平面和群集级组件仍保持共享状态。

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myMultiTenantCluster \
    --name tenanta \
    --node-taints tenant=tenant-a:NoSchedule \
    --labels tenant=tenant-a

随后,租户必须在其 Pod 清单中包含相应的容忍度:

tolerations:
- key: "tenant"
  operator: "Equal"
  value: "tenant-a"
  effect: "NoSchedule"

AKS 优势:AKS 允许独立缩放、升级和管理特定于租户的节点池的生命周期,这意味着你可以修补租户 A 的节点,而不会造成租户 B 的停机。

验证隔离

kubectl get nodes -l tenant=tenant-a

7. Azure Monitor

问题:在共享群集中,平台管理员需要基于每个租户跟踪资源利用率、应用程序日志和性能指标。

解决方案:启用 Azure Monitor Container Insights 并使用命名空间标签筛选 KQL 查询。

az aks enable-addons -a monitoring -n myMultiTenantCluster -g myResourceGroup

AKS 优势:Azure Monitor 自动捕获 Kubernetes 命名空间元数据。 您可以创建自定义 Azure 仪表板,按 KubePodInventory 列筛选 ContainerLogNamespace 表,为每个租户提供专属的可观测性窗格。

验证隔离:在 Log Analytics 中运行 KQL 查询,并按 Namespace == "tenant-a-production" 进行筛选。


企业隔离注意事项

对于大规模企业部署,请考虑以下附加体系结构边界:

  • 订阅层次结构:将多租户群集放置在专用登陆区域订阅中,以在云提供商级别隔离Azure API 限制和计费。
  • 专用群集:使用具有Azure 专用链接的 AKS 专用群集来确保 Kubernetes API 服务器只能从受信任的内部网络访问,从而防止控制平面免受公共 Internet 威胁。
  • 多区域节点池:跨Azure 可用性区域分配租户节点池,以确保租户工作负荷在数据中心级故障中幸存下来。
  • 成本隔离:在节点池上使用Azure标记,并集成 Kubecost 等工具来执行退款,将确切的计算和存储成本归因于特定的租户命名空间。

生产就绪情况核对清单

将租户加入 AKS 群集之前,请验证以下内容:

  • 第 1 层:使用适当的计费和所有权标签创建托管命名空间。
  • 第 2 层:Kubernetes RBAC 角色绑定将映射到 Microsoft Entra ID 组,以实现命名空间范围内的访问。
  • 第 3 层:ACNS Cilium 租户命名空间隔离策略应用于所有租户命名空间。
  • 第 4 层ResourceQuota 对象 LimitRange 在每个命名空间中处于活动状态。
  • 第 5 层:通过命名空间标签或 Azure Policy 将 Pod 安全准入设置为 restricted
  • 第 6 层:(如有需要)会为专用节点池配置污点,以实现硬隔离多租户。
  • 第 7 层:启用Azure Monitor,平台团队具有命名空间筛选的仪表板。

后续步骤

若要查看告知这些最佳做法的体系结构理论和隔离范围,请返回到概念性概述。