两个相同的 Azure 部署;一个总是抛出 404 - 如何找出区别是什么?
Two identical Azure deployments; one always throws 404 - how to find out what the difference is?
我正在使用 Pulumi 将 C# ASP.NET 核心 Web 服务部署到 Azure。我可以通过 3 种方式部署它:
- 运行 从 Visual Studio 本地获取,即根本不使用 Azure。
- 从我的本地开发人员计算机将它部署到 Azure。
- 将其从 Jenkins 部署到 Azure(在另一台计算机上 运行)。
我有这个问题:
- 当我在本地 运行 时,我可以很好地调用该服务,例如来自 Postman 或 C# 应用程序。 Web 服务 return 符合我的预期。
- 当我将它从我的本地机器部署到 Azure 时,我也可以正常调用它。 Web 服务 return 符合我的预期。
- 当我将它从 Jenkins 部署到 Azure,然后尝试调用 Web 服务时,无论我做什么,它都会对所有调用显示“NotFound”。 (这大概意味着 HTTP 404。)
2和3的部署应该是完全一样的。我的问题是:我如何找出这两个部署在 Azure 中的区别?
Jenkins 部署的网络服务表现出以下奇怪的行为:
- 它不会记录任何异常(即使我等待几分钟让它们出现)。
- 如果我转到我的资源组 -> Application Insights -> 日志并搜索“请求”,它会列出请求。奇怪的是,它说它对所有请求 returned HTTP 200,即使我调用它们时得到的是 404。
- 即使对于永远不应 return 200(它们应该 return 201)的 Web 服务调用也是如此。
- 即使是 Web 服务调用甚至不应该存在的方法(即,当我在调用服务之前故意破坏方法 URI)时,上述情况也是如此。
在部署期间,我使用服务主体向 Azure 进行身份验证。我的 Jenkinsfile 看起来像这样:
withVaultSecrets([
"path/to/secret/in/vault": [
"sp_name", "application_id", "object_id", "sp_secret"
]
]){
script {
env.PULUMI_CONFIG_PASSPHRASE = 'jenkinspassphrase'
env.ARM_CLIENT_ID = "${application_id}"
env.ARM_CLIENT_SECRET = "${sp_secret}"
env.ARM_TENANT_ID = "${azure_dev_tenant_id}"
env.ARM_SUBSCRIPTION_ID = "${azure_dev_subscription_id}"
env.AZURE_CLIENT_ID = "${application_id}"
env.AZURE_CLIENT_SECRET = "${sp_secret}"
env.AZURE_TENANT_ID = "${azure_dev_tenant_id}"
}//script
dir("./src/deploy/KmsStack"){
powershell "pulumi login --local";
powershell "pulumi stack init jenkinsfunctionaltest --secrets-provider=passphrase"
powershell "pulumi up --yes"
}//dir
}//withVaultSecrets
我用来在本地部署的脚本如下所示,具有相同的服务主体凭据:
cd $PSScriptRoot
cd webapi
dotnet publish /p:DisableGitVersionTask=true
cd ../deploy/KmsStack
$env:PULUMI_CONFIG_PASSPHRASE = 'jenkinspassphrase'
$env:ARM_CLIENT_ID = ...
$env:ARM_CLIENT_SECRET = ...
$env:ARM_TENANT_ID = ...
$env:ARM_SUBSCRIPTION_ID = ...
$env:AZURE_CLIENT_ID = ...
$env:AZURE_CLIENT_SECRET = ...
$env:AZURE_TENANT_ID = ...
pulumi logout
pulumi login --local
pulumi stack rm jenkinsfunctionaltest -y
pulumi stack init jenkinsfunctionaltest --secrets-provider=passphrase
pulumi stack select jenkinsfunctionaltest
pulumi up --yes
我如何找出这两个部署的服务行为不同的原因? Azure 门户 GUI 内容丰富,包含很多部分。你能推荐我去哪里看吗?可能有一些不同的安全设置?我怎样才能找到它们?
提前致谢!
我们发现了问题所在。这不是 Azure 的问题。问题是我们部署了一个错误的 ZIP 文件。 ZIP 文件丢失 web.config,这意味着 Web 应用程序无法启动。
我们通过在 CSPROJ 文件中包含以下内容来压缩已发布的 Web 应用程序:
<Target Name="ZipOutputPath" AfterTargets="Publish">
<ZipDirectory SourceDirectory="$(OutputPath)\publish" DestinationFile="$(MSBuildProjectDirectory)\kmswebapp.zip" Overwrite="true" />
</Target>
事实证明这是行不通的,因为编译器的执行顺序与我们预期的不同。在它生成 ZIP 文件的时候,web.config 还没有生成,所以 web.config 从来没有被打包到ZIP 文件。因此 Azure 无法启动应用程序。
当我们从本地机器部署时,它起作用了,因为我们没有在每个 运行 之前清理发布目录,所以会有一个 web.config 从前一个 运行 遗留下来,这个旧的(但未更改)web.config 将打包到 ZIP 文件中并部署到 Azure,因此 Azure 会知道如何启动应用程序。
我们通过从我们的 CSPROJ 文件中删除上面的内容并在我们的 Jenkins 文件中(粗略地)执行此操作来解决它:
powershell "dotnet publish ./src/webapi/WebAPI.csproj"
powershell "if (!(Test-Path('${publishDirectoryPath}/web.config'))){throw 'We need web.config to exist in the publish directory'}"
powershell "Compress-Archive -Path '${publishDirectoryPath}/*' -DestinationPath './src/webapi/kmswebapp.zip' -Force"
这会生成一个包含 web.config 的正确 ZIP 文件,Azure 现在可以启动我们的应用程序,以便它可以正确响应请求。
我正在使用 Pulumi 将 C# ASP.NET 核心 Web 服务部署到 Azure。我可以通过 3 种方式部署它:
- 运行 从 Visual Studio 本地获取,即根本不使用 Azure。
- 从我的本地开发人员计算机将它部署到 Azure。
- 将其从 Jenkins 部署到 Azure(在另一台计算机上 运行)。
我有这个问题:
- 当我在本地 运行 时,我可以很好地调用该服务,例如来自 Postman 或 C# 应用程序。 Web 服务 return 符合我的预期。
- 当我将它从我的本地机器部署到 Azure 时,我也可以正常调用它。 Web 服务 return 符合我的预期。
- 当我将它从 Jenkins 部署到 Azure,然后尝试调用 Web 服务时,无论我做什么,它都会对所有调用显示“NotFound”。 (这大概意味着 HTTP 404。)
2和3的部署应该是完全一样的。我的问题是:我如何找出这两个部署在 Azure 中的区别?
Jenkins 部署的网络服务表现出以下奇怪的行为:
- 它不会记录任何异常(即使我等待几分钟让它们出现)。
- 如果我转到我的资源组 -> Application Insights -> 日志并搜索“请求”,它会列出请求。奇怪的是,它说它对所有请求 returned HTTP 200,即使我调用它们时得到的是 404。
- 即使对于永远不应 return 200(它们应该 return 201)的 Web 服务调用也是如此。
- 即使是 Web 服务调用甚至不应该存在的方法(即,当我在调用服务之前故意破坏方法 URI)时,上述情况也是如此。
在部署期间,我使用服务主体向 Azure 进行身份验证。我的 Jenkinsfile 看起来像这样:
withVaultSecrets([
"path/to/secret/in/vault": [
"sp_name", "application_id", "object_id", "sp_secret"
]
]){
script {
env.PULUMI_CONFIG_PASSPHRASE = 'jenkinspassphrase'
env.ARM_CLIENT_ID = "${application_id}"
env.ARM_CLIENT_SECRET = "${sp_secret}"
env.ARM_TENANT_ID = "${azure_dev_tenant_id}"
env.ARM_SUBSCRIPTION_ID = "${azure_dev_subscription_id}"
env.AZURE_CLIENT_ID = "${application_id}"
env.AZURE_CLIENT_SECRET = "${sp_secret}"
env.AZURE_TENANT_ID = "${azure_dev_tenant_id}"
}//script
dir("./src/deploy/KmsStack"){
powershell "pulumi login --local";
powershell "pulumi stack init jenkinsfunctionaltest --secrets-provider=passphrase"
powershell "pulumi up --yes"
}//dir
}//withVaultSecrets
我用来在本地部署的脚本如下所示,具有相同的服务主体凭据:
cd $PSScriptRoot
cd webapi
dotnet publish /p:DisableGitVersionTask=true
cd ../deploy/KmsStack
$env:PULUMI_CONFIG_PASSPHRASE = 'jenkinspassphrase'
$env:ARM_CLIENT_ID = ...
$env:ARM_CLIENT_SECRET = ...
$env:ARM_TENANT_ID = ...
$env:ARM_SUBSCRIPTION_ID = ...
$env:AZURE_CLIENT_ID = ...
$env:AZURE_CLIENT_SECRET = ...
$env:AZURE_TENANT_ID = ...
pulumi logout
pulumi login --local
pulumi stack rm jenkinsfunctionaltest -y
pulumi stack init jenkinsfunctionaltest --secrets-provider=passphrase
pulumi stack select jenkinsfunctionaltest
pulumi up --yes
我如何找出这两个部署的服务行为不同的原因? Azure 门户 GUI 内容丰富,包含很多部分。你能推荐我去哪里看吗?可能有一些不同的安全设置?我怎样才能找到它们?
提前致谢!
我们发现了问题所在。这不是 Azure 的问题。问题是我们部署了一个错误的 ZIP 文件。 ZIP 文件丢失 web.config,这意味着 Web 应用程序无法启动。
我们通过在 CSPROJ 文件中包含以下内容来压缩已发布的 Web 应用程序:
<Target Name="ZipOutputPath" AfterTargets="Publish">
<ZipDirectory SourceDirectory="$(OutputPath)\publish" DestinationFile="$(MSBuildProjectDirectory)\kmswebapp.zip" Overwrite="true" />
</Target>
事实证明这是行不通的,因为编译器的执行顺序与我们预期的不同。在它生成 ZIP 文件的时候,web.config 还没有生成,所以 web.config 从来没有被打包到ZIP 文件。因此 Azure 无法启动应用程序。
当我们从本地机器部署时,它起作用了,因为我们没有在每个 运行 之前清理发布目录,所以会有一个 web.config 从前一个 运行 遗留下来,这个旧的(但未更改)web.config 将打包到 ZIP 文件中并部署到 Azure,因此 Azure 会知道如何启动应用程序。
我们通过从我们的 CSPROJ 文件中删除上面的内容并在我们的 Jenkins 文件中(粗略地)执行此操作来解决它:
powershell "dotnet publish ./src/webapi/WebAPI.csproj"
powershell "if (!(Test-Path('${publishDirectoryPath}/web.config'))){throw 'We need web.config to exist in the publish directory'}"
powershell "Compress-Archive -Path '${publishDirectoryPath}/*' -DestinationPath './src/webapi/kmswebapp.zip' -Force"
这会生成一个包含 web.config 的正确 ZIP 文件,Azure 现在可以启动我们的应用程序,以便它可以正确响应请求。