【问题标题】:Azure Function Failing to Start - "Didn't respond to HTTP pings on port X" (Docker/VNet)Azure 函数无法启动 - “未响应端口 X 上的 HTTP ping”(Docker/VNet)
【发布时间】:2020-06-25 18:57:27
【问题描述】:

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

我遇到的主要问题是,在我的容器启动并运行之后,它似乎没有响应底层框架用来确定函数是否启动并运行的 HTTP ping。我认为主要问题是,当您设置使用 Docker 的 Linux 服务并将其连接到 VNet 时,使用的端口不是标准的(据我了解)。我已经更新了 dockerfile 中的 ENTRYPOINT 行以相应地处理此问题,但是用于测试 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 参数来执行我上面所说的操作。

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

有人知道如何设置一个同时使用 Docker 和 VNet 的 Azure 函数吗?

【问题讨论】:

    标签: docker azure-functions vnet


    【解决方案1】:

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

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

    在你的 docker 镜像中,使用 PORT 环境变量作为主 web 服务器的监听端口,而不是使用硬编码的端口号

    As mentioned in the doc


    建议

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


    另一个选项是在 docker build 期间将监听端口配置为 ENVIRONMENT PORT。 Dockerfile 中的ENTRYPOINT 命令如下所示:

    ENTRYPOINT "dotnet" "Tutorial.WebApi.dll" --urls="http://0.0.0.0:${PORT:-80}"
    

    【讨论】:

    • 我已经这样做了(请查看我的 docker 文件的底部 - 我什至有一条评论解释了我为什么使用 --urls 参数)。我的与您的略有不同,我可以向您保证,两者都不起作用。我的问题是如何使用 Azure 函数来做到这一点。他们的示例 docker 文件根本不使用 ENTRYPOINT,因为他们已经在他们的文件中定义了它。你知道如何让它与 Azure 函数、Docker 和 VNet 一起工作吗?
    【解决方案2】:

    我相信当您使用函数基本标记的-appservice 变体时,我们会处理正确的端口转发。

    https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-function-linux-custom-image?tabs=bash%2Cportal&pivots=programming-language-csharp#enable-ssh-connections

    所以从这个修改dockerfile中的这一行:

    FROM mcr.microsoft.com/azure-functions/dotnet:2.0 AS base

    到这里

    FROM mcr.microsoft.com/azure-functions/dotnet:2.0-appservice AS base

    可以解决

    【讨论】:

    • 我真的很希望能做到这一点,但我已经做出了改变,但仍然看到同样的问题。这似乎不是解决办法...
    猜你喜欢
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多