category
此参考架构显示了部署到Azure Kubernetes Service(AKS)的微服务应用程序。它描述了一个基本的AKS配置,可以作为大多数部署的起点。本文假设您具备Kubernetes的基本知识。本文主要关注在AKS上运行微服务架构的基础设施和DevOps考虑因素。有关如何设计微服务的指导,请参阅在Azure上构建微服务。
GitHub徽标此架构的参考实现可在GitHub上获得。
架构
显示AKS参考架构的图。
下载此体系结构的Visio file文件。
如果您希望看到一个基于AKS Baseline架构的更高级的微服务示例,请参阅高级Azure Kubernetes服务(AKS)微服务架构
通讯流
该架构由以下组件组成。
- Azure Kubernetes服务(AKS)。AKS是托管在Azure云中的Kubernetes集群。Azure管理Kubernetes API服务,您只需要管理代理节点。
- 虚拟网络。默认情况下,AKS创建一个代理节点连接到的虚拟网络。您可以首先为更高级的场景创建虚拟网络,这使您可以控制子网配置、本地连接和IP地址等。有关更多信息,请参阅在Azure Kubernetes Service(AKS)中配置高级网络。
- 进入。入口服务器向集群内的服务公开HTTP(S)路由。有关更多信息,请参阅下面的API网关部分。
- Azure负载平衡器。创建AKS集群后,集群就可以使用负载均衡器了。然后,一旦部署了NGINX服务,负载均衡器将配置一个新的公共IP,该IP将位于您的入口控制器之前。这样,负载均衡器将互联网流量路由到入口。
- 外部数据存储。微服务通常是无状态的,并将状态写入外部数据存储,如Azure SQL数据库或Azure Cosmos数据库。
- Microsoft Entra ID。AKS使用Microsoft Entra标识来创建和管理其他Azure资源,如Azure负载平衡器。还建议在客户端应用程序中使用Microsoft Entra ID进行用户身份验证。
- Azure容器注册表。使用容器注册表存储部署到集群的私有Docker镜像。AKS可以使用其Microsoft Entra身份向容器注册表进行身份验证。AKS不需要Azure容器注册表。您可以使用其他容器注册表,如Docker Hub。只需确保您的容器注册表与工作负载的服务级别协议(SLA)相匹配或超过SLA。
- Azure管道。Azure管道是Azure DevOps服务的一部分,运行自动化构建、测试和部署。您还可以使用第三方CI/CD解决方案,如Jenkins。
- Helm。Helm是Kubernetes的包管理器,它是一种将Kubernetes对象捆绑和泛化到一个可以发布、部署、版本控制和更新的单元中的方法。
- Azure监视器。Azure Monitor收集并存储Azure服务的指标和日志、应用程序遥测和平台指标。使用此数据监视应用程序、设置警报、仪表板并执行故障的根本原因分析。Azure Monitor与AKS集成,从控制器、节点和容器收集指标。
注意事项
设计
此参考架构侧重于微服务架构,尽管许多推荐的做法适用于在AKS上运行的其他工作负载。
微服务
微服务是一个松散耦合、可独立部署的代码单元。微服务通常通过定义良好的API进行通信,并且可以通过某种形式的服务发现进行发现。即使Pod四处移动,该服务也应始终可访问。Kubernetes Service对象是在Kubernetes中建模微服务的自然方式。
API网关
API网关是一种通用的微服务设计模式。API网关位于外部客户端和微服务之间。它充当反向代理,将请求从客户端路由到微服务。它还可以执行各种跨领域任务,如身份验证、SSL终止和速率限制。有关更多信息,请参阅:
在Kubernetes中,API网关的功能主要由Ingress控制器处理。有关注意事项,请参阅Ingress部分。
数据存储
在微服务架构中,服务不应该共享数据存储解决方案。每个服务都应该管理自己的数据集,以避免服务之间隐藏的依赖关系。数据分离有助于避免服务之间的无意耦合,当服务共享相同的底层数据模式时,可能会发生这种情况。此外,当服务管理自己的数据存储时,它们可以根据自己的特定需求使用正确的数据存储。
有关更多信息,请参阅设计微服务:数据考虑因素。
避免在本地集群存储中存储持久数据,因为这会将数据与节点联系起来。相反,使用外部服务,如Azure SQL数据库或Azure Cosmos数据库。另一种选择是使用Azure磁盘或Azure文件将持久数据卷装载到解决方案。
有关更多信息,请参阅Azure Kubernetes Service中应用程序的存储选项。
服务对象
Kubernetes Service对象提供了一组与服务可发现性的微服务要求相匹配的功能:
- IP地址。Service对象为一组Pod(ReplicaSet)提供静态内部IP地址。当Pod被创建或移动时,服务总是可以在这个内部IP地址上访问。
- 负载平衡。发送到服务IP地址的流量对Pod进行负载平衡。
- 服务发现。服务由Kubernetes DNS服务分配内部DNS条目。这意味着API网关可以使用DNS名称调用后端服务。相同的机制可用于服务到服务的通信。DNS条目按命名空间组织,因此如果您的命名空间对应于有界上下文,则服务的DNS名称将自然映射到应用程序域。
下图显示了服务和Pod之间的概念关系。到端点IP地址和端口的实际映射是由Kubernetes网络代理kube-proxy完成的。
显示服务和Pod的图表。
Ingress
在Kubernetes中,Ingress控制器可能实现API网关模式。在这种情况下,Ingress和Ingress控制器协同工作以提供以下功能:
- 将客户端请求路由到正确的后端服务。此路由为客户端提供了一个端点,并有助于将客户端与服务解耦。
- 将多个请求聚合为一个请求,以减少客户端和后端之间的聊天。
- 从后端服务卸载功能,如SSL终止、身份验证、IP限制或客户端速率限制(节流)。
Ingress抽象了代理服务器的配置设置。您还需要一个Ingress控制器,它提供Ingress的底层实现。Nginx、HAProxy、Traefik和Azure应用程序网关等都有Ingress控制器。
Ingress资源可以通过不同的技术来实现。为了协同工作,它们需要部署为集群内的Ingress控制器。它作为边缘路由器或反向代理运行。反向代理服务器是一个潜在的瓶颈或单点故障,因此始终部署至少两个副本以实现高可用性。
通常,配置代理服务器需要复杂的文件,如果你不是专家,这些文件可能很难调整。因此,Ingress控制器提供了一个很好的抽象。Ingress控制器还可以访问Kubernetes API,因此它可以做出关于路由和负载平衡的智能决策。例如,Nginx入口控制器绕过kube-proxy网络代理。
另一方面,如果您需要完全控制设置,您可能希望绕过此抽象并手动配置代理服务器。有关更多信息,请参阅将Nginx或HAProxy部署到Kubernetes。
注:
对于AKS,您还可以使用Azure应用程序网关,使用应用程序网关入口控制器(AGIC)。Azure应用程序网关可以执行第7层路由和SSL终止。它还内置了对Web应用程序防火墙的支持。如果您的AKS集群正在使用CNI网络,则应用网关可以部署到集群虚拟网络的子网中,也可以部署在与AKS虚拟网络不同的虚拟网络中,但是,这两个虚拟网络必须相互连接。AGIC还支持Kubenet网络插件。使用Kubenet模式时,入口控制器需要管理应用网关子网中的路由表,以将流量引导到pod IP。有关更多信息,请参阅如何在Application Gateway和AKS之间设置网络。
有关Azure中负载平衡服务的信息,请参阅Azure中负载均衡选项概述。
TLS/SSL加密
在常见的实现中,Ingress控制器用于SSL终止。因此,作为部署Ingress控制器的一部分,您需要创建一个TLS证书。仅将自签名证书用于开发/测试目的。有关更多信息,请参阅创建HTTPS入口控制器并在Azure Kubernetes Service(AKS)上使用自己的TLS证书。
对于生产工作负载,从受信任的证书颁发机构(CA)获取签名证书。有关生成和配置Let's Encrypt证书的信息,请参阅在Azure Kubernetes Service(AKS)中创建具有静态公共IP地址的入口控制器。
您可能还需要根据组织的政策轮换证书。有关信息,请参阅Azure Kubernetes服务(AKS)中的旋转证书。
命名空间
使用命名空间组织群集中的服务。Kubernetes集群中的每个对象都属于一个命名空间。默认情况下,当您创建新对象时,它会进入默认名称空间。但是,创建更具描述性的名称空间来帮助组织集群中的资源是一种很好的做法。
首先,名称空间有助于防止命名冲突。当多个团队将微服务部署到同一个集群中时,可能有数百个微服务,如果它们都进入同一个命名空间,就很难管理。此外,命名空间允许您:
- 对命名空间应用资源约束,以便分配给该命名空间的Pod总数不能超过命名空间的资源配额。
- 在命名空间级别应用策略,包括RBAC和安全策略。
对于微服务架构,考虑将微服务组织到有界上下文中,并为每个有界上下文创建名称空间。例如,与“订单履行”有界上下文相关的所有微服务都可以进入同一个命名空间。或者,为每个开发团队创建一个名称空间。
将实用程序服务放入它们自己的单独命名空间中。例如,您可以部署Elasticsearch或Prometheus进行集群监控,或部署Tiller进行Helm。
健康探测器
Kubernetes定义了pod可以公开的两种类型的健康探测器:
- Readiness探测:告诉Kubernetes pod是否准备好接受请求。
- Liveness探测:告诉Kubernetes是否应该移除一个pod并启动一个新实例。
在考虑探测器时,回忆一下服务在Kubernetes中是如何工作的是很有用的。服务有一个标签选择器,可以匹配一组(零个或多个)Pod。Kubernetes负载平衡了与选择器匹配的Pod的流量。只有成功启动且健康的Pod才能接收流量。如果容器崩溃,Kubernetes会杀死pod并安排替换。
有时,即使pod成功启动,它也可能没有准备好接收流量。例如,可能存在初始化任务,其中在容器中运行的应用程序将内容加载到内存中或读取配置数据。要指示pod健康但尚未准备好接收流量,请定义一个准备就绪探测。
Liveness探测器处理吊舱仍在运行但不健康且应回收的情况。例如,假设一个容器正在处理HTTP请求,但由于某种原因挂起。容器没有崩溃,但它已停止为任何请求提供服务。如果定义了HTTP活性探测,探测将停止响应,并通知Kubernetes重新启动pod。
以下是设计探头时的一些注意事项:
- 如果你的代码启动时间很长,那么在启动完成之前,活性探测可能会报告失败。为防止此探测失败,请使用initialDelaySeconds设置,该设置会延迟探测启动。
- 活性探针没有帮助,除非重新启动pod可能会将其恢复到健康状态。您可以使用活性探测来缓解内存泄漏或意外死锁,但重启将立即再次失败的pod是没有意义的。
- 有时,准备就绪探测器用于检查依赖服务。例如,如果一个pod依赖于数据库,探测器可能会检查数据库连接。然而,这种方法可能会产生意想不到的问题。外部服务可能因某种原因暂时不可用。这将导致服务中所有Pod的就绪性探测失败,导致所有Pod都从负载平衡中删除,从而在上游产生级联故障。更好的方法是在您的服务中实现重试处理,以便您的服务能够从瞬态故障中正确恢复。
资源限制
资源争用会影响服务的可用性。为容器定义资源约束,这样单个容器就不会淹没集群资源(内存和CPU)。对于非容器资源,如线程或网络连接,考虑使用隔板模式来隔离资源。
使用资源配额限制命名空间允许的总资源。这样,前端就不会耗尽后端服务的资源,反之亦然。
安全
基于角色的访问控制(RBAC)
Kubernetes和Azure都有基于角色的访问控制(RBAC)机制:
- Azure RBAC控制对Azure中资源的访问,包括创建新Azure资源的能力。权限可以分配给用户、组或服务主体。(服务主体是应用程序使用的安全标识。)
- Kubernetes RBAC控制对Kubernetesneneneba API的权限。例如,创建Pod和列出Pod是可以通过Kubernetes RBAC授权(或拒绝)给用户的操作。要向用户分配Kubernetes权限,您可以创建角色和角色绑定:
- 角色是在命名空间内应用的一组权限。权限被定义为对资源(Pod、部署等)的动词(获取、更新、创建、删除)。
- RoleBinding将用户或组分配给角色。
- 还有一个ClusterRole对象,它类似于Role,但适用于整个集群,跨越所有命名空间。要将用户或组分配给ClusterRole,请创建ClusterRoleBinding。
AKS集成了这两种RBAC机制。创建AKS群集时,可以将其配置为使用Microsoft Entra ID进行用户身份验证。有关如何设置此项的详细信息,请参阅将Microsoft Entra ID与Azure Kubernetes服务集成。
一旦配置好,想要访问Kubernetes API(例如,通过kubectl)的用户必须使用他们的Microsoft Entra凭据登录。
默认情况下,Microsoft Entra用户无权访问群集。为了授予访问权限,集群管理员创建了引用Microsoft Entra用户或组的RoleBinding。如果用户没有特定操作的权限,它将失败。
如果默认情况下用户没有访问权限,那么集群管理员首先如何有权创建角色绑定?AKS集群实际上有两种用于调用Kubernetes API服务器的凭据:集群用户和集群管理员。群集管理员凭据授予对群集的完全访问权限。Azure CLI命令az aks get credentials-admin下载集群管理员凭据并将其保存到kubeconfig文件中。集群管理员可以使用此kubeconfig创建角色和角色绑定。
与其在Kubernetes中本地管理Kubernetes集群角色和RoleBinding对象,不如使用Azure RBAC进行Kubernetes授权。这允许跨Azure资源、AKS和Kubernetes资源进行统一管理和访问控制。这些Azure RBAC角色分配可以针对集群或集群内的命名空间,以实现更细粒度的访问控制。Azure RBAC支持一组有限的默认权限,您可以将其与管理角色和角色绑定的本机Kubernetes机制相结合,以支持高级或更细粒度的访问模式。启用后,Microsoft Entra主体将仅由Azure RBAC验证,而常规Kubernetes用户和服务帐户将仅由Kubernetes RBAC验证。
由于集群管理员凭据非常强大,请使用Azure RBAC限制对它们的访问:
- “Azure Kubernetes服务集群管理员角色”有权下载集群管理员凭据。只应将群集管理员分配给此角色。
- “Azure Kubernetes服务群集用户角色”有权下载群集用户凭据。非管理员用户可以被分配到此角色。该角色不授予集群内Kubernetes资源的任何特定权限,只允许用户连接到API服务器。
在定义RBAC策略(Kubernetes和Azure)时,请考虑组织中的角色:
- 谁可以创建或删除AKS集群并下载管理员凭据?
- 谁可以管理集群?
- 谁可以在命名空间中创建或更新资源?
使用Roles和RoleBinding,而不是ClusterRoles和ClusterRoleBinding,按命名空间限定Kubernetes RBAC权限是一种很好的做法。
最后,还有一个问题是,AKS集群有什么权限来创建和管理Azure资源,如负载均衡器、网络或存储。为了使用Azure API进行身份验证,集群使用Microsoft Entra服务主体。如果在创建集群时没有指定服务主体,则会自动创建一个。但是,首先创建服务主体并为其分配最小RBAC权限是一种很好的安全做法。有关更多信息,请参阅Azure Kubernetes service的服务主体。
机密管理和应用程序凭据
应用程序和服务通常需要凭据,以允许它们连接到外部服务,如Azure存储或SQL数据库。挑战在于保护这些凭据的安全,而不是泄露它们。
对于Azure资源,一种选择是使用托管身份。托管身份的概念是,应用程序或服务具有存储在Microsoft Entra ID中的身份,并使用此身份向Azure服务进行身份验证。应用程序或服务在Microsoft Entra ID中为其创建了服务主体,并使用OAuth 2.0令牌进行身份验证。执行过程代码可以透明地获取要使用的令牌。这样,您就不需要存储任何密码或连接字符串。您可以通过使用Microsoft Entra工作负载ID(预览版)将Microsoft Entra标识分配给各个Pod,在AKS中使用托管标识。
目前,并非所有Azure服务都支持使用托管身份进行身份验证。有关列表,请参阅支持Microsoft Entra身份验证的Azure服务。
即使使用托管身份,您也可能需要存储一些凭据或其他应用程序机密,无论是不支持托管身份的Azure服务、第三方服务、API密钥等。以下是安全存储机密的一些选项:
- Azure密钥库。在AKS中,您可以将密钥库中的一个或多个密钥挂载为卷。该卷从密钥库读取机密。然后,吊舱可以像普通卷一样读取秘密。有关更多信息,请参阅在AKS群集中使用Azure密钥库提供程序进行密钥存储CSI驱动程序。
- pod通过使用工作负载标识或使用用户或系统分配的托管标识进行身份验证。有关更多注意事项,请参阅提供身份以访问Azure密钥库提供程序的Secrets Store CSI驱动程序。
- HashiCorp保险库。Kubernetes应用程序可以使用Microsoft Entra管理的身份与HashiCorp Vault进行身份验证。请参阅HashiCorp Vault讲Microsoft Entra ID。您可以将Vault本身部署到Kubernetes,考虑在与应用程序集群分离的专用集群中运行它。
- Kubernetes的秘密。另一种选择是简单地使用Kubernetes secrets。此选项最容易配置,但也有一些挑战。秘密存储在etcd中,这是一个分布式键值存储。AKS在静止时加密etcd。微软管理加密密钥。
使用像HashiCorp Vault或Azure Key Vault这样的系统提供了几个优点,例如:
- 集中控制秘密。
- 确保所有秘密在静止状态下加密。
- 集中密钥管理。
- 秘密的访问控制。
- 审计
容器和编排器安全
以下是保护吊舱和容器的推荐做法:
- 威胁监控:使用Microsoft Defender for Containers(或第三方功能)监控威胁。如果您在虚拟机上托管容器,请将Microsoft Defender用于服务器或第三方功能。此外,您可以将Azure Monitor中的容器监控解决方案的日志集成到Microsoft Sentinel或现有的SIEM解决方案中。
- 漏洞监控:使用Microsoft Defender for Cloud或通过Azure Marketplace提供的第三方解决方案,持续监控图像和正在运行的容器中的已知漏洞。
- 使用ACR任务(Azure容器注册表的一项功能)自动修补映像。容器图像是由层构建的。基础层包括操作系统映像和应用程序框架映像。NET核心或Node.js。基础映像通常由应用程序开发人员在上游创建,并由其他项目维护人员维护。当这些映像在上游进行修补时,更新、测试和重新部署自己的映像非常重要,这样就不会留下任何已知的安全漏洞。ACR任务可以帮助自动化此过程。
- 将映像存储在受信任的私有注册表中,如Azure容器注册表或Docker受信任注册表。在Kubernetes中使用验证准入webhook,以确保Pod只能从受信任的注册表中提取映像。
- 应用最小特权原则
- 不要在特权模式下运行容器。特权模式允许容器访问主机上的所有设备。
- 如果可能的话,避免在容器内以root身份运行进程。从安全角度来看,容器不提供完全隔离,因此最好以非特权用户身份运行容器进程。
DevOps
此参考架构提供了一个Azure资源管理器模板,用于配置云资源及其依赖关系。使用[AAzure资源管理器模板][arm模板],您可以使用Azure DevOps服务在几分钟内配置不同的环境,例如复制生产场景。这允许您节省成本,并仅在需要时配置负载测试环境。
考虑遵循工作负载隔离标准来构建ARM模板,工作负载通常被定义为任意功能单元;例如,您可以为集群设置一个单独的模板,然后为依赖服务设置另一个模板。工作负载隔离使DevOps能够执行持续集成和持续交付(CI/CD),因为每个工作负载都由其相应的DevOps团队关联和管理。
部署(CI/CD)注意事项
以下是微服务架构健壮的CI/CD流程的一些目标:
- 每个团队都可以独立构建和部署其拥有的服务,而不会影响或中断其他团队。
- 在将新版本的服务部署到生产环境之前,它会被部署到dev/test/QA环境中进行验证。每个阶段都有质量门。
- 新版本的服务可以与上一版本并行部署。
- 有足够的访问控制策略。
- 对于容器化工作负载,您可以信任部署到生产环境的容器映像。
要了解有关挑战的更多信息,请参阅微服务架构的CI/CD。
有关具体建议和最佳实践,请参阅Kubernetes上微服务的CI/CD。
成本优化
使用Azure定价计算器估算成本。其他考虑因素在Microsoft Azure良好架构框架的成本部分进行了描述。
对于此架构中使用的一些服务,需要考虑以下几点。
Azure Kubernetes服务(AKS)
在Kubernetes集群的部署、管理和操作中,AKS没有相关成本。您只需为Kubernetes集群消耗的虚拟机实例、存储和网络资源付费。
要估算所需资源的成本,请参阅容器服务计算器。
Azure负载平衡器
您只需为配置的负载平衡和出站规则的数量付费。入站NAT规则是免费的。未配置规则时,标准负载平衡器不收取小时费用。
有关更多信息,请参阅Azure负载平衡器定价。
Azure管道
此参考架构仅使用Azure管道。Azure将Azure Pipeline作为单独的服务提供。您可以获得一个免费的Microsoft托管作业,每月有1800分钟的CI/CD,以及一个每月无限制分钟的自托管作业,额外的作业需要收费。有关更多信息,请参阅Azure DevOps服务定价。
Azure监视器
对于Azure Monitor日志分析,您需要为数据摄取和保留付费。有关详细信息,请参阅Azure Monitor定价。
部署此场景
要部署此架构的参考实现,请按照GitHub仓库中的步骤进行操作。
Next steps
Related resources
- 登录 发表评论
- 3 次浏览
最新内容
- 8 hours ago
- 11 hours ago
- 11 hours ago
- 3 days ago
- 3 days 9 hours ago
- 3 days 10 hours ago
- 3 days 10 hours ago
- 3 days 10 hours ago
- 1 week ago
- 1 week ago