高级 Azure Kubernetes 服务 (AKS) 微服务体系结构
此参考体系结构介绍了在 Azure Kubernetes 服务(AKS)上运行微服务时要考虑的多个配置。 本文讨论基于微服务的应用程序的网络策略配置、Pod 自动缩放和分布式跟踪。
此 体系结构基于 AKS 基线体系结构,Microsoft建议作为 AKS 基础结构的起点。 AKS 基线描述了基础结构功能,例如Microsoft Entra 工作负荷 ID、入口和出口限制、资源限制和其他安全的 AKS 基础结构配置。 本文未介绍这些功能。 建议先熟悉 AKS 基线体系结构,然后再继续处理微服务内容。
GitHub 中提供了此体系结构的参考实现。
体系结构
下载此体系结构的 Visio 文件。
如果想要从 AKS 上更基本的微服务示例开始,请参阅 AKS 上的微服务体系结构。
Workflow
此请求流实现发布者-订阅者、竞争使用者和网关路由云设计模式。 以下工作流与上图相对应:
提交 HTTPS 请求以安排无人机取件。 请求通过 Azure 应用程序网关传递到引入 Web 应用程序,该应用程序在 AKS 中作为群集内微服务运行。
引入 Web 应用程序生成消息并将其发送到 Azure 服务总线消息队列。
后端系统分配无人机并通知用户。 工作流微服务执行以下任务:
- 使用服务总线消息队列中的消息信息
- 向传递微服务发送 HTTPS 请求,该微服务将数据传递到 Azure Cache for Redis 外部数据存储
- 向无人机计划程序微服务发送 HTTPS 请求
- 向包微服务发送 HTTPS 请求,该请求将数据传递到 MongoDB 外部数据存储
体系结构使用 HTTPS GET 请求返回传递状态。 此请求通过应用程序网关传递到传递微服务。
交付微服务从 Azure Cache for Redis 读取数据。
组件
AKS 提供托管的 Kubernetes 群集。 使用 AKS 时,Azure 管理 Kubernetes API 服务器。 群集作员可以访问和管理 Kubernetes 节点或节点池。
此体系结构使用以下 AKS 基础结构功能:
Azure 虚拟网络 为运行虚拟机(VM)和应用程序提供隔离且高度安全的环境。 此参考体系结构使用对等互连的中心辐射型虚拟网络拓扑。 中心虚拟网络托管 Azure 防火墙和 Azure Bastion 子网。 辐射虚拟网络包含 AKS 系统和用户节点池子网和应用程序网关子网。
Azure 专用链接 分配特定的专用 IP 地址,以通过Microsoft主干网络访问 Azure 容器注册表和 Azure Key Vault。 平台即服务解决方案(如容器注册表和 Key Vault)可通过 AKS 系统和用户节点池子网中的专用终结点进行访问。
使用 Web 应用程序防火墙的应用程序网关(WAF)对 Web 应用程序的 Web 流量进行负载均衡。 在此体系结构中,应用程序网关将引入微服务公开为公共终结点。
Azure 防火墙 是云原生智能网络防火墙安全服务,可为 Azure 云工作负载提供威胁防护。 防火墙仅允许已获批准的服务和完全限定域名 (FQDN) 作为出口流量。 在此体系结构中,Azure 防火墙控制从微服务到虚拟网络外部资源的出站通信。
外部存储和其他组件
Key Vault 存储和管理 Azure 服务的安全密钥、机密值和证书。 在此体系结构中,Azure 密钥保管库存储 Azure Cosmos DB 和 Azure Redis 缓存的凭据。
容器注册表 存储可在 AKS 群集中运行的专用容器映像。 AKS 使用容器注册表Microsoft Entra 托管标识进行身份验证。 也可以使用其他容器注册表,例如 Docker Hub。 在此体系结构中,容器注册表存储微服务的容器映像。
Azure Cosmos DB 是完全托管的 NoSQL、关系数据库和矢量数据库。 微服务通常是无状态的,它们将自身的状态写入外部数据存储。 Azure Cosmos DB 具有用于 MongoDB、PostgreSQL 和 Cassandra 的开源 API。 在此体系结构中,Azure Cosmos DB 和 Azure Cosmos DB for MongoDB 充当每个微服务的数据存储。
服务总线 以服务和简单的混合集成的形式提供可靠的云消息传送。 服务总线支持微服务应用程序中常见的异步消息传送模式。 在此体系结构中,服务总线充当引入和工作流微服务之间的异步排队层。
Azure Redis 缓存 将缓存层添加到应用程序体系结构,以提高大量流量负载的速度和性能。 在此体系结构中,传递微服务使用 Azure Redis 缓存作为状态存储和 端缓存。
Azure Monitor 收集并存储指标和日志,包括应用程序遥测数据以及 Azure 平台和服务指标。 在此体系结构中,可以使用此数据来监视应用程序、设置警报和仪表板,以及执行故障的根本原因分析。
其他作支持系统组件
Helm 是 Kubernetes 的包管理器,可将 Kubernetes 对象捆绑到可以发布、部署、版本和更新的单个单元中。 在此体系结构中,使用 Helm 命令打包微服务并将其部署到 AKS 群集。
Key Vault 机密存储 CSI 驱动程序提供程序 机密存储 CSI 驱动程序的 Key Vault 提供程序允许通过 CSI 卷将密钥保管库作为机密存储与 AKS 群集集成。 在此体系结构中,Key Vault 机密装载为微服务容器中的卷,以便微服务可以检索 Azure Cosmos DB、Azure Redis 缓存和服务总线的凭据。
Flux 是适用于 Kubernetes 的开放且可扩展的持续交付解决方案,可在 AKS 中启用 GitOps。
替代方案
可以使用 适用于容器的应用程序网关 和 Istio 网关加载项等替代方法,而不是使用应用程序路由加载项。 有关 AKS 中的入口选项的比较,请参阅 AKS 中的入口。 用于容器的应用程序网关是应用程序网关入口控制器的演变,提供额外的功能,例如流量拆分和加权轮循机制负载均衡。
可以使用 ArgoCD 作为 GitOps 工具,而不是 Flux v2。 Flux v2 和 ArgoCD 都可用作群集扩展。
建议不要在密钥保管库中存储 Azure Cosmos DB 和 Azure Redis 缓存的凭据,而是使用托管标识进行身份验证,因为无密码身份验证机制更安全。 有关详细信息,请参阅 使用托管标识从 Azure VM 连接到 Azure Cosmos DB , 并使用 Microsoft Entra ID 访问服务总线资源对托管标识进行身份验证。 Azure Redis 缓存还支持 使用托管标识进行身份验证。
方案详细信息
上图中显示的 Fabrikam 无人机交付交付应用 示例实现了本文介绍的体系结构组件和做法。 在此示例中,虚构公司 Fabrikam Inc. 管理一个无人机群。 商家可以注册该服务,用户可以请求无人机收取要交付的商品。 当客户安排取件时,后端系统会分配无人机,并通知用户估计的交付时间。 交付正在进行时,客户可以跟踪无人机的位置,并查看持续更新的预计到达时间。
建议
您可以将以下建议应用于大多数场景。 除非有优先于这些建议的特定要求,否则请遵循这些建议。
使用应用程序路由加载项的托管 NGINX 入口
API 网关路由是一种常规微服务设计模式。 API 网关充当反向代理,用于将请求从客户端路由到微服务。 Kubernetes 入口 资源和 入口控制器 通过执行以下作来处理大多数 API 网关功能:
将客户端请求路由到正确的后端服务,以便为客户端提供单个终结点,并帮助将客户端与服务分离
将多个请求聚合到单个请求,以减少客户端和后端之间的聊天
卸载安全套接字层(SSL)终止、身份验证、IP 地址限制以及后端服务中的客户端速率限制或限制等功能
入口控制器简化了 AKS 群集的流量引入,提高了安全性和性能,并节省资源。 此体系结构使用 托管 NGINX 入口和应用程序路由加载项 进行入口控制。
建议将 入口控制器与内部(专用)IP 地址 和内部负载均衡器配合使用,并集成到 Azure 专用域名系统区域,以解析微服务的主机名。 将入口控制器的专用 IP 地址或主机名配置为应用程序网关中的后端池地址。 应用程序网关接收公共终结点上的流量,执行 WAF 检查,并将流量路由到入口专用 IP 地址。
应使用 自定义域名和 SSL 证书 配置入口控制器,以便对流量进行端到端加密。 应用程序网关接收 HTTPS 侦听器上的流量。 WAF 检查后,应用程序网关会将流量路由到入口控制器的 HTTPS 终结点。 所有微服务都应使用自定义域名和 SSL 证书进行配置,以便 AKS 群集中的微服务间通信也使用 SSL 进行保护。
多租户工作负荷或支持开发和测试环境的单个群集可能需要更多入口控制器。 应用程序路由加载项支持高级配置和自定义,包括 同一 AKS 群集中的多个入口控制器 ,并使用注释配置入口资源。
零信任网络策略
网络策略指定允许 AKS pod 如何相互通信以及与其他网络终结点通信。 默认情况下,允许传入和传出 pod 的所有入口和出口流量。 设计微服务如何相互通信和其他终结点时,请考虑遵循 零信任原则,其中访问任何服务、设备、应用程序或数据存储库需要显式配置。
实施零信任策略的一种策略是创建一个网络策略,该策略拒绝目标命名空间中所有 Pod 的所有入口和出口流量。 以下示例显示了 一个拒绝所有 策略,该策略适用于命名空间中的所有 backend-dev
Pod。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: backend-dev
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
实施限制性策略后,开始定义特定的网络规则,以允许流量传入和传出微服务中的每个 Pod。 在以下示例中,网络策略应用于命名空间中 backend-dev
具有匹配 app.kubernetes.io/component: backend
标签的任何 Pod。 除非该策略源自具有匹配 app.kubernetes.io/part-of: dronedelivery
标签的 Pod,否则该策略将拒绝任何流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: package-v010-dev-np-allow-ingress-traffic
namespace: backend-dev
spec:
podSelector:
matchLabels:
app.kubernetes.io/component: backend
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/part-of: dronedelivery
ports:
- port: 80
protocol: TCP
有关 Kubernetes 网络策略和潜在默认策略的更多示例的详细信息,请参阅 Kubernetes 文档中的网络策略。
Azure 提供了三个用于 强制实施网络策略的网络策略引擎:
- 使用由 Cilium 提供支持的 Azure CNI 的 AKS 群集的 Cilium
- Azure 网络策略管理器
- Calico,开源网络和网络安全解决方案
建议使用 Cilium 作为网络策略引擎。
资源配额
管理员使用资源配额来保留和限制开发团队或项目中的资源。 可以在命名空间上设置资源配额,并使用这些配额来设置以下资源的限制:
- 计算资源,例如 CPU 和内存或 GPU
- 存储资源,包括给定存储类的卷数或磁盘空间量
- 对象计数,例如可以创建的机密、服务或作业的最大数目
在累计资源请求或限制通过分配的配额后,不会再成功部署。
资源配额确保分配给命名空间的 pod 总数不能超过命名空间的资源配额。 前端不能对后端服务使用所有资源,后端不能对前端服务使用所有资源。
定义资源配额时,命名空间中创建的所有 pod 必须在其 pod 规范中提供限制或请求。 如果它们未提供这些值,则会拒绝部署。
以下示例演示一个 Pod 规范,用于设置资源配额请求和限制:
requests:
cpu: 100m
memory: 350Mi
limits:
cpu: 200m
memory: 500Mi
有关资源配额的详细信息,请参阅:
自动缩放
Kubernetes 支持 自动缩放 ,以增加分配给部署的 Pod 数或增加群集中的节点数,以增加可用计算资源总数。 自动缩放是一种自我纠正的自治反馈系统。 可以手动缩放 Pod 和节点,但自动缩放可最大程度地减少服务在高负载时达到资源限制的可能性。 自动缩放策略必须同时考虑 Pod 和节点。
群集自动缩放
群集自动缩放程序(CA)可缩放节点数。 如果由于资源约束而无法计划 Pod,群集自动缩放程序会预配更多节点。 定义最少数量的节点可使 AKS 群集和工作负载保持正常运行,而定义最多数量的节点可以应对繁重的流量。 CA 每隔几秒钟检查一次挂起的 pod 或空节点,并相应地缩放 AKS 群集。
以下示例显示了 Bicep 模板中的 CA 配置:
autoScalerProfile: {
'scan-interval': '10s'
'scale-down-delay-after-add': '10m'
'scale-down-delay-after-delete': '20s'
'scale-down-delay-after-failure': '3m'
'scale-down-unneeded-time': '10m'
'scale-down-unready-time': '20m'
'scale-down-utilization-threshold': '0.5'
'max-graceful-termination-sec': '600'
'balance-similar-node-groups': 'false'
expander: 'random'
'skip-nodes-with-local-storage': 'true'
'skip-nodes-with-system-pods': 'true'
'max-empty-bulk-delete': '10'
'max-total-unready-percentage': '45'
'ok-total-unready-count': '3'
}
Bicep 模板中的以下行设置了群集自动缩放程序的示例最小节点和最大节点数:
minCount: 2
maxCount: 5
水平 Pod 自动缩放
水平 Pod 自动缩放程序(HPA)根据观察到的 CPU、内存或自定义指标缩放 Pod。 若要配置水平 Pod 缩放,请在 Kubernetes 部署 Pod 规范中指定目标指标和最小和最大副本数。 负载测试服务以确定这些数字。
CA 和 HPA 协同工作,因此在 AKS 群集中启用两个自动缩放程序选项。 HPA 缩放应用程序,而 CA 缩放基础结构。
以下示例为 HPA 设置资源指标:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: delivery-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: delivery
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
HPA 查看正在运行的 Pod 中消耗的实际资源或其他指标。 CA 为尚未计划的 Pod 预配节点。 因此,CA 会按照 Pod 规范中指定的请求资源来查看请求的资源。 使用负载测试微调这些值。
有关详细信息,请参阅 AKS 中应用程序的缩放选项。
垂直 Pod 自动缩放
垂直 Pod 自动缩放程序(VPA)会自动调整 Pod 的 CPU 和内存请求,以匹配工作负荷的使用模式。 配置后,VPA 会根据过去的使用情况自动设置每个工作负荷的容器的资源请求和限制。 VPA 使 CPU 和内存可用于其他 Pod,并帮助确保有效利用 AKS 群集。
在此体系结构中,VPA 会根据微服务的过去使用情况增加 CPU 和内存请求和限制。 例如,如果工作流微服务与其他微服务相比消耗更多的 CPU,VPA 可以监视此使用情况并增加工作流微服务的 CPU 限制。
Kubernetes 事件驱动的自动缩放
Kubernetes 事件驱动自动缩放程序(KEDA)加载项使事件驱动的自动缩放能够缩放微服务,以可持续且经济高效的方式满足需求。 例如,当服务总线队列中的消息数超过特定阈值时,KEDA 可以纵向扩展微服务。
在 Fabrikam 无人机交付示例中,KEDA 根据服务总线队列深度和引入微服务输出横向扩展工作流微服务。 有关 Azure 服务的 KEDA 缩放程序列表,请参阅 AKS 上的与 KEDA 的集成。
运行状况探测
Kubernetes 对发往与服务标签选择器匹配的 pod 的流量进行负载均衡。 只有成功启动且正常的 pod 才能收到流量。 如果某个容器崩溃,Kubernetes 会删除 pod,并计划替代的 pod。
Kubernetes 定义了 Pod 可以公开的三种类型的运行状况探测:
就绪情况探测告知 Kubernetes Pod 是否已准备好接受请求。
实时性探测告知 Kubernetes 是否应删除 Pod 并启动新实例。
启动探测告知 Kubernetes 是否已启动 Pod。
运行情况探测处理仍在运行但运行不正常且应回收的 pod。 例如,如果为 HTTP 请求提供服务的容器挂起,则该容器不会崩溃,而是停止为请求提供服务。 HTTP 实时性探测停止响应,这提醒 Kubernetes 重启 Pod。
有时,尽管某个 pod 已成功启动,但不一定已准备好接收流量。 例如,容器中运行的应用程序可能正在执行初始化任务。 就绪情况探测指示 pod 是否已准备好接收流量。
微服务应在其代码中公开终结点,以便进行运行状况探测,并专门针对它们执行的检查进行延迟和超时。 HPA 公式依赖于 Pod 的就绪阶段,因此运行状况探测存在且准确至关重要。
监视
在微服务应用程序中,应用程序性能管理(APM)监视对于检测异常、诊断问题以及快速了解服务之间的依赖关系至关重要。 Application Insights 是 Azure Monitor 的一项功能,它为以 .NET Core、Node.js、Java 和其他许多应用程序语言编写的实时应用程序提供 APM 监视。
Azure 提供了用于监视微服务工作负荷的各种机制:
用于收集指标的托管 Prometheus。 使用 Prometheus 监视和警报基础结构和工作负载的性能。
适用于 Prometheus 和容器见解的 Azure Monitor 托管服务协同工作,以全面监视 Kubernetes 环境。
用于群集和微服务可视化的托管 Grafana。
若要在 Kubernetes 中上下文化服务遥测,可将 Azure Monitor 遥测与 AKS 集成,以从控制器、节点、容器和容器和节点日志收集指标。 无需 更改代码即可将 Application Insights 与 AKS 集成。
注意事项
这些注意事项实施 Azure 架构良好的框架的支柱原则,即一套可用于改进工作负荷质量的指导原则。 有关详细信息,请参阅 Well-Architected Framework。
安全性
安全性提供针对故意攻击和滥用宝贵数据和系统的保证。 有关详细信息,请参阅 安全的设计评审清单。
规划安全性时,请考虑以下几点。
在 AKS 群集中使用 部署安全措施 。 部署安全措施通过 Azure Policy 控件在 AKS 群集中强制实施 Kubernetes 最佳做法。
将安全扫描集成到微服务生成和部署管道中。 使用 Microsoft Defender for Cloud DevOps 安全性管理 DevOps 环境。 使用 无代理代码扫描 并运行 静态代码分析工具 作为持续集成和持续部署(CI/CD)管道的一部分,以便可以在生成和部署过程中识别和解决微服务代码漏洞。
AKS Pod 使用存储在 Microsoft Entra ID 中的 工作负荷标识 来自行进行身份验证。 应使用工作负荷标识,因为它不需要客户端密码。
使用托管标识时,应用程序可以在运行时快速获取 Azure 资源管理器 OAuth 2.0 令牌。 它不需要密码或连接字符串。 在 AKS 中,可以使用 工作负荷 ID 将标识分配给各个 Pod。
应该为微服务应用程序中的每个服务分配唯一的工作负载标识,以便于完成最低特权 RBAC 分配。 应该只将标识分配给需要标识的服务。
如果某个应用程序组件需要 Kubernetes API 访问权限,请确保将应用程序 Pod 配置为使用具有适当范围的 API 访问权限的服务帐户。 有关详细信息,请参阅 管理 Kubernetes 服务帐户。
并非所有 Azure 服务都支持使用 Microsoft Entra ID 进行数据平面身份验证。 若要存储这些服务的凭据或应用程序机密、非Microsoft服务或 API 密钥,请使用 Key Vault。 Key Vault 提供集中管理、访问控制、静态加密以及对所有密钥和机密的审核。
在 AKS 中,可将 Key Vault 中的一个或多个机密装载为一个卷。 然后,pod 可以像读取普通卷一样读取密钥保管库机密。 有关详细信息,请参阅在 AKS 群集中对机密存储 CSI 驱动程序使用 Key Vault 提供程序。 建议为每个微服务维护单独的密钥保管库。 引用实现为每个微服务使用单独的密钥保管库。
如果微服务需要与群集外部的资源(例如外部 URL)通信,请通过 Azure 防火墙控制访问。 如果微服务不需要进行任何出站调用,请使用 网络隔离群集。
启用 Microsoft Defender for Containers 以提供安全状况管理、微服务漏洞评估、运行时威胁防护和其他安全功能。
成本优化
成本优化侧重于减少不必要的开支和提高运营效率的方法。 有关详细信息,请参阅 成本优化的设计评审清单。
Well-Architected Framework 中的“成本优化”部分介绍了成本注意事项。
使用 Azure 定价计算器估算特定方案的成本。
在免费层中,AKS 不与 Kubernetes 群集的部署、管理和作相关的成本。 只需为群集使用的 VM 实例、存储和网络资源付费。 群集自动缩放可以通过删除空节点或未使用的节点来显著降低群集成本。
考虑将 AKS 免费层用于开发工作负荷,并将 标准层和高级层 用于生产工作负荷。
考虑启用 AKS 成本分析,以便通过 Kubernetes 特定构造进行精细群集基础结构成本分配。
卓越运营
卓越运营涵盖部署应用程序并使其在生产环境中运行的运营流程。 有关详细信息,请参阅 卓越运营的设计评审清单。
规划可管理性时,请考虑以下几点。
通过自动部署管道管理 AKS 群集基础结构。 此体系结构的 参考实现 提供了一个 GitHub Actions 工作流,可在生成管道时引用该工作流。
工作流文件仅将基础结构(而不会将工作负载)部署到已存在的虚拟网络和 Microsoft Entra 配置中。 通过单独部署基础结构和工作负荷,可以解决不同的生命周期和作问题。
如果发生区域故障,请考虑工作流作为部署到另一个区域的机制。 生成管道,以便可以在具有参数和输入更改的新区域中部署新群集。
性能效率
性能效率是指工作负荷能够高效地缩放以满足用户需求。 有关详细信息,请参阅 性能效率的设计评审清单。
规划可伸缩性时,请考虑以下几点。
不要将自动缩放和副本数量的命令式或声明式管理相结合。 用户和自动缩放程序都尝试修改副本数可能会导致意外行为。 启用 HPA 后,请将副本数减少到要部署的最小数量。
Pod 自动缩放的副作用是,当应用程序横向扩展或横向扩展时,可能会频繁创建或逐出 Pod。若要缓解这些影响,请执行以下步骤:
- 使用就绪情况探测来让 Kubernetes 知道新 pod 已准备好接受流量。
- 使用 pod 中断预算来限制每次可从服务中逐出的 pod 数。
如果微服务存在大量出站流,请考虑使用 网络地址转换网关 以避免源网络地址转换端口耗尽。
多租户或其他高级工作负荷可能具有节点池隔离要求,这些要求需要更多和可能更小的子网。 有关详细信息,请参阅 添加具有唯一子网的节点池。 组织对其中心辐射型实现采用不同的标准。 请务必遵循组织的准则。
请考虑将 CNI 与覆盖网络配合使用 ,以节省网络地址空间。
后续步骤
- AKS 的
简介 - 什么是 Azure 虚拟网络?
- 什么是专用链接?
- 什么是应用程序网关?
- 什么是 Azure Bastion?
- Key Vault 简介
- 容器注册表简介
- Azure Cosmos DB 简介
- Azure Monitor 概述