教程:将 Windows 容器中的 .NET 应用程序部署到 Azure Service Fabric

本教程介绍如何将现有 ASP.NET 应用程序容器化,并将其打包为 Service Fabric 应用程序。 在 Service Fabric 开发群集上本地运行该容器,然后将该应用程序部署到 Azure。 应用程序将数据保存在 Azure SQL 数据库中。

在本教程中,你将了解如何执行以下操作:

  • 使用 Visual Studio 将现有应用程序容器化
  • 在 Azure SQL 数据库中创建数据库
  • 创建 Azure 容器注册表
  • 将 Service Fabric 应用程序部署到 Azure

注意

建议使用 Azure Az PowerShell 模块与 Azure 交互。 请参阅安装 Azure PowerShell 以开始使用。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az

先决条件

  1. 如果没有 Azure 订阅,请创建一个试用版订阅
  2. 启用“Hyper-V”和“容器”这两项 Windows 功能 。
  3. 安装 Docker Desktop for Windows,以便在 Windows 10 上运行容器。
  4. 安装 Service Fabric 运行时版本 6.2 或更高版本以及 Service Fabric SDK 版本 3.1 或更高版本。
  5. 安装 Visual Studio,并启用“Azure 开发”以及“ASP.NET 和 Web 开发”工作负载。
  6. 安装 Azure PowerShell

下载并运行 Fabrikam Fiber CallCenter

  1. 从 GitHub 下载 Fabrikam Fiber CallCenter 示例应用程序。

  2. 验证 Fabrikam Fiber CallCenter 应用程序是否能正确无误地生成和运行。 以管理员身份启动 Visual Studio,然后打开 VS2015\FabrikamFiber.CallCenter.sln 文件。 按 F5 运行和调试应用程序。

    Screenshot of the Fabrikam Fiber CallCenter application home page running on the local host. The page shows a dashboard with a list of support calls.

创建 Azure SQL DB

在生产中运行 Fabrikam Fiber CallCenter 应用程序时,需要将数据保存在数据库中。 目前无法保证将数据保留在容器中,因此无法将生产数据存储在容器中的 SQL Server 中。

建议使用 Azure SQL 数据库。 若要在 Azure 中设置和运行托管的 SQL Server DB,请运行以下脚本。 根据需要修改脚本变量。 clientIP 是开发计算机的 IP 地址。 记下脚本输出的服务器的名称。

$subscriptionID="<subscription ID>"

# Sign in to your Azure account and select your subscription.
Connect-AzAccount -Environment AzureChinaCloud -SubscriptionId $subscriptionID

# The data center and resource name for your resources.
$dbresourcegroupname = "fabrikam-fiber-db-group"
$location = "chinaeast"

# The server name: Use a random value or replace with your own value (do not capitalize).
$servername = "fab-fiber-$(Get-Random)"

# Set an admin login and password for your database.
# The login information for the server.
$adminlogin = "ServerAdmin"
$password = "Password@123"

# The IP address of your development computer that accesses the SQL DB.
$clientIP = "<client IP>"

# The database name.
$databasename = "call-center-db"

# Create a new resource group for your deployment and give it a name and a location.
New-AzResourceGroup -Name $dbresourcegroupname -Location $location

# Create the SQL server.
New-AzSqlServer -ResourceGroupName $dbresourcegroupname `
    -ServerName $servername `
    -Location $location `
    -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminlogin, $(ConvertTo-SecureString -String $password -AsPlainText -Force))

# Create the firewall rule to allow your development computer to access the server.
New-AzSqlServerFirewallRule -ResourceGroupName $dbresourcegroupname `
    -ServerName $servername `
    -FirewallRuleName "AllowClient" -StartIpAddress $clientIP -EndIpAddress $clientIP

# Create the database in the server.
New-AzSqlDatabase  -ResourceGroupName $dbresourcegroupname `
    -ServerName $servername `
    -DatabaseName $databasename `
    -RequestedServiceObjectiveName "S0"

Write-Host "Server name is $servername"

提示

如果你处于企业防火墙之后,则开发计算机的 IP 地址可能不是暴露于 Internet 的 IP 地址。 若要验证数据库是否有防火墙规则的正确 IP 地址,请转到 Azure 门户,在“SQL 数据库”部分找到数据库。 单击其名称,然后在“概览”部分单击“设置服务器防火墙”。 “客户端 IP 地址”是开发计算机的 IP 地址。 请确保它与“AllowClient”规则中的 IP 地址匹配。

更新 Web 配置

返回到 FabrikamFiber.Web 项目,更新 web.config 文件中的连接字符串,以指向容器中的 SQL Server。 将连接字符串的 Server 部分更新为上一脚本创建的服务器名称。 它应该类似于“fab-fiber-751718376.database.chinacloudapi.cn”。 在以下 XML 中,只需更新 connectionString 属性;不需要更改 providerNamename 属性。

<add name="FabrikamFiber-Express" connectionString="Server=<server name>,1433;Initial Catalog=call-center-db;Persist Security Info=False;User ID=ServerAdmin;Password=Password@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" providerName="System.Data.SqlClient" />
<add name="FabrikamFiber-DataWarehouse" connectionString="Server=<server name>,1433;Initial Catalog=call-center-db;Persist Security Info=False;User ID=ServerAdmin;Password=Password@123;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" providerName="System.Data.SqlClient" />

注意

可以使用选择的任何 SQL Server 进行本地调试,只要可通过主机访问。 但是,localdb 不支持 container -> host 通信。 如果想要在生成 Web 应用程序的发布版本时使用其他 SQL 数据库,可将另一个连接字符串添加到 web.release.config 文件。

容器化应用程序

  1. 右键单击“FabrikamFiber.Web”项目 >“添加”>“容器业务流程协调程序支持”。 选择“Service Fabric”作为容器业务流程协调程序,然后单击“确定” 。

  2. 如果收到提示,单击“是”立即将 Docker 切换到 Windows 容器。

    解决方案中将创建一个新的 Service Fabric 应用程序项目,即“FabrikamFiber.CallCenterApplication”。 系统会向现有的“FabrikamFiber.Web”项目添加一个 Dockerfile。 还会向“FabrikamFiber.Web”项目添加一个“PackageRoot”目录,其中包含新 FabrikamFiber.Web 服务的服务清单和设置 。

    现在可以在 Service Fabric 应用程序中生成和打包该容器。 在计算机上生成容器映像后,即可将其推送到任何容器注册表并下拉到任何主机上运行。

本地运行已容器化的应用程序

按 F5,在本地 Service Fabric 开发群集的容器中运行和调试应用程序。 如果出现一个消息框,请求授予“ServiceFabricAllowedUsers”组对Visual Studio 项目目录的读取和执行权限,请单击“是”。

如果 F5 运行引发异常(如下所示),则表示尚未将正确的 IP 添加到 Azure 数据库防火墙中。

System.Data.SqlClient.SqlException
HResult=0x80131904
Message=Cannot open server 'fab-fiber-751718376' requested by the login. Client with IP address '123.456.789.012' is not allowed to access the server.  To enable access, use the Windows Azure Management Portal or run sp_set_firewall_rule on the master database to create a firewall rule for this IP address or address range.  It may take up to five minutes for this change to take effect.
Source=.Net SqlClient Data Provider
StackTrace:
<Cannot evaluate the exception stack trace>

若要将适当的 IP 添加到 Azure 数据库防火墙,请运行以下命令。

# The IP address of your development computer that accesses the SQL DB.
$clientIPNew = "<client IP from the Error Message>"

# Create the firewall rule to allow your development computer to access the server.
New-AzSqlServerFirewallRule -ResourceGroupName $dbresourcegroupname `
    -ServerName $servername `
    -FirewallRuleName "AllowClientNew" -StartIpAddress $clientIPNew -EndIpAddress $clientIPNew

创建容器注册表

在本地运行应用程序后,开始准备将其部署到 Azure。 需将容器映像保存在容器注册表中。 使用以下脚本创建 Azure 容器注册表。 容器注册表名称对其他 Azure 订阅可见,因此它必须是唯一的。 将应用程序部署到 Azure 之前,先将容器映像推送给此注册表。 应用程序部署到 Azure 中的群集时,系统会从此注册表中拉取容器映像。

# Variables
$acrresourcegroupname = "fabrikam-acr-group"
$location = "chinaeast"
$registryname="fabrikamregistry$(Get-Random)"

New-AzResourceGroup -Name $acrresourcegroupname -Location $location

$registry = New-AzContainerRegistry -ResourceGroupName $acrresourcegroupname -Name $registryname -EnableAdminUser -Sku Basic

在 Azure 上创建 Service Fabric 群集

在群集(一组已连接网络的虚拟机或物理计算机)上运行 Service Fabric 应用程序。 需在 Azure 中创建一个 Service Fabric 群集,然后才能将应用程序部署到 Azure。

方法:

  • 通过 Visual Studio 创建一个测试群集。 可以通过此选项使用首选的配置直接从 Visual Studio 创建安全的群集。
  • 模板创建安全的群集

本教程通过 Visual Studio 创建群集,这非常适合测试方案。 如果通过其他方式创建群集或使用现有的群集,可复制粘贴连接终结点或从订阅中选择连接终结点。

在开始之前,请在解决方案资源管理器中打开 FabrikamFiber.Web -> PackageRoot -> ServiceManifest.xml。 记下在“终结点”中列出的 Web 前端的端口。

创建群集时,请执行以下操作:

  1. 在解决方案资源管理器中右键单击“FabrikamFiber.CallCenterApplication”应用程序项目,然后选择“发布” 。

  2. 使用 Azure 帐户登录,以便访问订阅。

  3. 在“连接终结点”下拉列表下,选择“新建群集...”选项 。

  4. 在“创建群集”对话框中,修改以下设置:

    a. 在“群集名称”字段中指定群集的名称,并指定要使用的订阅和位置。 记下群集资源组的名称。

    b. 可选:可以修改节点数。 默认有三个节点,这是测试 Service Fabric 方案的最低要求。

    c. 选择“证书”选项卡。在此选项卡中键入一个密码,用于确保群集证书的安全。 此证书有助于确保群集的安全。 也可修改用于保存证书的路径。 Visual Studio 还可以为你导入证书,因为这是将应用程序发布到群集的必需步骤。

    注意

    记下导入此证书的文件夹路径。 在创建群集后,下一步是导入此证书。

    d. 选择“VM 详细信息”选项卡。指定一个密码,以便将其用于构成群集的虚拟机 (VM)。 可以使用用户名和密码远程连接到 VM。 此外还必须选择 VM 大小,并可根据需要更改 VM 映像。

    重要

    选择一个支持运行容器的 SKU。 群集节点上的 Windows Server OS 必须与容器的 Windows Server OS 兼容。 若要了解更多信息,请参阅 Windows Server 容器 OS 与主机 OS 的兼容性。 默认情况下,本教程将创建基于 Windows Server 2016 LTSC 的 Docker 映像。 基于此映像的容器将运行在使用带容器的 Windows Server 2016 Datacenter 创建的群集上。 但是,如果基于不同版本的 Windows Server 创建群集或使用现有群集,则必须更改容器所基于的 OS 映像。 打开 FabrikamFiber.Web 项目中的 dockerfile,注释掉基于以前版本的 Windows Server 的任何现有 FROM 语句,并根据所需版本的标记从 Windows Server Core DockerHub 页添加 FROM 术语 。 有关 Windows Server Core 版本、支持时间线和版本控制的其他信息,请参阅 Windows Server Core 版本信息

    e. 在“高级”选项卡中,列出群集部署时要在负载均衡器中打开的应用程序端口。 这是在开始创建群集之前记下的端口。 还可以添加现有的 Application Insights 密钥,用于路由应用程序日志文件。

    f. 修改完设置以后,选择“创建”按钮。

  5. 需要数分钟才能创建完毕;输出窗口会指示群集何时完全创建好。

安装导入的证书

将在群集创建步骤中导入的证书安装到“当前用户”存储位置,并提供你提供的私钥密码。

可从控制面板打开“管理用户证书”,并确认已在“证书 - 当前用户”->“个人”->“证书”下安装证书来确认安装。 证书应类似于 [群集名称].[群集地址].cloudapp.chinacloudapi.cn,例如 fabrikamfibercallcenter.chinaeast.cloudapp.chinacloudapi.cn。

允许在 Azure 中运行的应用程序访问 SQL 数据库

之前已创建一个 SQL 防火墙规则,允许对本地运行的应用程序进行访问。 接下来,需要使 Azure 中运行的应用程序能够访问 SQL DB。 为 Service Fabric 群集创建虚拟网络服务终结点,然后创建一个规则,允许该终结点访问 SQL DB。 请务必指定群集资源组变量,该变量是在创建群集时记下的。

# Create a virtual network service endpoint
$clusterresourcegroup = "<cluster resource group>"
$resource = Get-AzResource -ResourceGroupName $clusterresourcegroup -ResourceType Microsoft.Network/virtualNetworks | Select-Object -first 1
$vnetName = $resource.Name

Write-Host 'Virtual network name: ' $vnetName

# Get the virtual network by name.
$vnet = Get-AzVirtualNetwork `
  -ResourceGroupName $clusterresourcegroup `
  -Name              $vnetName

Write-Host "Get the subnet in the virtual network:"

# Get the subnet, assume the first subnet contains the Service Fabric cluster.
$subnet = Get-AzVirtualNetworkSubnetConfig -VirtualNetwork $vnet | Select-Object -first 1

$subnetName = $subnet.Name
$subnetID = $subnet.Id
$addressPrefix = $subnet.AddressPrefix

Write-Host "Subnet name: " $subnetName " Address prefix: " $addressPrefix " ID: " $subnetID

# Assign a Virtual Service endpoint 'Microsoft.Sql' to the subnet.
$vnet = Set-AzVirtualNetworkSubnetConfig `
  -Name            $subnetName `
  -AddressPrefix   $addressPrefix `
  -VirtualNetwork  $vnet `
  -ServiceEndpoint Microsoft.Sql | Set-AzVirtualNetwork

$vnet.Subnets[0].ServiceEndpoints;  # Display the first endpoint.

# Add a SQL DB firewall rule for the virtual network service endpoint
$subnet = Get-AzVirtualNetworkSubnetConfig `
  -Name           $subnetName `
  -VirtualNetwork $vnet;

$VNetRuleName="ServiceFabricClusterVNetRule"
$vnetRuleObject1 = New-AzSqlServerVirtualNetworkRule `
  -ResourceGroupName      $dbresourcegroupname `
  -ServerName             $servername `
  -VirtualNetworkRuleName $VNetRuleName `
  -VirtualNetworkSubnetId $subnetID;

将应用程序部署到 Azure

至此,应用程序已准备就绪,可以直接通过 Visual Studio 将它部署到 Azure 中的群集。 在解决方案资源管理器中,右键单击“FabrikamFiber.CallCenterApplication”应用程序项目,然后选择“发布” 。 在“连接终结点”中,选择之前创建的群集的终结点。 在“Azure 容器注册表”中,选择之前创建的容器注册表。 单击“发布”,将应用程序部署到 Azure 中的群集。

Publish application

在“输出”窗口中跟进部署进度。 应用程序部署完毕后,打开浏览器并键入群集地址和应用程序端口。 例如 http://fabrikamfibercallcenter.chinaeast.cloudapp.chinacloudapi.cn:8659/

Screenshot of the Fabrikam Fiber CallCenter application home page running on azure.com. The page shows a dashboard with a list of support calls.

如果页面未能加载或未能提示提供证书,请尝试打开资源管理器路径,例如 https://fabrikamfibercallcenter.chinaeast.cloudapp.chinacloudapi.cn:19080/Explorer,然后选择新安装的证书。

使用 Service Fabric 群集设置持续集成和部署 (CI/CD)

若要了解如何使用 Azure DevOps 配置到 Service Fabric 群集的 CI/CD 应用程序部署,请参阅教程:使用 CI/CD 将应用程序部署到 Service Fabric 群集。 本教程中所述的过程与此 (FabrikamFiber) 项目相同,只需跳过下载 Voting 示例并将 FabrikamFiber 替换为存储库名称而不是 Voting。

清理资源

如果已完成,请务必删除所创建的所有资源。 最简单的方法是删除包含 Service Fabric 群集、Azure SQL DB 和 Azure 容器注册表的资源组。

$dbresourcegroupname = "fabrikam-fiber-db-group"
$acrresourcegroupname = "fabrikam-acr-group"
$clusterresourcegroupname="fabrikamcallcentergroup"

# Remove the Azure SQL DB
Remove-AzResourceGroup -Name $dbresourcegroupname

# Remove the container registry
Remove-AzResourceGroup -Name $acrresourcegroupname

# Remove the Service Fabric cluster
Remove-AzResourceGroup -Name $clusterresourcegroupname

后续步骤

在本教程中,你了解了如何执行以下操作:

  • 使用 Visual Studio 将现有应用程序容器化
  • 在 Azure SQL 数据库中创建数据库
  • 创建 Azure 容器注册表
  • 将 Service Fabric 应用程序部署到 Azure

在本教程的下一部分中,了解如何使用 CI/CD 将容器应用程序部署到 Service Fabric 群集