在Azure中国区为.NET Core App创建Linux的Web App

本文最早发布于个人的微信公众号内,现在迁移到博客园中。

Microsoft Azure在中国区运营已久,但其云产品和服务相较于国际区的还是有些区别(功能有阉割、有滞后)。

笔者在本次开发完ASP.NET Core的App后,想部署到中国区的Web App上,但在创建Web App资源时发现,在Azure中国区的门户上(Azure China Portal)无法创建Linux的Web App,只能是Windows,为此我特地到国际区做了比较确认,以下是截图:

  • Azure Global Portal,可以为.NET Core 3.1创建系统为Linux的Web App

  • Azure China Portal,截至发文时(2020/7/23),只能创建系统是Windows的Web App(而且目前即使选择其他Runtime stack,也无法选择Linux的Web App

作为喜欢折腾的程序员,依然希望在中国区能有所突破,为此做了一点小尝试。

幸运的是找到了一个方案,也很简单:放弃在门户上手动创建资源,改为使用ARM template进行资源创建,以下是研究过程和操作步骤(在China East 2上测试成功,在China East上失败,无法创建此类资源):

  • 从国际区的资源组中,导出包含Web App(Linux)的ARM template。

    通过观察发现,在此template中,创建Service Plan(Service Farms)的JSON内有一个"kind"对象,其值为"linux",如下图:

    创建Web App(Sites)的JSON内也有一个"kind"对象,其值为"app,linux",如下图:

  • 据此推测,在中国区使用该ARM template进行资源创建,也应该可行。所以,对这个ARM template略加修改(修改location为China East2),并在Azure中国区进行了部署,具体步骤如下:

    1. 在Azure China Portal上创建一个资源组

    2. 在资源组内点击"+",添加一个资源

    3. 在Marketplace中搜索template,并选择"Template deployment",如下图:

    4. 点击"Build your own template in the editor"

    5. 将ARM template的内容复制到编辑框中,检查一下确保没有错误(特别注意location,目前在China East2上测试成功)并保存。

    6. 保存后,自动跳转回上页,勾选同意协议,并点击"Purchase"

    7. 之后就开始进入部署阶段,等待片刻后,就可以在资源组内看到创建好的云资源,Service Plan带有企鹅图标,是一个Linux的系统,如下图:

    8. 查看Web App,可以看到,这就是一个服务于.NET Core 3.1的App

    9. 在向该Web App部署.NET Core的代码前,还需要做额外设置,打开该App的Configuration-->Application settings,新增一个配置,WEBSITE_WEBDEPLOY_USE_SCM: false,如下图:

      如果没有进行上述配置,则无法通过Visual Studio手动发布

    10. 保存配置后,就可以通过下载publish profile,并使用Visual Studio向该Web App部署.NET Core App,如下图:

      在Portal上下载publish profile:

      在Visual Studio中导入publish profile,点击Publish进行部署

      部署成功

      成功打开页面

最后,附上本次部署时所用的ARM template供各位参考,有兴趣的朋友也可以到China North或China North2上进行尝试(China East无法使用该方案)

{
​    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "site_name": {
            "defaultValue": "coreapponlinux_china_webapp",
            "type": "String"
        },
        "serverfarms_name": {
            "defaultValue": "coreapponlinux_china_serviceplan",
            "type": "String"
        },
    "region": {
      "defaultValue": "China East2",
      "type": "String"
    }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Web/serverfarms",
            "apiVersion": "2018-02-01",
            "name": "[parameters('serverfarms_name')]",
            "location": "[parameters('region')]",
            "sku": {
                "name": "B1",
                "tier": "Basic",
                "size": "B1",
                "family": "B",
                "capacity": 1
            },
            "kind": "linux",
            "properties": {
                "perSiteScaling": false,
                "maximumElasticWorkerCount": 1,
                "isSpot": false,
                "freeOfferExpirationTime": "2020-08-21T08:26:43.8033333",
                "reserved": true,
                "isXenon": false,
                "hyperV": false,
                "targetWorkerCount": 0,
                "targetWorkerSizeId": 0
            }
        },
        {
            "type": "Microsoft.Web/sites",
            "apiVersion": "2018-11-01",
            "name": "[parameters('site_name')]",
            "location": "[parameters('region')]",
            "dependsOn": [
                "[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_name'))]"
            ],
            "kind": "app,linux",
            "properties": {
                "enabled": true,
                "hostNameSslStates": [
                    {
                        "name": "[concat(parameters('site_name'), '.azurewebsites.net')]",
                        "sslState": "Disabled",
                        "hostType": "Standard"
                    },
                    {
                        "name": "[concat(parameters('site_name'), '.scm.azurewebsites.net')]",
                        "sslState": "Disabled",
                        "hostType": "Repository"
                    }
                ],
                "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_name'))]",
                "reserved": true,
                "isXenon": false,
                "hyperV": false,
                "siteConfig": {},
                "scmSiteAlsoStopped": false,
                "clientAffinityEnabled": false,
                "clientCertEnabled": false,
                "hostNamesDisabled": false,
                "containerSize": 0,
                "dailyMemoryTimeQuota": 0,
                "httpsOnly": false,
                "redundancyMode": "None"
            }
        },
        {
            "type": "Microsoft.Web/sites/config",
            "apiVersion": "2018-11-01",
            "name": "[concat(parameters('site_name'), '/web')]",
            "location": "[parameters('region')]",
            "dependsOn": [
                "[resourceId('Microsoft.Web/sites', parameters('site_name'))]"
            ],
            "properties": {
                "numberOfWorkers": 1,
                "defaultDocuments": [
                    "Default.htm",
                    "Default.html",
                    "Default.asp",
                    "index.htm",
                    "index.html",
                    "iisstart.htm",
                    "default.aspx",
                    "index.php",
                    "hostingstart.html"
                ],
                "netFrameworkVersion": "v4.0",
                "linuxFxVersion": "DOTNETCORE|3.1",
                "requestTracingEnabled": false,
                "remoteDebuggingEnabled": false,
                "httpLoggingEnabled": false,
                "logsDirectorySizeLimit": 35,
                "detailedErrorLoggingEnabled": false,
                "publishingUsername": "$coreapponlinux",
                "azureStorageAccounts": {},
                "scmType": "None",
                "use32BitWorkerProcess": true,
                "webSocketsEnabled": false,
                "alwaysOn": false,
                "managedPipelineMode": "Integrated",
                "virtualApplications": [
                    {
                        "virtualPath": "/",
                        "physicalPath": "site\\wwwroot",
                        "preloadEnabled": false
                    }
                ],
                "loadBalancing": "LeastRequests",
                "experiments": {
                    "rampUpRules": []
                },
                "autoHealEnabled": false,
                "localMySqlEnabled": false,
                "ipSecurityRestrictions": [
                    {
                        "ipAddress": "Any",
                        "action": "Allow",
                        "priority": 1,
                        "name": "Allow all",
                        "description": "Allow all access"
                    }
                ],
                "scmIpSecurityRestrictions": [
                    {
                        "ipAddress": "Any",
                        "action": "Allow",
                        "priority": 1,
                        "name": "Allow all",
                        "description": "Allow all access"
                    }
                ],
                "scmIpSecurityRestrictionsUseMain": false,
                "http20Enabled": false,
                "minTlsVersion": "1.2",
                "ftpsState": "AllAllowed",
                "reservedInstanceCount": 0
            }
        }
    ]
}

本文也算抛砖引玉,如果各位大牛有更好的方案,也请指教。当然,等以后Linux Web App在中国区上线后,也就不用这么折腾了。

posted @ 2020-08-19 13:32  *蓝色基因*  阅读(121)  评论(0)    收藏  举报