Microsoft AZ-204: Azure 容器解决方案 — 学习指南
属于 Microsoft Azure Developer Associate AZ-204 — 学习指南. 使用经过验证的答案练习: Microsoft 考试中心, 或参加限时模拟考试: ExamRoll.io.
概述
Azure 提供了一系列容器选项,涵盖了单容器执行、编排集群以及安全的企业级镜像供应链。Azure Container Instances (ACI) 是无需管理服务器即可运行 Linux 或 Windows 容器的最快途径。Azure Kubernetes Service (AKS) 是一个托管的 Kubernetes 控制平面,可通过高级调度、网络、安全和 DevOps 集成来扩展微服务。Azure Container Registry (ACR) 是一个私有的、异地复制的注册表,是您构建、标记、推送/拉取和 Helm 分发流程的基石。掌握 Docker 镜像的构建和生命周期管理是在这些平台上实现可靠部署的基础。本节从开发人员的实用角度出发,阐述了各个部分如何协同工作,包括 YAML 驱动的部署、Helm 打包、服务暴露以及身份/安全模式。
Docker 和 Azure Container Registry (ACR)
可靠的容器交付始于扎实的 Docker 基础。每个镜像都由 Dockerfile 指令形成的层组成;层的重用和缓存命中对于快速构建至关重要。
- 常见的 Dockerfile 指令和指南:
- FROM 定义基础镜像。优先选择最小化镜像(例如,在适当时使用 distroless、alpine),以减少攻击面和大小。
- RUN 执行命令以安装依赖项。合并相关命令以减少层数,但要避免使用会掩盖故障的庞大单行 RUN 指令。
- COPY 和 ADD 用于放置应用程序构件。使用 .dockerignore 避免上下文体积膨胀;将 COPY 固定到明确的路径。
- WORKDIR 设置工作目录;使用它而不是在 RUN 中链接 cd 命令。
- EXPOSE 记录预期的监听端口(它不是防火墙)。
- ENV 和 ARG 配置环境变量和构建时变量;通过固定 ARG 默认值或传递显式值来提升构建时的确定性。
- ENTRYPOINT 定义主可执行文件;使用 CMD 提供默认参数。倾向于使用 exec 格式(JSON 数组)以保留信号处理能力,从而实现优雅停机。
- HEALTHCHECK 启用存活状态评估,以便编排器可以做出反应。
- 多阶段构建将构建阶段和运行时阶段分开,仅将所需构件复制到干净的运行时镜像中,从而大大减小镜像大小和 CVE 足迹。例如,使用 SDK 进行构建,发布二进制文件,然后将其复制到运行时基础镜像中。
- 镜像层是不可变的且基于内容寻址。重新排序指令会改变缓存行为。将频繁变化的指令(例如,COPY 源文件)放在 Dockerfile 的末尾,以最大化缓存命中率。
使用 ACR,可以私密地存储和分发镜像及 Helm charts:
- 仓库和标记:以
<registry>.azurecr.io/<repo>:<tag>的格式推送镜像。优先使用语义化或基于 Git 的标签(例如 1.4.0、构建的 SHA),并在生产部署中使用不可变摘要以确保可重复性。 - 推送和拉取:
- 使用
az acr login -n <acr-name>或通过docker login配合 Azure AD 令牌向 ACR 进行身份验证。避免在生产环境中启用 ACR 管理员用户。 - 标记和推送:
docker tag app:1.0 <acr>.azurecr.io/apps/app:1.0;docker push <acr>.azurecr.io/apps/app:1.0。使用docker pull或通过 Kubernetes 镜像引用进行拉取。 - 将上游镜像导入 ACR 以控制供应链:
az acr import -n <acr> --source docker.io/library/nginx:1.25 --image base/nginx:1.25。
- 使用
- ACR Tasks:在 Azure 中原生构建、测试和修补镜像。使用
az acr build -r <acr> -t apps/app:1.0 .进行按需构建;通过az acr task create自动执行更新,可由 Git 提交或基础镜像更新触发,从而在不更改应用程序代码的情况下实现 CVE 修复。 - 异地复制 (Premium SKU) 提供多区域拉取局部性和弹性。在靠近 AKS 集群的区域配置副本,以减少拉取延迟和跨区域出口流量。
- 访问控制:
- 与 Azure AD 集成,并将 AcrPull 等内置角色分配给 AKS kubelet 身份,将 AcrPush 分配给 CI 管道。可通过令牌和范围映射实现仓库范围的权限,以进行细粒度控制。
- 使用私有终结点、服务终结点和防火墙规则限制网络访问。生产环境优先使用私有终结点。
- 使用
az aks update --attach-acr <acr>将 ACR 附加到 AKS,以简化 AcrPull 角色的分配。
Azure Container Instances (ACI)
ACI 按需运行容器,无需进行集群管理。其主要单元是容器组,它是一组共同调度的容器,共享相同的主机操作系统内核、生命周期、IP 和卷。使用容器组可以实现 sidecar 模式(例如,日志托运程序、代理)或将主进程与辅助进程组合在一起。
- 多容器组共享一个网络命名空间,从而允许容器间通过 localhost 进行通信。它们还共享挂载卷(Azure Files、emptyDir)和生命周期,使其适用于需要紧密耦合的一次性内聚任务。
- 重启策略控制执行语义:
- Always:容器退出时总是重启。最适合长时间运行的服务。
- OnFailure:仅在退出代码为非零时重启。适用于应在失败时重试的批处理任务。
- Never:容器运行一次后绝不重启,是幂等作业的理想选择。
- 网络集成包括带有 DNS 标签的公共 IP、委派的 Azure VNet 子网中的私有 IP,以及通过 NAT 或防火墙实现的安全出口。注入 VNet 的 ACI 能够私密访问服务(数据库、存储),而无需将其公开暴露。
- 运维注意事项:
- 使用安全环境变量或挂载 Azure Files 来注入机密;为获得更强的安全态势,可在运行时通过托管身份从 Key Vault 中检索机密。
- 使用
az container logs和az container attach进行观察;使用az container exec运行交互式命令。 - 按 vCPU 和 GiB 内存的使用量进行秒级计费。容器启动迅速,适合突发性工作负载、CI 辅助任务、集成测试以及无需 Kubernetes 开销的队列触发作业。
Azure Kubernetes Service (AKS)
AKS 提供一个托管的控制平面,具备节点池、自动缩放以及深度的网络/身份集成选项。
节点池用于构建容量和工作负载的放置。系统节点池运行核心服务;用户节点池运行应用程序 Pod。可使用多个节点池,根据 CPU/内存/GPU 需求、操作系统 (Linux/Windows)、虚拟机大小和可用区来隔离工作负载。利用污点/容忍 (taints/tolerations) 来保护系统池,使用标签 (labels) 进行选择,并借助集群自动缩放器 (cluster autoscaler) 根据待处理的 Pod 来增删节点。在规划容量时,需考虑每个节点的最大 Pod 数 (maxPods) 和 Pod 密度。
Pod 调度由资源请求/限制 (requests/limits)、QoS 等级 (Guaranteed/Burstable/BestEffort) 和各种约束驱动。使用 nodeSelector/亲和性 (affinity) 与反亲和性 (anti-affinity) 将 Pod 推送到合适的池中,并将副本分布到不同的可用区和故障域。拓扑分布约束 (Topology spread constraints) 能改善 Pod 的均匀分布。对于关键服务,应定义 PodDisruptionBudgets 和 PriorityClasses 来控制自愿性中断和抢占行为。DaemonSets 用于在每个节点上放置代理(如日志、监控),而 CronJobs 则用于调度容器以执行周期性任务。
在 AKS 中,部署是声明式的。YAML 清单为 Deployments、StatefulSets、Jobs、Services 和 Ingress 定义了 apiVersion、kind、metadata 和 spec。应将清单保存在源代码控制中,使用 Kustomize 覆盖 (overlays) 来参数化环境差异,并通过 kubectl apply -f 应用。服务器端应用 (Server-side apply) 和恰当的标签/注解有助于明确所有权和进行漂移检测。对于打包可重用的应用程序,Helm 3 将模板和值捆绑在一起。可将 Helm chart 作为 OCI 制品托管在 ACR 中,并使用 helm upgrade –install <release> oci://<acr>.azurecr.io/helm/<chart> -f values.yaml 进行安装。为每个环境使用不同的 values 文件,跟踪 chart 版本,并使用 helm rollback 进行快速恢复。
您日常会用到的 kubectl 命令:
- 访问集群上下文:az aks get-credentials -g
<rg>-n<cluster>会合并 kubeconfig;在一台已加入 Azure AD 的计算机上使用 kubectl 就足够了——部署清单并不需要 Docker。 - 检查与操作:kubectl get nodes,pods,deploy,svc -A; kubectl describe pod
<name>; kubectl logs -f<pod>; kubectl exec -it<pod>– sh; kubectl rollout status deploy/<name>; kubectl set image deploy/<name>container=<image>:<tag>; kubectl top pods; kubectl cordon/drain nodes 进行维护;kubectl auth can-i 验证 RBAC。 - 应用/修补:kubectl apply -f k8s/; kubectl patch deploy
<name>–type merge -p ‘{…}’。
AKS 中的网络通过明确的职责划分来暴露 Pod 和服务:
- ClusterIP 提供仅限内部、集群范围的虚拟 IP 和 DNS,用于服务发现。这是微服务之间东西向流量的默认选择。
- NodePort 在每个节点上打开相同的端口;最好在 Ingress 或外部 LB 后面使用,而不是直接消费。
- LoadBalancer 会预配一个 Azure Load Balancer 前端,该前端以 NodePorts 为目标。通过添加注解 service.beta.kubernetes.io/azure-load-balancer-internal: “true” 将服务标记为内部服务,或分配一个静态公共 IP 以获得稳定的 DNS。
- Ingress 控制器提供 L7 路由、TLS 终止以及基于路径/主机的规则。NGINX Ingress Controller 是一个功能丰富的通用默认选项,拥有丰富的注解。Application Gateway Ingress Controller (AGIC) 与 Azure Application Gateway 集成,提供 WAF、自动缩放和企业级 L7 功能,同时保持 Kubernetes 原生的清单配置方式。使用 cert-manager 通过 ACME 自动化 TLS,或使用 CSI Secret Store 将 Key Vault 证书同步到 Kubernetes secret 中。
身份和授权集成了 Azure AD,无需在集群内部存储密钥:
- AKS 的托管标识包括集群/控制平面标识和 kubelet 标识。授予 kubelet 对 ACR 的 AcrPull 权限 (az aks update –attach-acr
<acr>),以便节点可以安全地拉取镜像。 - 工作负载身份 (Workload identity) 使 Pod 能够使用映射到 Kubernetes 服务帐户的联合 Azure AD 凭据来访问 Azure 资源——无需节点级别的凭据或 sidecar。在集群上启用 OIDC 颁发者,创建一个用户分配的托管标识,为服务帐户/命名空间配置一个 FederatedIdentityCredential,并在应用程序中使用 Azure Identity SDK。这种方式取代了旧的 AAD Pod Identity 模型,并与开放标准保持一致。
- RBAC 用于管理 Kubernetes API 权限。当 AKS 与 Azure AD 集成时,通过 RoleBindings/ClusterRoleBindings 将 Kubernetes Roles/ClusterRoles 绑定到 Azure AD 用户或组。或者,启用 Azure RBAC for Kubernetes Authorization,以使用 Azure RBAC 角色(如 Azure Kubernetes Service RBAC Reader、Writer 和 Admin)来管理访问。遵循最小权限原则,按团队或工作负载分离命名空间,并通过基于组的绑定来控制对生产环境的访问。
从镜像到 AKS 的端到端流程是直接且安全的。构建多阶段镜像,用不可变的版本进行标记,推送到 ACR,然后通过清单或 Helm 部署到 AKS。AKS 使用 kubelet 托管标识从 ACR 拉取镜像,Pod 通过工作负载身份消费 Azure 资源。服务通过 ClusterIP/LoadBalancer 暴露,并由一个集中管理 TLS 和路由的 ingress 控制器进行优化。
实际问题场景
Adobe 的 Creative Cloud 团队正在将一个单体的媒体处理服务分解为微服务,目标是实现低延迟的全球交付和强化的供应链。
- 在 CI 中使用多阶段 Dockerfile 构建和存储镜像
- 使用 Docker 多阶段构建来编译媒体编解码器,并仅将运行时二进制文件复制到一个精简的基础镜像中,从而最小化镜像大小和 CVE 数量。将镜像以
<acr>.azurecr.io/processing/encoder:<git-sha>的格式推送到 ACR。这确保了可复现、安全的制品,并带有用于部署固定的不可变摘要。
- 强化镜像仓库并自动化补丁更新
- 创建一个 ACR Premium 仓库,并在每个托管 AKS 的虚拟网络中配置私有端点。启用到北欧和美国东部的异地复制,以保持镜像拉取在本地进行。配置 ACR Tasks,在上游基础镜像更新时触发重新构建,自动传播已打补丁的层。这在性能与安全之间取得了平衡,并减少了出口流量。
- 建立具有分离节点池和身份的 AKS
- 部署具有 Azure CNI 和系统/用户节点池的 AKS:一个用于控制平面附加组件的小型系统池,用于转码的启用 GPU 的用户池,以及用于 API 的通用目的池。启用 Azure AD 集成、OIDC 颁发者和工作负载身份。通过 az aks update –attach-acr 为 kubelet 标识分配 AcrPull 权限。这隔离了工作负载,实现了高效扩展,并消除了基于密钥的镜像拉取方式。
- 定义声明式部署和打包
- 为 Deployments、需要持久化的 StatefulSets、Services、HorizontalPodAutoscaler 和 PodDisruptionBudgets 编写 Kubernetes YAML。将编码器服务和 API 网关打包为 Helm chart,将它们作为 OCI 制品发布到 ACR,并使用 helm upgrade –install 并配合特定环境的 values 文件进行部署。这提供了版本一致的发布和简单的回滚。
- 暴露服务并强制执行 L7 安全
- 对内部微服务使用 ClusterIP,对公共 API 使用带有 Application Gateway Ingress Controller 的 LoadBalancer 服务。在 Application Gateway 上使用 WAF 策略终止 TLS,使用与 Azure DNS 集成的 cert-manager 来管理证书以应对 ACME 挑战,并根据主机/路径将流量路由到后端。这在实现企业级 L7 安全的同时,保持了 Kubernetes 原生的配置方式。
- 实现工作负载对 Azure 资源的安全访问
- 对于一个需要写入 Blob Storage 和读取密钥的缩略图服务,创建一个用户分配的托管标识,通过工作负载身份将其与服务帐户联合,并授予 Storage Blob Data Contributor 和 Key Vault Secrets User 角色。Pod 使用 Azure AD 进行身份验证,从而消除了挂载密钥的需要,并实现了细粒度、可审计的访问。
- 使用 ACI 处理批处理溢出
- 对于零星的、高优先级的批处理溢出,在一个注入了 VNet 的子网内触发 ACI 多容器组(编码器 + sidecar 指标收集器),并设置 restartPolicy: Never。这可以在不将 AKS 扩展到峰值的情况下吸收流量尖峰,并保留到存储帐户的私有数据路径。
每个选择都直接支持 Adobe 的目标:带有异地复制和私有端点的 ACR Premium 确保并加速了镜像拉取;具有专用节点池和工作负载身份的 AKS 强制执行了隔离和最小权限访问;Helm 和声明式 YAML 标准化了部署和回滚;带有 WAF 的 AGIC 提供了弹性、安全的 L7 ingress;而 ACI 则在没有持久集群成本的情况下处理突发批处理任务。
← Azure Cosmos DB · 所有领域 · Azure 身份验证、授权与安全性 →
练习这些题目 → · 在 ExamRoll.io 上限时练习 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
通过考试 →