你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure 应用服务环境进行企业部署

Microsoft Entra ID
Azure 应用程序网关
Azure 应用服务
Azure 防火墙
Azure 虚拟网络
Azure 专用链接

此参考体系结构演示了使用应用服务环境版本 3 的常见企业工作负载。 它还介绍了增强工作负载安全性的最佳做法。

注意

本体系结构的主要组件是应用服务环境版本 3。 现已推出版本 3。 版本 1 和 2 将于 2024 年 8 月 31 日停用

GitHub logoGitHub 中提供了本体系结构的参考实现。

体系结构

Diagram that shows an architecture for an App Service Environment deployment.

下载此体系结构的 Visio 文件

工作流

应用服务环境版本 3 提供的功能与早期版本不同,并且优于这些版本。 有关详细信息,请参阅功能差异。 可以通过两种方式部署应用服务环境:

  • 作为具有公共 IP 地址的外部应用服务环境
  • 作为内部 IP 地址属于内部负载均衡器 (ILB) 的内部应用服务环境

此参考体系结构会在内部应用服务环境(也称为 ILB 应用服务环境)中部署企业 Web 应用程序。 当方案要求执行以下操作时,请使用 ILB 应用服务环境:

  • 在云中托管具有增强安全性的 Intranet 应用程序,并通过站点到站点 VPN 或 Azure ExpressRoute 访问它们。
  • 使用 Web 应用程序防火墙 (WAF) 为应用提供保护层。
  • 在云端托管未在公用 DNS 服务器中列出的应用。
  • 创建与 Internet 隔离且前端应用可以与之以高度安全的方式集成的后端应用。

应用服务环境必须始终部署在企业虚拟网络中其自己的子网中,以严格控制传入和传出流量。 在此子网中,应用服务应用程序部署在一个或多个应用服务计划中,这些计划是运行应用所需的物理资源的集合。 根据复杂性和资源要求,可以在多个应用之间共享应用服务计划。 本参考实现会部署一个名为 Voting App 的 Web 应用,该应用可与专用 Web API 和函数交互。 它还将部署一个名为 Test App(测试应用)的虚构 Web 应用来演示多应用部署。 每个应用服务应用托管在其自身的应用服务计划中,因此在必要时,它们可以相互独立地缩放。 这些托管应用所需的所有资源(例如存储和计算)以及缩放需求完全由应用服务环境基础结构进行管理。

通过此实现中的简单投票应用,用户可以查看现有条目、创建新条目,并对现有条目进行投票。 Web API 用于创建和检索条目及投票。 数据本身存储在 SQL Server 数据库中。 为了演示异步数据更新,Web 应用在服务总线实例中将新添加的投票排队。 函数拾取排队的投票并更新 SQL 数据库。 Azure Cosmos DB 用于存储一段模拟广告,Web 应用检索该广告以便在浏览器上显示。 应用程序使用 Azure Cache for Redis 进行缓存管理。 通过使用高级层 Azure Cache for Redis,可以在其自己的子网中配置到与应用服务环境相同的虚拟网络。 这样可为缓存提供增强的安全性和隔离性。

Web 应用是唯一可从 Internet 通过应用程序网关访问的组件。 无法从 Internet 客户端访问 API 和函数。 入站流量受在应用程序网关上配置的 WAF 保护。

组件

以下服务是在此体系结构中锁定应用服务环境的关键:

  • Azure 虚拟网络是企业所有的专用 Azure 云网络。 它提供基于网络的增强的安全性和隔离。 应用服务环境是企业拥有的虚拟网络子网中的应用服务部署。 它支持企业使用网络安全组和专用终结点来严格控制网络空间及其访问的资源。

  • 应用程序网关是一个应用程序级 Web 流量负载均衡器,具有 TLS/SSL 卸载和 WAF。 它可侦听公共 IP 地址并将流量路由到 ILB 应用服务环境中的应用程序终结点。 由于这是应用程序级路由,因此它可以将流量路由到同一 ILB 应用服务环境中的多个应用。 有关详细信息,请参阅应用程序网关多站点托管

  • Azure 防火墙用于限制来自 Web 应用程序的出站流量。 不通过专用终结点通道和应用服务环境所需路由表的传出流量将会定向到防火墙子网。 为简单起见,此体系结构回在服务子网上配置所有专用终结点。

  • Microsoft Entra ID 提供对 Azure 资源和服务的访问权限与权限管理。 托管标识将标识分配给 Microsoft Entra ID 自动管理的服务和应用。 这些标识可用于对任何支持 Microsoft Entra 身份验证的服务进行身份验证。 这样就无需为这些应用显式配置凭据。 此体系结构将托管标识分配给 Web 应用。

  • Azure 密钥保管库会存储应用所需的任何机密和凭据。 请优先使用此选项,而不要直接在应用程序中存储机密。

  • GitHub Actions 在此体系结构中提供持续集成和持续部署功能。 由于应用服务环境位于虚拟网络中,因此虚拟机jiang 用作虚拟网络中的 jumpbox,以在应用服务计划中部署应用。 该操作可在虚拟网络外部生成应用。 如需实现增强的安全性和无缝 RDP/SSH 连接,请考虑对 jumpbox 使用 Azure Bastion

多站点配置

Diagram that shows a multi-site deployment.

下载此体系结构的 Visio 文件

内部应用服务环境可以使用 HTTP 终结点托管多个 Web 应用和 API。 将禁止从公共 Internet 访问这些应用程序,因为只能从虚拟网络内部访问 ILB IP。 应用程序网关用于选择性地向 Internet 公开这些应用程序。 应用服务环境可为每个应用服务应用程序分配默认 URL 作为 <default-appName>.<app-service-environment-domain>.appserviceenvironment.net。 创建一个专用 DNS 区域,用于将应用服务环境域名映射到应用服务环境 ILB IP 地址。 这可以避免使用自定义 DNS 来访问虚拟网络中的应用。

应用程序网关的配置方式为使用一个侦听器在 HTTPS 端口上侦听对网关 IP 地址的请求。 为简单起见,此实现不使用公共 DNS 名称注册。 它会要求修改计算机上的 localhost 文件,以将任意选择的 URL 指向应用程序网关 IP。 为简单起见,侦听器使用自签名证书来处理这些请求。 应用程序网关为每个应用服务应用程序的默认 URL 提供后端池路由规则配置为将侦听器连接到后端池。 创建 HTTP 设置,以确定是否加密网关与应用服务环境之间的连接。 这些设置还用于将传入的 HTTP 主机头替代为从后端池选择的主机名。 此实现使用为默认应用服务环境应用 URL 创建的默认证书,这是受网关信任的。 请求将重定向到相应应用的默认 URL。 链接到虚拟网络的专用 DNS 会将此请求转发到 ILB IP。 然后,应用服务环境将此转发到请求的应用服务。 应用服务环境应用中的任何 HTTP 通信将通过专用 DNS。 请注意,需要在应用程序网关上为每个应用服务环境应用配置侦听器、后端池、路由规则和 HTTP 设置。

查看 appgw.bicepdns.bicep,以了解如何进行这些配置以支持多个站点。 名为 testapp 的 Web 应用是为演示此配置而创建的空应用。 可从部署脚本 commands_std.azcli 访问这些 JSON 文件。 这些文件也可由 commands_ha.azcli 访问,这用于实现高可用性多站点应用服务环境部署

方案详细信息

Azure 应用服务是一个 PaaS 服务,用于在 Azure 上托管各种应用:Web 应用、API 应用、函数和移动应用。 通过应用服务环境,企业可将其应用服务应用部署到其自己 Azure 虚拟网络的子网中,从而为其云工作负载提供隔离且高度可缩放的专用环境。

注意事项

这些注意事项实施 Azure 架构良好的框架的支柱原则,即一套可用于改善工作负载质量的指导原则。 有关详细信息,请参阅 Microsoft Azure 架构良好的框架

安全性

安全性针对蓄意攻击及滥用宝贵数据和系统提供保障措施。 有关详细信息,请参阅安全性支柱概述

应用服务环境

内部应用服务环境部署在企业虚拟网络中,对公共 Internet 隐藏。 它允许企业在网络级别锁定其后端服务,例如 Web API 和函数。 可以通过 ILB 从虚拟网络内部访问任何具有 HTTP 终结点的应用服务环境应用。 应用程序网关配置为通过 ILB 将请求转发到 Web 应用。 Web 应用本身通过 ILB 访问 API。 关键的后端组件(即 API 和函数)实际上无法从公共 Internet 访问。

为应用服务环境分配的默认域名的每个应用服务创建默认证书。 此证书可以加强网关与应用之间流量的安全性,并且在某些方案中可能是必需的。 这些证书不通过客户端浏览器显示。 它只能响应在应用程序网关上配置的证书。

应用程序网关

参考实现会在 appgw.bicep 中以编程方式配置应用程序网关。 部署网关时,文件 deploy_std.sh 将使用此配置:

az deployment group create --resource-group $RGNAME --template-file templates/appgw.bicep --parameters vnetName=$VNET_NAME appgwSubnetAddressPrefix=$APPGW_PREFIX appgwApplications=@appgwApps.parameters.json
APPGW_PUBLIC_IP=$(az deployment group show -g $RGNAME -n appgw --query properties.outputs.appGwPublicIpAddress.value -o tsv)
Encryption

应用程序网关的 TLS 终止和端到端 TLS 概述中所述,应用程序网关可以使用传输层安全性 (TLS)/安全套接字层 (SSL) 来加密和保护来自 Web 浏览器的所有流量。 可通过以下方式配置加密:

  • 加密在网关上终止。 在这种情况下,将为后端池配置 HTTP。 加密在网关上停止,网关与应用服务之间的流量未加密。 由于加密是 CPU 密集型操作,后端上的未加密流量可以提高性能并实现更简单的证书管理。 这提供了合理的安全级别,因为后端是凭借网络配置保护的。

  • 端到端加密。 在某些情况下(例如要满足特定的安全性或合规要求),可能需要加密网关与应用程序之间的流量。 这是通过使用 HTTPS 连接并在后端池中配置证书来实现的。

此参考实现针对应用程序网关使用自签名证书。 对于生产代码,应使用证书颁发机构颁发的证书。 有关受支持证书类型的列表,请参阅支持用于 TLS 终止的证书。 请参阅使用 Azure 门户配置具有 TLS 终止的应用程序网关,了解如何创建网关终止的加密。 appgw.bicep 中的以下代码行会以编程方式配置此项:

          httpListeners: [for item in appgwApplications: {
          name: '${appgwListenerName}${item.name}'
          properties: {
            frontendIPConfiguration: {
              id: '${appgwId}/frontendIPConfigurations/${appgwFrontendName}'
            }
            frontendPort: {
              id: '${appgwId}/frontendPorts/port_443'
            }
            protocol: 'Https'
            sslCertificate: {
              id: '${appgwId}/sslCertificates/${appgwSslCertificateName}${item.name}'
            }
            hostName: item.hostName
            requireServerNameIndication: true
          }
        }]

参考实现演示了用于应用程序网关与应用服务环境上的 Web 应用之间的流量的端到端加密。 使用默认 SSL 证书。 此实现中的后端池配置为使用与 Web 应用关联的默认域名替代的主机名来重定向 HTTPS 流量。 应用程序网关将信任默认 SSL 证书,因为它们是由 Microsoft 颁发的。 请参阅使用应用程序网关配置应用服务,以了解如何进行这些配置。 appgw.bicep 中的以下代码演示了如何在参考实现中配置此项:

        backendHttpSettingsCollection: [for item in appgwApplications: {
        name: '${appgwHttpSettingsName}${item.name}'
        properties: {
          port: 443
          protocol: 'Https'
          cookieBasedAffinity: 'Disabled'
          pickHostNameFromBackendAddress: true
          requestTimeout: 20
          probe: {
            id: '${appgwId}/probes/${appgwHealthProbeName}${item.name}'
          }
        }
      }]
Web 应用程序防火墙

应用程序网关上的 Web 应用程序防火墙 (WAF) 可保护 Web 应用免受 SQL 注入等恶意攻击。 它还与 Azure Monitor 集成,以使用实时日志监视攻击。 需要按照使用 Azure 门户创建具有 Web 应用程序防火墙的应用程序网关中所述,在网关上启用 WAF。 参考实现在 appgw.bicep 文件中使用以下代码片段以编程方式启用 WAF:

        webApplicationFirewallConfiguration: {
        enabled: true
        firewallMode: 'Detection'
        ruleSetType: 'OWASP'
        ruleSetVersion: '3.0'
      }

虚拟网络

可将网络安全组与虚拟网络中的一个或多个子网相关联。 这些规则是允许或拒绝流量在不同 Azure 资源之间流动的安全规则。 此体系结构为每个子网关联了一个单独的网络安全组。 此操作支持根据每个子网中包含的服务按子网微调这些规则。 例如,对于应用服务环境子网的网络安全组和应用程序网关子网的网络安全组,请分别参阅 ase.bicep 文件以及 appgw.bicep 文件中的 "type": "Microsoft.Network/networkSecurityGroups" 配置。

专用终结点可通过专用网络在客户端与 Azure 服务之间实现增强了安全性的专用连接。 它们为 Azure 服务提供专用的可访问 IP 地址,从而增强了流向 Azure 专用链接资源的流量的安全性。 平台会验证网络连接,从而仅允许连接到指定专用链接资源的网络连接。 专用终结点支持网络安全组、用户定义的路由和应用程序安全组等网络策略。 要提高安全性,应为支持专用终结点的任何 Azure 服务启用专用终结点。 然后,可以通过禁用公共访问来提高虚拟网络中服务的安全性,从而有效阻止来自公共 Internet 的任何访问。 此体系结构可为支持它的服务配置专用终结点,如 Azure 服务总线、SQL Server、密钥保管库和 Azure Cosmos DB。 可以在 privatendpoints.bicep 中查看该配置。

要启用专用终结点,还需要配置专用 DNS 区域。 有关详细信息,请参阅 Azure 专用终结点 DNS 配置

防火墙

Azure 防火墙和专用终结点两者相辅相成。 专用终结点通过仅允许源自虚拟网络的流量来帮助保护资源。 Azure 防火墙支持限制来自应用程序的出站流量。 建议允许所有出站流量通过防火墙子网,包括专用终结点流量。 这样可以更好地监视出站流量。 为简单起见,此参考体系结构将在服务子网而不是防火墙子网上配置所有专用终结点。

要了解 Azure 防火墙如何与应用服务环境集成,请参阅使用应用服务环境配置 Azure 防火墙。 防火墙会监视和限制任何不通过专用终结点和虚拟网络路由表的流量。

Microsoft Entra ID

Microsoft Entra ID 提供了安全功能用于对应用程序进行身份验证和授权访问资源。 此参考体系结构使用 Microsoft Entra ID 的两项关键功能:托管标识和 Azure 基于角色的访问控制。

在云应用程序上,必须保护对云服务进行身份验证所需的凭据。 理想情况下,凭据应永远不应显示在开发人员工作站上,也永远不会签入源代码管理中。 Azure 密钥保管库提供一种安全存储凭据和机密的方式,但应用仍然需要对密钥保管库进行身份验证才能检索这些凭据和机密。 Azure 资源的托管标识在 Microsoft Entra ID 中为 Azure 服务提供了一个自动托管标识。 此标识可用于对任何支持Microsoft Entra 身份验证的服务(包括密钥保管库)进行身份验证,而无需在应用程序中添加任何凭据。

Azure 基于角色的访问控制 (Azure RBAC) 管理对 Azure 资源的访问。 这包括:

  • 具有访问权限的实体:用户、托管标识、安全主体。
  • 实体具有的访问权限类型:所有者、参与者、读者、管理员。
  • 访问范围:资源、资源组、订阅或管理组。

可以通过严格控制所需角色和每个应用的访问权限类型来锁定对应用服务环境应用程序的访问权限。 这样,可以从不同开发团队在同一应用服务环境上部署多个应用。 例如,前端可由一个团队处理,后端则由另一个团队处理。 Azure RBAC 可用于限制每个团队对其处理的应用的访问权限。 请浏览 Azure 自定义角色以创建适合你组织的角色。

密钥保管库

某些服务支持托管标识,但使用 Azure RBAC 来设置应用的权限。 有关示例,请参阅内置服务总线角色,以及 Azure Cosmos DB 中的 Azure RBAC。 授予这些权限需要对订阅拥有的“所有者”访问权限,即使拥有“参与者”访问权限的人员也可以部署这些服务。 要使更大规模的开发人员团队能够运行部署脚本,下一个最佳选项是使用服务的本机访问控制策略:

这些访问控制策略的连接字符串随后将存储在密钥保管库中。 保管库本身是通过托管标识访问的,这需要使用 Azure RBAC。 请相应地为这些连接字符串设置访问策略。 例如,为后端设置只读策略、为前端设置只写策略,等等,而不要使用默认的 root 访问策略。

services.bicep 中的以下代码显示了这些服务的密钥保管库配置:

      resource keyVaultName_CosmosKey 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = {
      parent: keyVaultName
      name: 'CosmosKey'
      properties: {
        value: cosmosName.listKeys().primaryMasterKey 
      }
    }

      resource keyVaultName_ServiceBusListenerConnectionString 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = {
      parent: keyVaultName
      name: 'ServiceBusListenerConnectionString'
      properties: {
        value: listKeys(serviceBusName_ListenerSharedAccessKey.id, '2021-11-01').primaryConnectionString
      }
    }

      resource keyVaultName_ServiceBusSenderConnectionString 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = {
      parent: keyVaultName
      name: 'ServiceBusSenderConnectionString'
      properties: {
        value: listKeys(serviceBusName_SenderSharedAccessKey.id, '2021-11-01').primaryConnectionString
      }
    }

应用通过引用密钥保管库密钥/值对来访问这些连接字符串值。 此操作是在 sites.bicep 文件中完成的,如 Voting App 的以下代码所示:

  properties: {
    enabled: true
    hostingEnvironmentProfile: {
      id:aseId
    }
    serverFarmId: votingWebPlanName.id
    siteConfig: {
      appSettings: [
        {
          name: 'ConnectionStrings:sbConnectionString'
          value: '@Microsoft.KeyVault(SecretUri=${reference(resourceId('Microsoft.KeyVault/vaults/secrets', keyVaultName, serviceBusSenderConnectionStringSecretName), '2022-07-01').secretUriWithVersion})'
        }
        {
          name: 'ConnectionStrings:RedisConnectionString'
          value: '@Microsoft.KeyVault(SecretUri=${reference(keyVaultName_redisSecretName.id, '2022-07-01').secretUriWithVersion})'
        }
        {
          name: 'ConnectionStrings:CosmosKey'
          value: '@Microsoft.KeyVault(SecretUri=${reference(resourceId('Microsoft.KeyVault/vaults/secrets', keyVaultName, cosmosKeySecretName), '2022-07-01').secretUriWithVersion})'
        }
      ]
    }
  }

该函数还以类似方式访问服务总线侦听器连接字符串。

可伸缩性

设计可缩放的应用

此参考体系结构中的应用程序是结构化的,因此可以根据使用情况缩放各个组件。 每个 Web 应用、API 和函数部署在其自身的应用服务计划中。 可以监视每个应用是否存在任何性能瓶颈,然后根据需要纵向扩展该应用

自动缩放应用程序网关

可以在 Azure 应用程序网关 V2 上启用自动缩放。 通过此操作,应用程序网关可以根据流量负载模式进行纵向扩展或缩减。 此参考体系结构会在文件 appgw.bicep 中配置 autoscaleConfiguration,以在 0 到 10 个额外实例之间进行缩放。 有关更多详细信息,请参阅缩放应用程序网关和 WAF v2

部署

此参考体系结构中的部署脚本用于部署应用服务环境、其他服务以及应用服务环境中的应用程序。 部署这些应用程序后,企业可能希望制定持续集成和部署计划,以便进行应用维护和升级。 本部分介绍了可供开发人员用来实现应用服务环境应用程序 CI/CD 的一些常用方法。

只能从虚拟网络内部将应用部署到内部应用服务环境。 以下三种方法广泛用于部署应用服务环境应用:

  • 在虚拟网络内部手动部署:使用所需的部署工具在应用服务环境虚拟网络内部创建虚拟机。 使用 NSG 配置与该 VM 建立 RDP 连接。 将代码项目复制到该 VM,然后生成并部署到应用服务环境子网。 这是设置初始生成和测试开发环境的一种简单方法。 但是,不建议在生产环境中使用此方法,因为这样无法缩放所需的部署吞吐量。

  • 从本地工作站建立点到站点连接:通过此操作,可以将应用服务环境虚拟网络扩展到开发计算机,并从该计算机进行部署。 这是设置初始开发环境的另一种方法,不建议在生产环境中使用。

  • 通过 Azure Pipelines:这会实现一个完整的 CI/CD 管道,该管道的末端为虚拟网络中的某个代理。 此方法非常适合在需要较高部署吞吐量的生产环境中使用。 生成管道完全位于虚拟网络外部。 部署管道可将生成的对象复制到虚拟网络中的生成代理,然后部署到应用服务环境子网。 有关详细信息,请参阅有关 Pipelines 与应用服务环境虚拟网络之间的自托管生成代理的讨论。

建议在生产环境中使用 Azure Pipelines。 借助 Azure Pipelines YAML 架构编写 CI/CD 脚本有助于将生成和部署过程自动化。 在此参考实现中,azure-pipelines.yml 为 Web 应用实现此类 CI/CD 管道。 Web API 以及函数也有类似的 CI/CD 脚本。 请参阅使用 Azure Pipelines,了解如何使用它来自动化每个应用程序的 CI/CD。

一些企业可能不希望在虚拟网络中维护永久性的生成代理。 在这种情况下,可以选择在 DevOps 管道中创建生成代理,并在部署完成后将其拆除。 这会在 DevOps 中增加另一个步骤,但会降低 VM 的维护复杂性。 甚至可以考虑使用容器而不是 VM 作为生成代理。 通过从虚拟网络外部的压缩文件(通常在某个存储帐户中)进行部署,也可以完全避免使用生成代理。 存储帐户需要能够从应用服务环境中访问。 管道应该能够访问存储。 在发布管道结束时,可将压缩文件放入 Blob 存储中。 然后,应用服务环境可以选择它并进行部署。 请注意此方法的以下限制:

  • DevOps 与实际部署过程之间会脱节,导致难以监视和跟踪任何部署问题。
  • 在包含受保护流量的锁定环境中,可能需要更改规则才能访问存储上的压缩文件。
  • 需要在应用服务环境上安装特定的扩展和工具,然后才能从压缩文件进行部署。

若要了解将应用部署到应用服务计划的更多方法,请参阅侧重于部署策略的应用服务文章

成本优化

使用 Azure 定价计算器估算成本。 Microsoft Azure 架构良好的框架的“成本”部分描述了其他注意事项。 Azure 预留项可帮助你节省资金,因为它可以承诺许多 Azure 资源的一年期或三年期计划。 在购买预留项一文中了解详细信息。

此处提供了对于此体系结构中使用的某些关键服务需要考虑的要点。

应用服务环境 v3

有多种适用于应用服务的定价选项。 应用服务环境是使用独立 v2 服务计划部署的。 在此计划中,存在从 I1v2 到 I6v2 的多个 CPU 大小选项。 此参考实现为每个实例使用三个 I1v2。

应用程序网关

应用程序网关定价提供了各种定价选项。 此实现使用了应用程序网关标准 v2 和 WAF v2 SKU,它们支持自动缩放和区域冗余。 有关用于此 SKU 使用的定价模型的详细信息,请参阅缩放应用程序网关 v2 和 WAF v2

用于 Redis 的 Azure 缓存

Azure Cache for Redis 定价提供了此服务的各种定价选项。 此体系结构使用高级 SKU 来提供虚拟网络支持。

下面是用于锁定应用服务环境的其他服务的定价页:

部署此方案

若要部署此体系结构的参考实现,请参阅 GitHub 自述文件,并按照脚本进行标准部署。

作者

本文由 Microsoft 维护, 它最初是由以下贡献者撰写的。

主要作者:

其他参与者:

若要查看非公开领英个人资料,请登录领英。

后续步骤

若要了解如何扩展此体系结构以支持高可用性,请参阅使用应用服务环境进行高可用性应用部署