2019 年 2 月

第 34 卷,第 2 期

此文章由机器翻译

[Azure]

在 Azure 上生成和部署可复原的高可用性解决方案

通过Srikantan Sankaran

在本文中讨论的技术的一些处于预览状态。所有信息可能都会发生变更。

组织如今具有全球范围开展业务,他们期望其任务关键型应用程序可跨多个地理区域影响的用户。此类组织的 IT 员工是在这些期望时传递的压力下,他们的成功取决于如何构建和旨在解决这一目标中固有的复杂性及其应用程序和平台。Microsoft Azure 提供许多服务和提供几乎统包实现以满足相关要求,无论它们涉及启用异地复制的服务和数据,易受延迟影响的用户对发出请求的路由的功能给最终用户或提供无缝应用程序故障转移到灾难发生时的其他区域更靠近服务。在本文中我看看几个这些目标,并讨论如何使用 Azure 来实现高可用性和可复原的全局应用程序。

我使用一个三层解决方案包含 MVC 和 Web API 的应用程序演示了构建和部署高度可用且可复原应用程序在 Azure 中的重要层面。若要捕获有关他的系列,其将被传递给 API 层,这又将数据保留在异地复制的 Cosmos DB 数据库的基本信息的用户访问应用程序。部署应用程序主动-主动跨多个区域,以确保发生区域服务中断的复原能力。在区域中,它部署跨可用性区域防范数据中心故障 (bit.ly/2zXlRll)。数据库已启用多区域写入功能 (bit.ly/2zV6OI0),确保用户可以写入和读取数据从数据库接近其的访问点,以尽量降低延迟 (bit.ly/2QRr1Il).

解决方案的体系结构

图 1表示解决方案的体系结构。Azure Service Fabric 承载适用于 Linux 打包为 Docker 容器的应用程序组件,提供了业务流程功能,并确保的可用性和可靠性的应用程序。有两个局域性的 Service Fabric 群集部署到每个亚洲东南部和美国东部 2 中的两个 Azure 区域。区域冗余的 Azure 负载均衡器是使用轮循机制为每个区域中的两个可用性区域之间的请求。

解决方案体系结构
图 1:解决方案体系结构

Azure (仍以公共预览版) 的第一道防线服务用户将请求定向到负载均衡终结点之一跨两个区域中,基于路径的最少的延迟。它还提供应用程序或整个数据中心停止运行中的区域之一,通过将请求定向到其他区域中的终结点时的还原能力。

在应用程序中使用的 Azure Cosmos DB 数据库是多区域写入两个 Azure 区域之间的异地复制和配置。因此,数据将写入从每个区域中的 API 服务发起写入到本地的该区域的 Cosmos DB 集合。

Azure DevOps 是应用程序源代码存储库。使用 azure 的管道生成的应用程序、 将其打包为 Docker 容器并将其上载到 Docker 中心注册表。

在组织中托管此解决方案的 IT 策略禁止通过公共 Internet 到 Service Fabric 群集的管理访问权限。使用 Jenkins 部署在 Azure 虚拟网络来实现持续交付 (CD) 管道。它提取部署包和容器从 Git 存储库中 Azure DevOps 和 Docker 中心,分别,并将在两个区域中 Service Fabric 群集应用程序部署。

Service Fabric 群集部署到每个区域包含两个节点类型。主节点类型运行 Service Fabric 平台服务,并公开管理终结点使用内部负载均衡器。第二个节点类型在运行使用 Docker 容器打包的 MVC 和 Web API 应用程序。面向公众的负载均衡器将从最终用户通过 Internet 访问应用程序请求路由。

在此体系结构使用第三个 Azure 负载均衡器 (不在关系图中所示) 以允许出站调用到 Internet 从群集中,若要下载的 Service Fabric 平台组件。配置内部负载均衡器未一个面向公众的终结点,并且无法连接到 Internet。而无需创建出站连接此额外的公共负载均衡器,Service Fabric 群集不能设置 (bit.ly/2A0VBpp)。

请注意,标准 SKU 的 Azure 负载均衡器和公共 IP 地址资源仅支持部署到 Azure 可用性区域,不再基本 SKU,却没有。

Azure Service Fabric 利用局域性部署的基础 Azure 虚拟机规模集 (VMSS) 资源的能力。 

开发应用程序

有两个用于此项目共享的 Visual Studio 2017 解决方案文件:

• censusapp.sln:ASP.NET Core 2.0 MVC 应用程序。

• censusapi.sln:ASP.NET Core 2.0 Web API 应用程序。

请记住生成此示例应用程序使用 ASP.NET Core 2.0,尽管它可能非常就会使用其他技术,如 Node.js、 PHP 等创建的 Web 应用程序。此外,与本文共享示例应用程序不实现任何编码的最佳做法。其目的仅为说明选择设计实现详细信息。

MVC 应用程序实现允许用户提交人口普查数据,并显示该数据的 UI。它使用 Service Fabric 中的服务发现功能来调用 REST API,将数据保存在 Azure Cosmos DB 中。API 项目使用 Cosmos DB SDK 来实现数据库位置连接到以读取和写入数据的优先顺序的列表。部署到南部亚洲东部区域的应用程序会添加此区域为"优先级 1"和"优先级为 2。"为美国东部 2 对于部署到美国东部 2 区域,它会反过来。因此,将有两个单独的容器映像的 Web API 项目,分别对应于部署到各自的区域。在 MVC 项目的容器映像都是相同的而不考虑部署到的 Azure 区域。

以下代码片段演示如何按优先顺序排列的位置列表添加到 Cosmos DB 连接,以及如何在应用程序中配置多区域写入:

ConnectionPolicy policy = new ConnectionPolicy
  {
    ConnectionMode = ConnectionMode.Direct,
    ConnectionProtocol = Protocol.Tcp,
    UseMultipleWriteLocations = true,
  };
policy.PreferredLocations.Add("East US 2");
policy.PreferredLocations.Add("South East Asia");
DocumentClient client = new DocumentClient(new Uri(this.accountEndpoint), 
  this.accountKey, policy);

Web API 项目使用"Bogus"NuGet 包生成虚构数据。

为简单起见,Web API 项目的 appsettings.json 文件中存储的 Cosmos DB 连接字符串和访问密钥。对于生产用途,可以改为将它们存储在 Azure 密钥保管库。请参阅我的文章"Secure Your 敏感业务信息与 Azure 密钥保管库"的指南 (msdn.com/magazine/mt845653)。

启用 Web 应用程序的 Docker 容器Visual Studio 2017 Tools for Docker 提供统包实现,若要启用 Windows 和 Linux 容器的 ASP.NET 2.0 Web 应用程序。在 Visual Studio 2017"启用 Docker 支持"中选择项目的右键单击选项将 Docker 文件添加到它。选择项目的右键单击选项"启用业务流程支持"会创建一个 Docker compose 文件。

此解决方案中的应用程序已打包为 Docker Linux 容器。较小的修改针对 Docker compose 文件以添加要部署应用程序 (端口 80 上 VMSS 节点访问 MVC 应用程序和 Web API 的端口 5002) 时使用的端口映射。

持续集成 (CI) Visual Studio 2017 解决方案文件签入了 Azure DevOps Git 存储库。一个管道,Azure 会创建一个将运行 Docker 为每个前面的步骤中创建的 MVC 和 Web API 项目中 compose 文件。这将生成 ASP.NET Core 2.0 应用程序并创建 Docker 容器映像。

在管道中下一步中,Bash 脚本用于标记容器映像并将其推送到 Docker 中心。此步骤需要执行一次以部署到 Azure 区域中亚洲东南部,一次针对部署到 Azure 区域美国东部 2。同样,MVC 容器是相同无论到哪些 Azure 区域部署。图 2显示创建来完成此步骤的 CI 管道的快照。

Azure DevOps Pipeline
图 2 Azure DevOps 管道

打包以部署到 Service Fabric 应用程序我使用 Yeoman 生成器为 Windows 生成的应用程序和服务清单文件并将解决方案打包。将使用在此工具中找到的指导bit.ly/2zZ334n

单个应用程序包作为服务类型创建的 MVC 应用和 API 应用的捆绑包。在服务清单文件中,输入在前面步骤中上传到 Docker 中心的容器名称。

请注意,Web API 项目的服务清单定义应与 MVC 项目的 appsettings.json 文件,以用于服务发现中的值相匹配的服务 DNS 名称。

在清单中每个服务类型 (即,Web 和 API 项目) 的实例数设置为 2。这会指示 Service Fabric 始终在群集中运行该服务类型的容器的两个实例。此数字可修改以满足部署,也可以设置为自动缩放最小值和最大范围内。

服务清单支持放置约束的概念。在以下片段中,服务应部署到的 Service Fabric 群集中的节点类型名称定义了放置约束。如果未指定,无法获取跨所有节点类型,包括主节点类型中,Service Fabric 群集中部署代码包。但是,我想要托管仅 Service Fabric 平台中的服务的主节点类型。

<ServiceTypes>
  <StatelessServiceType ServiceTypeName="censusapiType" 
    UseImplicitHost="true">
<PlacementConstraints>(NodeTypeName==nt-sfazvm0) </PlacementConstraints>
  </StatelessServiceType>
</ServiceTypes>

Azure 资源管理器 (ARM) 模板 (稍后讨论) 来部署 Service Fabric 群集中配置的节点类型名称应与匹配的服务清单的放置约束中。

部署到 Service Fabric 应用程序

现在让我们来创建 Service Fabric 群集,并向其部署应用程序包。

第一步是预配 Cosmos DB 数据库,可以从 Azure 门户中执行。首先在东南亚创建数据库并启用异地复制到美国东部 2 区域。在向导中选择"启用多区域写入"选项。

我保留会话一致性配置,这是 Cosmos DB 数据库的默认值和默认架构中设置该索引的所有属性。你可以仅选择特定属性编制索引,如果您愿意,根据需要来查询数据。

若要处理的起源启用多主机写入任何潜在冲突,我使用默认的"上次编写者赢冲突解决"策略。

接下来,你在设置 Service Fabric 群集使用 ARM 模板 (bit.ly/2swVkI5bit.ly/2rBvFfi)。模板 SF-标准-ELB-ZonalDeployment.Json 可部署到现有虚拟网络的两个区域群集。有某些先决条件,若要运行此模板。

首先,使用 Azure 密钥保管库中存储的群集中的节点到节点安全性的证书。此步骤中的指纹、 密钥保管库 URL 和证书 URL 需要在 ARM 模板的 Parameters 节中输入中所示图 3。这必须针对每个区域分开,因为 Service Fabric 群集并使用它在密钥保管库应驻留在同一区域中。

图 3 存储指纹,Azure 密钥保管库 URL 和证书 URL

"certificateThumbprint": {
      "type": "string",
      "defaultValue": "<Certificate Thumb print>
    },
    "sourceVaultValue": {
        "type": "string",
        "defaultValue": "/subscriptions/<SubscriptionId>/resourceGroups/
          lpvmvmssrg/providers/Microsoft.KeyVault/vaults/<vaultname>”
    },
    "certificateUrlValue": {
        "type": "string",
        "defaultValue": "https://<vaultname>.vault.azure.net/secrets/
          soloclustercert/<GUID>
        }
  }

其次,使用 Open SSL 生成自签名的证书。ARM 模板的 Parameters 节中输入此证书的指纹:

"clientCertificateStoreValue": {
      "type": "string",
      "defaultValue": "<Client certificate thumbprint
    },

在 Jenkins 中使用此证书连接到 Service Fabric 群集部署应用程序。请参阅bit.ly/2GfLHG0有关详细信息。

请注意,这篇文章演示中使用自签名的证书。对于生产部署,你会使用 Azure 凭据安全地连接到管理终结点和部署应用程序。

有关 Service Fabric 安全性的详细信息,请参阅bit.ly/2CeEzpibit.ly/2SR1E73

对于 MVC 应用程序和 Web API 需要使用正确的端口号和请求路径中,配置对于 HTTP,如中所示,在负载均衡器中使用的运行状况探测图4

图 4 配置的端口和请求路径

{
    "name": "SFContainerProbe1",
    "properties": {
      "protocol": "Http",
      "port": 5002,
      "requestPath": "/api/family",
      "intervalInSeconds": 5,
      "numberOfProbes": 2
    }
  },
    {
    "name": "SFContainerProbe2",
    "properties": {
      "intervalInSeconds": 5,
      "numberOfProbes": 2,
      "port": 80,
      "requestPath": "/",
      "protocol": " Http "
    }
  }

下面是特定于区域性部署 ARM 模板中的其他重要配置:

• 为群集中使用的所有负载均衡器选择了标准 SKU。

• 标准 SKU 公共 IP 地址资源的选择。

• 可用性区域属性需要指定。由于这是局域性部署,属性值中指定一个区域。对于局域性的 SF 群集 1 在亚洲东南部,此值将为"1"和局域性的 SF 群集 2 在亚洲东南部、 的值将为"2"。

•"SinglePlacementGroup"的属性设置为"true。

• 若要启用在群集中,Service Fabric DNS 服务发现,必须启用。

图 5显示这些 ARM 模板中的配置方式。验证是否已成功部署模板和的中显示的服务图 5在 Azure 门户中可见。

VMSS 资源为局域性部署 ARM 模板中使用
图 5 VMSS 资源为局域性部署 ARM 模板中使用

请注意,Azure 可用性区域尚不可用在所有 Azure 区域中。此外,该功能已推出正式版 (GA)) 在某些区域中,但仅处于预览状态,在其他用例。

现在让我们连接到 Service Fabric 群集。内部负载均衡器后面部署 Service Fabric 管理终结点。因此,若要访问 Service Fabric 资源管理器部署应用程序,部署运行 Windows Server 2016 的跳转框虚拟机 (VM),请在同一虚拟网络与 Service Fabric 群集,或为另一种虚拟网络的已建立的对等互连群集。

将证书用于 Service Fabric 管理客户端 (先前创建的自签名证书) 复制到跳转上的用户证书存储中的 VM。启动时 Service Fabric 资源管理器中,选择出现提示时此证书。

接下来,预配 Jenkins 以部署应用程序。对于本文中的方案,我将使用 Jenkins 和 Service Fabric 插件运行的 Docker 容器映像。此映像部署到在与 Service Fabric 群集位于同一虚拟网络中运行的 Azure 中的 Ubuntu VM。

您会发现下载、 安装和配置在容器映像所需的步骤的详细信息bit.ly/2RRRt1Q

若要准备 Jenkins 以连接到 Service Fabric 群集,执行以下附加步骤:

• 将证书用于 Service Fabric 管理客户端 (之前创建的自签名证书) 复制到 Jenkins VM 上的主目录,使用 WinSCP 之类的工具。

• 在此 VM 上启动 Jenkins 容器,并运行"docker exec"命令以将此证书复制到容器内的 Jenkins 主目录。

启动 Jenkins 并登录到 http://<Public-IP-of-JenkinsVM>:8080 若要配置 Service Fabric 插件。

若要配置适用于 Jenkins 的 Service Fabric 插件的步骤,请参阅bit.ly/2UBVhWV。在用来运行应用程序部署到其中一个区域的群集的"Post 生成操作"配置所示图 6。添加其他文章生成操作以用于第二个区域群集,在相同的行。

Service Fabric jenkins 插件
图 6 Service Fabric jenkins 插件

手动触发在 Jenkins 中生成的作业选项,并确保成功完成后触发操作。通过跳转盒 VM 中,启动 Service Fabric 资源管理器验证程序已部署到两个区域的群集。图 7后部署应用程序显示在 Service Fabric 资源管理器。

Service Fabric 资源管理器中的管理终结点
图 7 在 Service Fabric 资源管理器中管理终结点

重复上述步骤,将部署到第二个 Azure 区域。确保使其指向正确的容器映像的 API 服务用于此区域会修改 API 项目的服务清单文件。前面曾提到的每个 API 服务的两个容器映像具有单独的区域的优先级,当连接到 Cosmos DB 中,且实现多区域写入。

运行应用程序

若要激活应用程序部署到区域 1,启动以下 Url:

• http://<Public-IP-Address-LB Region1 > 启动 MVC 应用程序

• http://<Public-IP-Address-LB Region1 >: 5002/api/系列会直接启动 Web API。在 MVC 项目调用 API 在内部,使用服务发现。

Url 的另一组可供区域 2。

图 8显示了通过 Azure 第一道防线服务公开的终结点访问的应用程序页。您会注意到名为 DataOrigin 指示从中插入记录,Cosmos DB 数据库的写入区域的名称,它展示了 Cosmos DB 的多区域写入功能的列。

示例人口普查应用程序
图 8 示例人口普查应用程序

预配 Azure 第一道防线服务

使用 Azure 门户预配 Azure 第一道防线服务并添加 MVC 和 Web API 应用程序的面向公众的终结点,如后端到第一道防线服务。

在第一道防线服务中配置的运行状况探测可确保在时,区域或应用程序时获取无响应,因为在后续请求将定向到正常运行,另一个后, 端终结点之一无法访问,原因可能是发生服务中断。中的配置设置图 9显示如何映射到由第一道防线服务公开一个单一终结点的两个区域中的应用程序终结点。尽管可以作为备用 Azure 前门到使用 Azure 流量管理器,但我选择实现后一种此处,因为它提供了层 7 反向代理、 SSL 终止和路由请求,在此类应用程序所需的。

Azure 的第一道防线配置
图 9 Azure 第一道防线配置

您会发现创建全局 Web 应用,第一道防线的详细信息bit.ly/2QXRkwu

总结

在本文中我介绍了如何 Azure Service Fabric 可用于打包和部署 Docker 容器启用应用程序,并实现业务流程和服务发现功能,是微服务体系结构的基础。通过在 Azure 中的可用性区域的支持,我已部署 2 以消除数据中心故障的影响跨多个数据中心在区域中的局域性的 Service Fabric 群集。

若要增加的应用程序,我应用程序部署到多个 Azure 区域,并利用多区域 Azure Cosmos DB 中编写的支持,这可确保不只是异地复制,无状态应用程序层,但该数据库也是真正分布式和复制。最后,若要确保用户在访问应用程序时遇到延迟量最少,单个 Azure 第一道防线服务实现该路由请求正确的应用程序终结点。若要显示如何实现此体系结构与最少的中断业务,以确保遵循安全策略,我介绍了 CI 和 CD 的实施策略可以实现和分别,以及如何使用 Azure DevOps 服务和 Jenkins,这些可执行企业网络的范围内。

您可以下载示例应用程序bit.ly/2Lra9Dm。有关实现示例应用程序所需的软件,请参阅"必备软件"的信息。


Srikantan Sankaran是一名主要技术 One Commercial Partner 团队在印度,宣传员。他与印度的众多独立软件开发商合作,帮助他们在 Microsoft Azure 上生成和部署解决方案。与他联系sansri@microsoft.com

衷心感谢以下 Microsoft 技术专家对本文的审阅:Sudhanva Huruli,Muni Pulipalyam


在 MSDN 杂志论坛讨论这篇文章