What is the best way to get the current docker container IP address within the container itself using .net core
?
I try to register my container to a Consul
server which is hosted on the Docker host (not as a container) and I need to get the container IP address on startup to make the registration. Because the IP addresses change on any container startup I can't just hard-code it into the appsettings.json
. I followed this tutorial. And when it comes to this section:
// Get server IP address
var features = app.Properties["server.Features"] as FeatureCollection;
var addresses = features.Get<IServerAddressesFeature>();
var address = addresses.Addresses.First();
// Register service with consul
var uri = new Uri(address);
var registration = new AgentServiceRegistration()
{
ID = $"{consulConfig.Value.ServiceID}-{uri.Port}",
Name = consulConfig.Value.ServiceName,
Address = $"{uri.Scheme}://{uri.Host}",
Port = uri.Port,
Tags = new[] { "Students", "Courses", "School" }
};
The received address
contains only the loopback address and not the actual container address (as seen from outside - the host where Consul
is running). I already tried to use the HttpContext
(which is null
in the startup class) and the IHttpContextAccessor
which also does not contain anything at this time.
EDIT: This is a part of my appsettings.json
:
"ServiceRegistry": {
"Uri": "http://172.28.112.1:8500",
"Name": "AuthServiceApi",
"Id": "auth-service-api-v1",
"ContainerAddress": "http://<CONTAINER_IP/DNS>",
"Checks": [
{
"Service": "/health",
"Timeout": 5,
"Interval": 10
}
],
"Tags": [ "Auth", "User" ]
}
The Uri
is the one from my host system and I managed to register the service in Consul. The missing part is the <CONTAINER_IP/DNS>
which is needed for Consul to perform some checks for that particular container. Here I need either the IP of the container or the DNS on which it is accessible from the host system. I know that this IP will switch with every container starup and it's in the settings only for demonstration purpose (I'm happy if I can get the IP at startup time).
Ok, I got it working and it was much easier than I thought.
var name = Dns.GetHostName(); // get container id
var ip = Dns.GetHostEntry(name).AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);
With the container_id/name
I could get the IP with an easy compare if it's an IP4 address. I then can use this address and pass it to Consul. The health checks can now successfully call the container with it's IP from the outside host.
I'm still not 100% satisfied with the result because it relies on the "first" valid IP4 address in the AddressList
(currently, there are no more so I got this going for me). Any better / more generic solution would still be welcome.