在 .net 核心应用程序中获取 Docker 个容器 IP
Get Docker container IP within a .net core application
使用 .net core
在容器本身内获取当前 docker 容器 IP 地址的最佳方法是什么?
我尝试将我的容器注册到 Consul
服务器上,该服务器托管在 Docker 主机上(不是作为容器),我需要在启动时获取容器 IP 地址,以便登记。因为 IP 地址在任何容器启动时都会发生变化,所以我不能将其硬编码到 appsettings.json
中。我关注了这个tutorial。当谈到这个部分时:
// 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" }
};
接收到的address
只包含环回地址而不是实际的容器地址(从外面看- Consul
所在的主机是运行)。我已经尝试使用 HttpContext
(在启动 class 中是 null
)和 IHttpContextAccessor
,此时也不包含任何内容。
编辑:这是我的一部分 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" ]
}
Uri
是我的主机系统中的一个,我设法在 Consul 中注册了该服务。缺少的部分是 <CONTAINER_IP/DNS>
,Consul 需要它来对特定容器执行一些检查。在这里,我需要容器的 IP 或可从主机系统访问它的 DNS。我知道这个 IP 会随着每个容器启动而切换,并且它在设置中只是为了演示目的(如果我能在启动时获得 IP 我很高兴)。
好的,我成功了,而且比我想象的要容易得多。
var name = Dns.GetHostName(); // get container id
var ip = Dns.GetHostEntry(name).AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);
使用 container_id/name
如果它是 IP4 地址,我可以通过简单的比较获得 IP。然后我可以使用这个地址并将它传递给 Consul。健康检查现在可以使用外部主机的 IP 成功调用容器。
我对结果仍然不是 100% 满意,因为它依赖于 AddressList
中的 "first" 有效 IP4 地址(目前没有更多所以我得到了这个).仍然欢迎任何更好/更通用的解决方案。
我也有上面的要求,我必须启动一个 docker 容器并获取容器 IP 地址并保存到某个目录,所有这些都使用 c#(.net 核心)(这个概念将适用于其他编程语言也是如此)。下面是一段代码来实现这一点。喜欢请投赞成票,不喜欢请评论。
注意:此方法非常可靠,因为它会获取您想要的特定容器的 IP 地址。
static void Main(string[] args)
{
Console.WriteLine("Getting Container IP...");
//This command returns back ip address of the required container.
string inspectCommand = string.Concat("inspect -f ", "\"{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}\"", " container ID/Name");
//The command is appended with string 'docker' as all docker commans starts with it
var processInfo = new ProcessStartInfo("docker", $"{inspectCommand}");
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;'
using (var process = new Process())
{
process.StartInfo = processInfo;
var started = process.Start();
StreamReader reader = process.StandardOutput;
//to remove any unwanted char if appended
ip = Regex.Replace(reader.ReadToEnd(), @"\t|\n|\r", "");
if(string.IsNullOrEmpty(ip))
{
Console.WriteLine($"Unable to get ip of the container");
Environment.Exit(1);
}
Console.WriteLine($"Azurite conatainer is listening @ {ip}");
Environment.Exit(1);
}}
使用 .net core
在容器本身内获取当前 docker 容器 IP 地址的最佳方法是什么?
我尝试将我的容器注册到 Consul
服务器上,该服务器托管在 Docker 主机上(不是作为容器),我需要在启动时获取容器 IP 地址,以便登记。因为 IP 地址在任何容器启动时都会发生变化,所以我不能将其硬编码到 appsettings.json
中。我关注了这个tutorial。当谈到这个部分时:
// 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" }
};
接收到的address
只包含环回地址而不是实际的容器地址(从外面看- Consul
所在的主机是运行)。我已经尝试使用 HttpContext
(在启动 class 中是 null
)和 IHttpContextAccessor
,此时也不包含任何内容。
编辑:这是我的一部分 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" ]
}
Uri
是我的主机系统中的一个,我设法在 Consul 中注册了该服务。缺少的部分是 <CONTAINER_IP/DNS>
,Consul 需要它来对特定容器执行一些检查。在这里,我需要容器的 IP 或可从主机系统访问它的 DNS。我知道这个 IP 会随着每个容器启动而切换,并且它在设置中只是为了演示目的(如果我能在启动时获得 IP 我很高兴)。
好的,我成功了,而且比我想象的要容易得多。
var name = Dns.GetHostName(); // get container id
var ip = Dns.GetHostEntry(name).AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);
使用 container_id/name
如果它是 IP4 地址,我可以通过简单的比较获得 IP。然后我可以使用这个地址并将它传递给 Consul。健康检查现在可以使用外部主机的 IP 成功调用容器。
我对结果仍然不是 100% 满意,因为它依赖于 AddressList
中的 "first" 有效 IP4 地址(目前没有更多所以我得到了这个).仍然欢迎任何更好/更通用的解决方案。
我也有上面的要求,我必须启动一个 docker 容器并获取容器 IP 地址并保存到某个目录,所有这些都使用 c#(.net 核心)(这个概念将适用于其他编程语言也是如此)。下面是一段代码来实现这一点。喜欢请投赞成票,不喜欢请评论。
注意:此方法非常可靠,因为它会获取您想要的特定容器的 IP 地址。
static void Main(string[] args)
{
Console.WriteLine("Getting Container IP...");
//This command returns back ip address of the required container.
string inspectCommand = string.Concat("inspect -f ", "\"{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}\"", " container ID/Name");
//The command is appended with string 'docker' as all docker commans starts with it
var processInfo = new ProcessStartInfo("docker", $"{inspectCommand}");
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;'
using (var process = new Process())
{
process.StartInfo = processInfo;
var started = process.Start();
StreamReader reader = process.StandardOutput;
//to remove any unwanted char if appended
ip = Regex.Replace(reader.ReadToEnd(), @"\t|\n|\r", "");
if(string.IsNullOrEmpty(ip))
{
Console.WriteLine($"Unable to get ip of the container");
Environment.Exit(1);
}
Console.WriteLine($"Azurite conatainer is listening @ {ip}");
Environment.Exit(1);
}}