dotnet / extensions

This repository contains a suite of libraries that provide facilities commonly needed when creating production-ready applications.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Microsoft.Extensions.Diagnostics.Probes.KubernetesProbesExtensions.AddKubernetesProbes() fails with SocketException "Only one usage of each socket address (protocol/network address/port) is normally permitted"

allenplusplus opened this issue · comments

Description

When application is started with AddKubernetesProbes() extension option we get SocketException Only one usage of each socket address (protocol/network address/port) is normally permitted errors in the console.

2024-04-03 11:24:19.941 (err ) 00000000000000000000000000000000 0000000000000000 Error updating health status through TCP endpoint (Microsoft.Extensions.Diagnostics.Probes.TcpEndpointHealthCheckService/SocketExceptionCaughtTcpEndpoint)

0: Exception: Only one usage of each socket address (protocol/network address/port) is normally permitted. (System.Net.Sockets.SocketException)
   at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, Boolean disconnectOnFailure, String callerName)
   at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Bind(EndPoint localEP)
   at System.Net.Sockets.TcpListener.Start(Int32 backlog)
   at Microsoft.Extensions.Diagnostics.Probes.TcpEndpointHealthCheckService.UpdateHealthStatusAsync(CancellationToken cancellationToken)

We were expecting that when AddKubernetesProbes() is called with no options, the default ports in https://github.com/dotnet/extensions/blob/main/src/Libraries/Microsoft.Extensions.Diagnostics.Probes/KubernetesProbesOptions.cs (2305, 2306, 2307) would be used. However when we check netstat, only 2305 port is bound and 2306/2307 ports are not bound.

This is occurring on dotnet 8.0.202 and on Microsoft.Extensions.Diagnostics.Probes version 8.0.0-rtm.23558.11 and 9.0.0-preview.2.24157.4 (didn't try other versions).

This only occurs on the base AddKubernetesProbes function without additional parameters.

When using the overloaded method and specifying the ports is used, the errors do not occur:

    private static int LIVENESS_PROBE_TCP_PORT = 2305;
    private static int STARTUP_PROBE_TCP_PORT = 2306;
    private static int READINESS_PROBE_TCP_PORT = 2307;

    public void ConfigureServices(IServiceCollection services)
    {
        services.TryAddSingleton(TimeProvider.System);
        services
            .AddControllers()
            .AddApplicationPart(typeof(Startup).Assembly);

        services
            .AddCoreServices(_configuration)
            .AddResourceMonitoring()
            .AddKubernetesProbes(options =>
            {
                options.LivenessProbe.TcpPort = LIVENESS_PROBE_TCP_PORT;
                options.StartupProbe.TcpPort = STARTUP_PROBE_TCP_PORT;
                options.ReadinessProbe.TcpPort = READINESS_PROBE_TCP_PORT;
            })
            .AddTelemetryHealthCheckPublisher()
            .AddHealthChecks();
    }
}

Reproduction Steps

  1. Create new webapi project: dotnet new webapi --name KubernetesProbesBugReport
  2. Add package reference to csproj: <PackageReference Include="Microsoft.Extensions.Diagnostics.Probes" Version="9.0.0-preview.2.24157.4"/>
  3. Add code to Program.cs:
#pragma warning disable EXTEXP0015 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
builder.Services.AddKubernetesProbes();
  1. Run dotnet run
  2. Observe SocketException errors in console

Expected behavior

There should not be any SocketException in the console when AddKubernetesProbes used and that default ports in KubernetesProbesOptions would be used.

Actual behavior

SocketExceptions are observed in the console when AddKubernetesProbes() is used.

2024-04-03 11:24:19.941 (err ) 00000000000000000000000000000000 0000000000000000 Error updating health status through TCP endpoint (Microsoft.Extensions.Diagnostics.Probes.TcpEndpointHealthCheckService/SocketExceptionCaughtTcpEndpoint)

0: Exception: Only one usage of each socket address (protocol/network address/port) is normally permitted. (System.Net.Sockets.SocketException)
   at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, Boolean disconnectOnFailure, String callerName)
   at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Bind(EndPoint localEP)
   at System.Net.Sockets.TcpListener.Start(Int32 backlog)
   at Microsoft.Extensions.Diagnostics.Probes.TcpEndpointHealthCheckService.UpdateHealthStatusAsync(CancellationToken cancellationToken)

Regression?

No response

Known Workarounds

Using one of the AddKubernetesProbes overloaded method and specifying the ports works:

    private static int LIVENESS_PROBE_TCP_PORT = 2305;
    private static int STARTUP_PROBE_TCP_PORT = 2306;
    private static int READINESS_PROBE_TCP_PORT = 2307;

    public void ConfigureServices(IServiceCollection services)
    {
        services.TryAddSingleton(TimeProvider.System);
        services
            .AddControllers()
            .AddApplicationPart(typeof(Startup).Assembly);

        services
            .AddCoreServices(_configuration)
            .AddResourceMonitoring()
            .AddKubernetesProbes(options =>
            {
                options.LivenessProbe.TcpPort = LIVENESS_PROBE_TCP_PORT;
                options.StartupProbe.TcpPort = STARTUP_PROBE_TCP_PORT;
                options.ReadinessProbe.TcpPort = READINESS_PROBE_TCP_PORT;
            })
            .AddTelemetryHealthCheckPublisher()
            .AddHealthChecks();
    }
}

Configuration

No response

Other information

No response