简体   繁体   中英

Unable to get Linux container running as Azure function in isolated process

The function app runs locally but is deployed as a Linux container. The deployed function isn't reporting any issues in the portal and I can see the three functions listed in the Functions blade. However, none are working (one is a simple HTTP ping which is returning a 502 Bad Gateway response).

So no obvious issues in the portal, but inspection of logs reveals this recurring exception:

System.Threading.Tasks.TaskCanceledException at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess

The formatted message is:

Failed to start a new language worker for runtime: dotnet-isolated

My suspicion is that this is something to do with the value of the site setting linuxFxVersion . Mind you, I've tried using DOTNET|6.0 and DOTNET-ISOLATED|6.0 . In both cases it doesn't seem to make a difference and anyway when I export the function app's ARM template it has linuxFxVersion set to the URI of the container image prefixed with DOCKER| .

That seems to relate to this specific advice from Microsoft about pinning the host version on Linux. But it still isn't clear to me which value I should us, and anyway, in another place the advice from another Microsoft document states:

To support zip deployment and running from the deployment package on Linux, you also need to update the linuxFxVersion site config setting to DOTNET-ISOLATED|6.0.

Anyway, Here are the details of my config. I've followed every bit of guidance from Microsoft so I hope someone can spot what I've missed...

First two parts of project file:

<PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <AzureFunctionsVersion>V4</AzureFunctionsVersion>
    <OutputType>Exe</OutputType>
    <ImplicitUsings>true</ImplicitUsings>
    <Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.CosmosDB" Version="3.0.9" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.3.0" OutputItemType="Analyzer" />
    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.5.2" />
</ItemGroup>

host.json:

{
    "version": "2.0",
    "logging": {
        "applicationInsights": {
            "samplingSettings": {
                "isEnabled": true,
                "excludedTypes": "Request"
            }
        }
    }
}

Main method in Program.cs:

public static async Task Main()
{
    var host = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults()
        .ConfigureAppConfiguration((context, configurationBuilder) =>
        {
            configurationBuilder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

            if (context.HostingEnvironment.IsDevelopment())
            {
                configurationBuilder.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true);
            }
            else
            {
                configurationBuilder.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
            }

            configurationBuilder.AddEnvironmentVariables();
        })
        .ConfigureServices((context, collection) => ConfigureServices(collection, context.Configuration, context.HostingEnvironment))
        .Build()
        .RunAsync();
}

The function provisioning pipeline sets the following app settings:

FUNCTIONS_EXTENSION_VERSION: '~4'
FUNCTIONS_WORKER_RUNTIME: 'dotnet-isolated'

As stated above, the latest version of my site config defined during provisioning includes this:

linuxFxVersion: 'DOTNET-ISOLATED|6.0'

The Docker image uses mcr.microsoft.com/azure-functions/dotnet-isolated:4 as a base image for the published app, and mcr.microsoft.com/dotnet/sdk:6.0 to build it.

Please tell me there's something obvious I'm missing. We currently have two function apps, and neither can be deployed as dotnet-isolated. It's driving me mad!

After battling with this for 2 days I decide to strip right down to the bare bones. Followed the Microsoft guide from scratch. This led me to identify the following line as the problem:

configurationBuilder.AddEnvironmentVariables();

As soon as I add this line to my Program and push a new image to the function app, everything breaks upon restart. However, there's no indication as to why. The Docker logs exposed by Kudo report this as the final entry:

2022-05-18T14:06:46.295Z INFO - Container [image-name] for site [function-name] initialized successfully and is ready to serve requests.

App Insights traces indicate that an exception has occurred at line 52 of Program.cs, which is my host.Run(); line.

The exception itself is:

System.InvalidOperationException at Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcFunctionInvocationDispatcherLoadBalancer.GetLanguageWorkerChannel

And there's a message hidden in there saying "Did not find any initialized language workers" which I understand is Azure Function language for "something bad happened during startup but I'm not going to tell you what or why".

So this at least explains why my function wasn't running, and hopefully my experience will save someone else time in the future, but since my app depends on configuration added to the function by a pipeline I still don't have a working app. For that I will ask a new question and link it here...

Update

Here is the follow up question , which I've already answered!

The exception what you saw is not directly from your application, instead it is a general exception without detaills from an Azure Function runtime-process - so it's useless.

The reasons can be anything, for example: forget to await on a task.

public static async Task Main()
{
   var host = new HostBuilder()
      .ConfigureFunctionsWorkerDefaults()
      .ConfigureAppConfiguration(builder =>
      {
         builder
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true)
            .Build();
      })
      .ConfigureServices((context, collection) => ConfigureServices(collection, context.Configuration, context.HostingEnvironment))
    .Build();

     host.RunAsync();  // await host.RunAsync();
}

Or a corrupted appsettings.json

{
   "Logging": {
      "LogLevel": {
         "Default": "Warning",
         "Microsoft": "Warning",
         "Host": "Warning",
         "Function": "Information",
         "Host.Aggregator": "Information"
      }

}

Or a missing configure call during startup.

public static async Task Main()
{
   var host = new HostBuilder()
      // .ConfigureFunctionsWorkerDefaults()
      .ConfigureAppConfiguration(builder =>
      {
         builder
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true)
            .Build();
      }))
      .ConfigureServices((context, collection) => ConfigureServices(collection, context.Configuration, context.HostingEnvironment))
    .Build();

     await host.RunAsync();
}

That runtime-process from Microsoft which launches your application captures all your console logs and trashes them in case of exceptions during its own startup.

Btw, you should also enable Code Analysis which is per default not enabled in .net 6.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM