练习 - 向 Azure Kubernetes 服务群集分配策略
现在,你已准备好为Azure Kubernetes 服务 (AKS) 群集配置 Azure 策略和计划。
在本单元中,你将部署一个不合规的 Pod,并应用强制仅使用受信任的注册表的 Azure Policy。 然后,另外部署一个不合规的 Pod 来查看策略的效果。 你将了解故障排除步骤,并了解未创建 Pod 的原因。 还将部署“基于 Linux 的工作负载的 Kubernetes 群集 Pod 安全限制标准”计划。
注意
本练习为选做练习。 若要完成本练习,需要在开始之前创建 Azure 订阅。 如果没有 Azure 帐户,或者现在不想创建帐户,则可以通读说明,以便了解所提供的信息。
将不合规的 Pod 部署到群集中
首先直接将映像从 Docker Hub 部署到群集。 首先是登录到该群集。
在 Cloud Shell 中,登录到 AKS 群集。
az aks get-credentials -n videogamecluster -g videogamerg
运行以下代码,从 Docker Hub 创建简单的 nginx Pod。
cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: simple-nginx labels: app: nginx spec: selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: simple-nginx image: docker.io/library/nginx:stable resources: requests: cpu: 100m memory: 100Mi limits: cpu: 120m memory: 120Mi ports: - containerPort: 80 EOF
运行以下代码,部署服务来公开部署。
cat <<EOF | kubectl create -f - apiVersion: v1 kind: Service metadata: name: simple-nginx labels: app: nginx spec: type: LoadBalancer ports: - port: 80 selector: app: nginx EOF
列出所有已部署的服务。
kubectl get services
复制 simple-nginx 服务的 External-IP 并将其粘贴到浏览器中,以查看该服务是否按预期运行。
如果列出的外部 IP 为
<pending>
,请重新运行命令。 为工作负载分配公共 IP 地址需要一些时间。
将 Azure Policy 应用到 AKS 群集
你已成功在未实施任何策略的群集上部署工作负载。 现在可向群集添加策略,并查看策略的效果。
分配策略
你需要确保群集中仅允许来自特定注册表的映像。 需要创建新的策略定义,然后将其分配给范围。 在本例中,范围是“视频游戏”资源组。 可以通过 Azure 门户、Azure PowerShell 或 Azure CLI 创建和分配策略。 本练习介绍在门户中创建策略的过程。
通过以下步骤,使用 Azure 门户查找用于管理群集的内置策略定义。 在本例中,将应用“仅限允许的映像”策略。
转到 Azure 门户中的策略页面。
在“Azure Policy”页面的左侧窗格中,选择“定义”。
从“类别”下拉列表框中,使用“全选”清除筛选器,然后选择“Kubernetes”。
选择“Kubernetes 群集容器应只使用允许的映像”策略定义。
选择“分配”按钮。
将“范围”设置为你创建的 Kubernetes 群集的资源组,本例中为 videogamerg 资源组。
在“允许的容器映像正则表达式”字段中输入以下内容,然后选择“查看 + 创建”按钮
.+\.azurecr\.io/.+$
- 选择“创建”按钮。
启用新策略后,可选择“分配”查看分配的策略,然后选择你创建的策略分配。
策略分配应如下图所示。 默认情况下,效果设置为“拒绝”。 这意味着只有 Azure 容器注册表中托管的映像才能部署在群集中。
分配策略计划
现在你的策略已成功分配,接下来请在测试策略之前分配计划。 Azure Policy 计划是为满足特定目标或目的而组合在一起的 Azure Policy 定义或规则集合。 Azure 计划在逻辑上将一组策略分组为单个项,从而简化了对策略的管理。
计划分配方式与策略分配方式相同。 按照以下步骤分配基于 Linux 的工作负载的 Kubernetes 群集 Pod 安全限制标准计划。
- 返回到 Azure 门户中的策略页面。
- 在“Azure Policy”页面的左侧窗格中,选择“定义”。
- 从“类别”下拉列表框中,使用“全选”清除筛选器,然后选择“Kubernetes”。
- 选择“基于 Linux 的工作负载的 Kubernetes 群集 Pod 安全限制标准”计划定义。 请花一些时间查看该计划中的各种策略。
- 选择屏幕左上角的“分配”按钮。
- 将“范围”设置为你创建的 Kubernetes 群集的资源组,本例中为 videogamerg。 像上一步那样填写表单的其余部分,然后选择“查看 + 创建”。
- 选择“创建”按钮。
可在此处再次找到“策略分配”,方法是单击“策略”,然后选择“分配”。 在本例中,单击创建的策略分配将显示效果已设置为“审核”。
测试 Azure Policy
现在已将限制策略分配给群集,接下来可运行测试来查看策略是否有效。 为演示这一点,请创建一个新的部署,并查看部署是否正常工作。 首先新建一个 kubernetes 清单文件并部署它。
重要
请注意,策略分配最多可能需要 30 分钟才能生效。 由于此延迟,在以下步骤中,策略验证可能会成功,而且部署将不会失败。 如果发生这种情况,请留出更多时间并重试部署。
可运行以下命令来检查策略分配是否生效。
kubectl get ConstraintTemplates
应看到类似于以下输出的结果。 如果在列表中看到 k8sazurecontainerallowedimages
,则表示策略已生效。
k8sazureallowedcapabilities 40m
k8sazureallowedseccomp 20m
k8sazureallowedusersgroups 40m
k8sazureblockautomounttoken 40m
k8sazureblockdefault 40m
k8sazureblockhostnamespace 40m
k8sazurecontainerallowedimages 40m
k8sazurecontainerallowedports 40m
k8sazurecontainerlimits 40m
k8sazurecontainernoprivilege 40m
k8sazurecontainernoprivilegeescalation 40m
k8sazuredefenderblockvulnerableimages 40m
k8sazuredisallowedcapabilities 40m
k8sazureenforceapparmor 40m
k8sazurehostfilesystem 40m
k8sazurehostnetworkingports 40m
k8sazureingresshttpsonly 40m
k8sazurereadonlyrootfilesystem 40m
k8sazureserviceallowedports 40m
k8sazurevolumetypes 20m
使用以下代码另外创建一个
nginx
部署和服务。cat <<EOF | kubectl create -f - apiVersion: apps/v1 kind: Deployment metadata: name: second-simple-nginx labels: app: second-nginx spec: selector: matchLabels: app: second-nginx template: metadata: labels: app: second-nginx spec: containers: - name: second-simple-nginx image: docker.io/library/nginx:stable resources: requests: cpu: 100m memory: 100Mi limits: cpu: 120m memory: 120Mi ports: - containerPort: 80 EOF
创建服务
cat <<EOF | kubectl create -f - apiVersion: v1 kind: Service metadata: name: second-simple-nginx labels: app: second-nginx spec: type: LoadBalancer ports: - port: 80 selector: app: second-nginx EOF
现在可检查 Pod 是否已创建。
kubectl get pods
在以下输出中,即使部署显示为已创建,也不会创建 Pod。 你创建的策略阻止了该部署。 但是,在分配策略之前创建的 Pod 未停止。 该策略也没有阻止创建服务。 如果尝试在浏览器中打开 EXTERNAL-IP,你不会收到任何响应,这进一步表明部署未成功。
NAME READY STATUS RESTARTS AGE
simple-nginx-66d884c498-msbpc 1/1 Running 0 63m
诊断 Pod 未部署的原因
在上一部分,我们注意到第二个 Pod 未部署。 在本部分,我们使用命令行来诊断原因。
首先,让我们描述部署。 我们看到 ReplicaSet 已创建,但未能创建副本。
kubectl get replicasets
应会看到类似于以下示例的输出:
NAME DESIRED CURRENT READY AGE second-simple-nginx-64969b4566 1 0 0 8m45s simple-nginx-66d884c498 1 1 1 72m
接下来说明失败的 ReplicaSet。 复制以
second-simple-nginx
开头的 ReplicaSet 的名称,使用该值更新以下命令并运行该命令。kubectl describe replicaset <ReplicaSet name>
命令的输出会显示副本因策略而失败。
Warning FailedCreate 3m9s (x18 over 14m) replicaset-controller Error creating: admission webhook "validation.gatekeeper.sh" denied the request: [azurepolicy-container-allowed-images-bcfbd5e1e78f7c8b4104] Container image docker.io/library/nginx:stable for container second-simple-nginx has not been allowed.
删除部署以准备下一步。
kubectl delete deployment second-simple-nginx
使用 Azure 容器注册表映像重新部署 Pod
现在你知道 Policy 会根据你的策略阻止在群集中创建来自 Docker Hub 的映像。 让我们尝试使用 Azure 容器注册表 (ACR) 中的映像重新部署同一工作负载。 在此部分,你将创建 Azure 容器注册表。 然后,将 nginx 映像从 Docker Hub 复制到新注册表,并尝试从容器注册表重新部署 Pod。 我们使用 Azure CLI 来创建容器注册表。
返回到 Azure 门户中的 Cloud Shell,并输入以下命令创建新的容器注册表。
ACR_NAME=videogameacr$RANDOM az acr create --name $ACR_NAME \ --resource-group videogamerg \ --sku Premium
将映像从 Docker Hub 导入新的容器注册表。
az acr import --name $ACR_NAME --source docker.io/library/nginx:stable --image nginx:v1
检查以确保映像已导入。 结果列表中应该会显示 nginx。
az acr repository list --name $ACR_NAME
将 AKS 群集与已创建的容器注册表链接。
az aks update -n videogamecluster -g videogamerg --attach-acr $ACR_NAME
现在运行以下命令,使用新创建的容器注册表创建部署。
cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: second-simple-nginx labels: app: second-nginx spec: selector: matchLabels: app: second-nginx template: metadata: labels: app: second-nginx spec: containers: - name: second-simple-nginx image: ${ACR_NAME}.azurecr.io/nginx:v1 resources: requests: cpu: 100m memory: 100Mi limits: cpu: 120m memory: 120Mi ports: - containerPort: 80 EOF
获取 EXTERNAL-IP,以便测试服务是否正在群集中运行。
kubectl get pods kubectl get services
复制外部 IP 地址并将其粘贴到浏览器中。 你会看到页面现在已加载。
使用策略来强制执行标准
在本单元中,你了解了如何使用策略来确保群集仅允许部署 Azure 容器注册表中的映像。 你还了解了如何添加一个可帮助轻松治理群集并使其更安全的内置计划。 但你发现,在分配策略之前部署的 Pod 仍在运行。 下一个单元将介绍如何检查群集上运行的 Pod 的合规性。