练习 - 在 AKS 群集上配置用于 Kubernetes 的 Azure Policy

已完成

用于 Kubernetes 的 Azure Policy 可帮助组织满足监管和法律要求、实施最佳做法和制定云环境的组织约定。

你公司中的开发团队将 Azure Kubernetes 服务 (AKS) 作为开发平台。 你认识到,管理成本的最佳方式是强制执行定义工作负载资源限制的业务规则。 你需要确保开发人员只能在特定的 CPU 和内存分配限制范围内部署工作负载。 系统必须阻止超出这些限制的工作负载。

在本练习中,你将为群集上的 AKS 启用 Azure Policy,并添加“Kubernetes 群集容器 CPU 和内存资源限制不得超过指定的限制”策略。 然后,你将测试该策略是否拒绝调度超过策略资源参数的工作负载。

启用 ContainerService 和 PolicyInsights 资源提供程序

  1. 使用 Azure 帐户登录 Azure Cloud Shell。 选择 Cloud Shell 的 Bash 版本。

  2. 适用于 AKS 的 Azure Policy 要求群集版本为 1.14 或更高版本。 运行以下脚本来验证 AKS 群集版本:

    az aks list
    

    请确保报告的群集版本至少为 1.14。

  3. 运行 az provider register 命令以注册 Azure Kubernetes 服务提供程序:

    az provider register --namespace Microsoft.ContainerService
    
  4. 运行 az provider register 命令以注册 Azure Policy 提供程序:

    az provider register --namespace Microsoft.PolicyInsights
    
  5. 通过运行 az feature register 命令来启用加载项安装:

    az feature register --namespace Microsoft.ContainerService --name AKS-AzurePolicyAutoApprove
    
  6. 通过查询功能列表来检查是否已成功注册。 使用 az feature list 命令运行查询。 功能注册可能需要几分钟才能完成,因此你必须定期检查结果。

    az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/AKS-AzurePolicyAutoApprove')].   {Name:name,State:properties.state}"
    

    如果 Cloud Shell 会话超时,可在 Azure 门户中使用预览载入窗格跟踪注册过程。

  7. 确认功能列表查询命令显示“已注册”后,运行 az provider register 命令以传播更新:

    az provider register -n Microsoft.ContainerService
    

在群集上启用 Azure Policy

  1. 运行 az aks enable-addons 命令,为群集启用 azure-policy 加载项:

    az aks enable-addons \
        --addons azure-policy \
        --name $AKS_CLUSTER_NAME \
        --resource-group $RESOURCE_GROUP
    
  2. 验证 Azure 策略 Pod 是否已安装在 kube-system 命名空间中,以及 Gatekeeper Pod 是否已安装在 gatekeeper-system 命名空间中。 为此,请运行以下 kubectl get pods 命令:

    kubectl get pods -n kube-system
    

    输出应如下所示:

    NAME                                    READY   STATUS    RESTARTS   AGE
    azure-policy-78c8d74cd4-7fqn2           1/1     Running   0          12m
    azure-policy-webhook-545c898766-gsjrc   1/1     Running   0          12m
    ...
    
    kubectl get pods -n gatekeeper-system
    

    输出应如下所示:

    NAME                                            READY   STATUS    RESTARTS   AGE
    gatekeeper-controller-manager-d5cd87796-5tmhq   1/1     Running   0          15m
    ...
    
  3. 最后,运行 az aks show 命令来验证是否已安装最新的加载项。 此命令会检索群集的配置信息。

    az aks show \
     --resource-group $RESOURCE_GROUP\
     --name $AKS_CLUSTER_NAME \
     -o table --query "addonProfiles.azurepolicy"
    

    输出应如下所示:

    {
        "config": null,
        "enabled": true,
        "identity": null
    }
    

    你现已准备好切换到 Azure 门户来配置名为“Kubernetes 群集容器 CPU 和内存资源限制不得超过指定的限制”的策略。

分配内置策略定义

若要配置新的 Azure Policy,请使用 Azure 门户中的 Policy 服务。

  1. 登录到 Azure 门户

  2. 在 Azure 门户中找到 Policy 服务。 为此,请在门户顶部的搜索栏中,搜索并选择 Policy。

  3. 请从服务列表中选择 Policy 服务,如下所示:

    Screenshot of the general Azure portal search box with a result that shows the Azure Policy service.

    此时会打开“策略”仪表板,其中概括显示了所有已分配的策略、资源状态以及策略对它们的影响。 如果你未分配任何策略,则仪表板将为空。

  4. 在左侧菜单窗格中的“创作”下,选择“分配”:

    Screenshot of the Policy service navigation panel that shows the location of the Assignments option.

  5. 回想一下前面描述的内容,可通过两种方法来创建策略分配:分配计划或策略。 在顶部菜单栏中,选择“分配策略”:

    Screenshot that shows the new policy assignment option.

    此时将显示“分配策略”窗格。

  6. 在“基本信息”选项卡上,为每个设置输入以下值,以创建策略。

    设置
    范围
    范围 选择省略号按钮。 此时将显示“范围”窗格。 在“订阅”下选择保存资源组的订阅。 对于“资源组”,请选择“rg-akscostsaving”,然后选择“选择”按钮。
    排除项 留空。
    基础知识
    策略定义 选择省略号按钮。 此时将显示“可用定义”窗格。 在“搜索”框中,输入 CPU 以筛选选项。 在“策略定义”选项卡上,选择“Kubernetes 群集容器 CPU 和内存资源限制不得超过指定的限制”,然后选择“添加”
    分配名称 接受默认值。
    说明 留空。
    策略强制执行 确保此选项设置为“已启用”。
    分配者 接受默认值。

    下面是已完成的“基本”选项卡示例:

    Screenshot that shows the information captured in the Basics tab.

  7. 选择“参数”选项卡以指定策略的参数。

  8. 为每个参数设置设置以下值:

    设置
    允许的最大 CPU 单位 将值设置为“200m”。 策略会将此值与工作负载清单文件中指定的工作负载资源请求值和工作负载限制值相匹配。
    允许的最大内存字节数 将值设置为“256Mi”。 策略会将此值与工作负载清单文件中指定的工作负载资源请求值和工作负载限制值相匹配。

    下面是已完成的“参数”选项卡示例:

    Screenshot that shows the information captured in the Parameters tab.

  9. 选择“修正”选项卡。在此选项卡中,你可以选择新策略对已存在的资源产生的影响。 默认情况下,新策略仅检查新建的资源。 保留标准默认配置。

    下面是已完成的“修正”选项卡示例:

    Screenshot that shows the information captured in the Remediation tab.

  10. 选择“查看 + 创建”选项卡。查看所选的值,然后选择“创建”

重要

如果使用现有的 AKS 群集,则应用策略分配可能需要大约 15 分钟。

测试资源请求

最后一步是测试新策略。 部署其资源请求和限制违反了新策略的测试工作负载。 如果一切正常进行,则服务器将返回错误,指出已被策略拒绝。

  1. 打开 Azure Cloud Shell,并确保选择 Cloud Shell 的 Bash 版本。

  2. 使用集成编辑器为 Kubernetes 部署创建清单文件。 调用文件 test-policy.yaml

    code test-policy.yaml
    

    提示

    Cloud Shell 中有一个集成的文件编辑器。 Cloud Shell 编辑器支持语言突出显示、命令面板和文件资源管理器等功能。 若要创建和编辑简单文件,可在 Cloud Shell 终端中运行 code . 以启动编辑器。 该操作会通过终端中设置的活动工作目录打开编辑器。 若要直接打开清单文件进行快速编辑,请运行 code test-policy.yaml。 此命令在没有文件资源管理器的情况下打开编辑器。

  3. 将以下文本粘贴到文件中:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        env: test
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        resources:
          requests:
            cpu: 500m
            memory: 256Mi
          limits:
            cpu: 1000m
            memory: 500Mi
    
  4. Ctrl+S 保存文件,然后按 Ctrl+Q 关闭编辑器。

  5. 运行 kubectl apply 命令,以应用配置并将应用程序部署到 costsavings 命名空间:

    kubectl apply \
    --namespace costsavings \
    -f test-policy.yaml
    

    输出应类似于以下内容:

    Error from server (
    [denied by azurepolicy-container-limits-52f2942767eda208f8ac3980dc04b548c4a18a2d1f7b0fd2cd1a7c9e50a92674] container <nginx> memory limit <500Mi> is higher than the maximum allowed of <256Mi>
    [denied by azurepolicy-container-limits-52f2942767eda208f8ac3980dc04b548c4a18a2d1f7b0fd2cd1a7c9e50a92674] container <nginx> cpu limit <1> is higher than the maximum allowed of <200m>)
     : error when creating "test-deploy.yml"
     : admission webhook "validation.gatekeeper.sh" denied the request: 
    [denied by azurepolicy-container-limits-52f2942767eda208f8ac3980dc04b548c4a18a2d1f7b0fd2cd1a7c9e50a92674] container <nginx> memory limit <500Mi> is higher than the maximum allowed of <256Mi>
    [denied by azurepolicy-container-limits-52f2942767eda208f8ac3980dc04b548c4a18a2d1f7b0fd2cd1a7c9e50a92674] container <nginx> cpu limit <1> is higher than the maximum allowed of <200m>
    

    请注意,准入 Webhook validation.gatekeeper.sh 拒绝了调度 Pod 的请求。

  6. 打开清单文件并修复资源请求:

    code test-policy.yaml
    

    将该文本替换为以下文本:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        env: test
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        resources:
          requests:
            cpu: 200m
            memory: 256Mi
          limits:
            cpu: 200m
            memory: 256Mi
    
  7. Ctrl+S 保存文件,然后按 Ctrl+Q 关闭编辑器。

  8. 运行 kubectl apply 命令,以应用配置并将应用程序部署到 costsavings 命名空间:

    kubectl apply \
    --namespace costsavings \
    -f test-policy.yaml
    

    将返回以下输出:

    pod/nginx created
    
  9. 获取在 costsavings 命名空间中新建的 Pod 的 Pod。

    kubectl get pods --namespace costsavings
    

    几秒钟内,Pod 将转换为 Running 状态。

    NAME    READY   STATUS    RESTARTS   AGE
    nginx   1/1     Running   0          50s
    
  10. 看到 Pod 运行后,按 Ctrl+C 停止监视。