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
- Create new webapi project:
dotnet new webapi --name KubernetesProbesBugReport
- Add package reference to csproj:
<PackageReference Include="Microsoft.Extensions.Diagnostics.Probes" Version="9.0.0-preview.2.24157.4"/>
- 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();
- Run
dotnet run
- 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