Azure功能无法启动-“未响应端口X上的HTTP ping" (Docker/VNet) [英] Azure Function Failing to Start - "Didn't respond to HTTP pings on port X" (Docker/VNet)

查看:181
本文介绍了Azure功能无法启动-“未响应端口X上的HTTP ping" (Docker/VNet)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很想弄清楚如何设置一个使用Docker容器映像并连接到VNet的Azure Function.我在任何地方都找不到此设置的任何示例.

I'm really struggling to figure out how to setup an Azure Function that uses a Docker container image and is connected to a VNet. I cannot find any examples of this setup anywhere.

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

The main issue I'm running into is that after my container is up and running, it does not seem to be responding to the HTTP pings the underlying framework uses to determine if the function is up and running. I believe the primary issue is that when you setup a Linux service that uses Docker and connect it to a VNet, the ports used are not standard (from what I understand). I have updated the ENTRYPOINT line in my dockerfile to handle this accordingly, however the port that is used to test for pings is not the port that is exposed via the docker run command. Here are the log entries that pertain to this startup error:

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这样作为环境变量传递.

As you can see in this example, port 8635 is being mapped (to port 8635) and is being specified as an environment variable, which is coming from the underlying vnet setup. However, the HTTP pings are being sent to port 3236. I see that this is part of the /Host.DestinationHostUrl parameter towards the end of the docker run command, but I don't see how I can get access to this parameter since it's not being passed as an environment variable like the PORT is.

这是我的Dockerfile:

Here is my 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不起作用.它会出现如下错误:

FYI The default Dockerfile created by the Azure Function tool chain does not work. It errors out with an error like this:

(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参数来完成上述操作.

To get around this error, I had to do what I said above by using the PORT environment variable and --urls parameter.

我假设我需要做的是将此另一个端口添加到我要传递给ENTRYPOINT的--urls=...参数中,但无法弄清楚该怎么做.

I assume what I need to do is add this other port to the --urls=... parameter I'm passing to the ENTRYPOINT, but cannot figure out how to do this.

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

Does anyone have any idea how to setup an Azure function that uses both Docker and VNet?

推荐答案

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

By default, the api listening port is 80 right? but VNet dynamically changes the port on every restart via PORT environment variable. Even if you attempt to set the PORT environment variable manually to 80, VNet still overrides it. Its part of the security provided by Vnet.

解决方案是api的侦听端口必须始终指向每个环境变量PORT所在的端口.

The solution is the api's listening port must always point to what every the environment variable PORT is.

在docker映像中,使用PORT环境变量作为主要Web服务器的侦听端口,而不是使用硬编码的端口号

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

文档中提到的

建议

一个选项是代码级,使您的应用监听PORT环境变量,例如 asp示例.这里的问题是,您必须始终在运行应用程序的任何地方(本地,暂存或生产环境)配置PORT环境变量,除非您进行了其他更改以检测ENV PORT进一步走到兔子洞之外,否则就没有此必要.

One option is code level, make your app listen to the PORT environment variable, like this js example or an asp example. The problem here is that you have to always configure the PORT environment variable anywhere you run your app (locally or staging or production), not unless you make additional changes to detect ENV PORT going down the rabbit hole further.

另一个选项是在Docker构建期间将侦听端口配置为ENVIRONMENT PORT. Dockerfile中的ENTRYPOINT命令如下所示:

Another option is to configure the listening port to ENVIRONMENT PORT during docker build. The ENTRYPOINT command in the Dockerfile looks like this:

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

这篇关于Azure功能无法启动-“未响应端口X上的HTTP ping" (Docker/VNet)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆