docker - Azure 函数无法启动 - "Didn' t 响应端口 X 上的 HTTP ping”(Docker/VNet)

标签 docker azure-functions vnet

我真的很难弄清楚如何设置使用 Docker 容器镜像并连接到 VNet 的 Azure 函数。我在任何地方都找不到此设置的任何示例。

我遇到的主要问题是,在我的容器启动并运行后,它似乎没有响应底层框架用来确定函数是否启动并运行的 HTTP ping。我认为主要问题是,当您设置使用 Docker 的 Linux 服务并将其连接到 VNet 时,使用的端口不是标准的(据我了解)。我已更新 ENTRYPOINT我的 dockerfile 中的行以相应地处理此问题,但是用于测试 ping 的端口不是通过 docker run 命令公开的端口。以下是与此启动错误相关的日志条目:

INFO  - Starting container for site
INFO  - docker run -d -p 8635:8635 --name evo-item-exporter-stage_0_42c1415b_middleware -e WEBSITE_CORS_ALLOWED_ORIGINS=https://functions.azure.com,https://functions-staging.azure.com,https://functions-next.azure.com -e WEBSITE_CORS_SUPPORT_CREDENTIALS=False -e WEBSITES_ENABLE_APP_SERVICE_STORAGE=false -e WEBSITE_SITE_NAME=evo-item-exporter-stage -e WEBSITE_AUTH_ENABLED=False -e PORT=8635 -e WEBSITE_ROLE_INSTANCE_ID=0 -e WEBSITE_HOSTNAME=evo-item-exporter-stage.azurewebsites.net -e WEBSITE_INSTANCE_ID=47d698ac06f21187d3dc07a6ddd707f955f4ca9b939be455493969c8c2fb4bb8 appsvc/middleware:1907112318 /Host.ListenUrl=http://0.0.0.0:8635 /Host.DestinationHostUrl=http://10.5.6.4:3236 /Host.UseFileLogging=true 

INFO  - Logging is not enabled for this container.
Please use https://aka.ms/linux-diagnostics to enable logging to see container logs here.
INFO  - Initiating warmup request to container evo-item-exporter-stage_0_42c1415b_msiProxy for site evo-item-exporter-stage
INFO  - Container evo-item-exporter-stage_0_42c1415b_msiProxy for site evo-item-exporter-stage initialized successfully and is ready to serve requests.
INFO  - Initiating warmup request to container evo-item-exporter-stage_0_42c1415b for site evo-item-exporter-stage
ERROR - Container evo-item-exporter-stage_0_42c1415b for site evo-item-exporter-stage has exited, failing site start
INFO  - Initiating warmup request to container evo-item-exporter-stage_0_42c1415b_middleware for site evo-item-exporter-stage

INFO  - Container evo-item-exporter-stage_0_42c1415b_middleware for site evo-item-exporter-stage initialized successfully and is ready to serve requests.
ERROR - Container evo-item-exporter-stage_0_42c1415b didn't respond to HTTP pings on port: 3236, failing site start. See container logs for debugging.
INFO  - Stoping site evo-item-exporter-stage because it failed during startup.

正如您在此示例中看到的,端口 8635 被映射(到端口 8635)并被指定为环境变量,该变量来自底层 vnet 设置。但是,HTTP ping 被发送到端口 3236。我看到这是 docker run 命令末尾的/Host.DestinationHostUrl 参数的一部分,但我不知道如何访问这个参数,因为它是不像 PORT 那样作为环境变量传递。

这是我的 Dockerfile:
FROM mcr.microsoft.com/azure-functions/dotnet:2.0 AS base
WORKDIR /app
EXPOSE 80

ENV PORT=80

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["nuget.config", ""]
COPY ["ItemExporter/app.ItemExporter/app.ItemExporter.csproj", "ItemExporter/app.ItemExporter/"]
COPY ["ItemExporter/evo.Domain/evo.Domain.csproj", "ItemExporter/evo.Domain/"]
COPY ["ItemExporter/evo.DependencyInjection/evo.DependencyInjection.csproj", "ItemExporter/evo.DependencyInjection/"]
COPY ["ItemExporter/evo.Infrastructure/evo.Infrastructure.csproj", "ItemExporter/evo.Infrastructure/"]
RUN dotnet restore "ItemExporter/app.ItemExporter/app.ItemExporter.csproj"
COPY . .
WORKDIR "/src/ItemExporter/app.ItemExporter"
RUN dotnet build "app.ItemExporter.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "app.ItemExporter.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV AzureWebJobsScriptRoot=/app

#See the Azure function docker file to get the correct entrypoint syntax
#in case this changes in the future
#https://github.com/Azure/azure-functions-host/blob/dev/Dockerfile
#The --urls=... part is needed to run inside an Azure App Service w/ vnet integration
ENTRYPOINT dotnet /azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost.dll --urls="http://0.0.0.0:$PORT"

仅供引用 Azure Function 工具链创建的默认 Dockerfile 不起作用。它会出现如下错误:
(Failed to bind to address http://[::]:5169: address already in use.) ---> System.IO.IOException: Failed to bind to address http://[::]:5169: address already in use. ---> Microsoft.AspNetCore.Connections.AddressInUseException: Address already in use ---> System.Net.Sockets.SocketException: Address already in use

为了解决这个错误,我必须通过使用 PORT 环境变量和 --urls 参数来执行我上面所说的操作。

我假设我需要做的是将这个其他端口添加到 --urls=...我将参数传递给 ENTRYPOINT,但无法弄清楚如何执行此操作。

有谁知道如何设置同时使用 Docker 和 VNet 的 Azure 功能?

最佳答案

默认情况下,api监听端口是80对吗?但是 VNet 在每次重新启动时通过 PORT 环境变量动态更改端口。即使您尝试手动将 PORT 环境变量设置为 80,VNet 仍会覆盖它。它是由 Vnet 提供的安全性的一部分。

解决方案是 api 的监听端口必须始终指向每个环境变量 PORT 是什么。

In your docker image, use the PORT environment variable as the main web server’s listening port, instead of using a hardcoded port number



As mentioned in the doc

建议

一种选择是代码级别,让您的应用程序监听 PORT 环境变量,如 this js exampleasp example .这里的问题是,您必须始终在运行应用程序的任何地方(本地或登台或生产)配置 PORT 环境变量,除非您进行额外的更改以检测 ENV PORT 进一步进入兔子洞。

另一种选择就是在docker build的时候把监听端口配置成ENVIRONMENT PORT。 ENTRYPOINT Dockerfile 中的命令如下所示:
ENTRYPOINT "dotnet" "Tutorial.WebApi.dll" --urls="http://0.0.0.0:${PORT:-80}"

关于docker - Azure 函数无法启动 - "Didn' t 响应端口 X 上的 HTTP ping”(Docker/VNet),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60675890/

相关文章:

python - 访问在 ubuntu 服务器上运行的 docker 上运行的 MySQL

azure - 即使在 30 秒后,逻辑应用也会返回网关超时错误

linux - 如何在无法启动的 Docker 容器中创建目录?

visual-studio - DOCKER_REGISTRY 变量未设置。默认为空字符串

c# - Azure Function 无法从设置加载 CRON 计时器

Azure 应用服务环境 - 为什么我无法选择现有子网?

Azure Vnet 对等互连与 Vnet 集成

database - docker 和 PostgreSQL : can not create database having '-' in database name during initialization

c# - Azure 功能防火墙