在.net核心应用程序中获取Docker容器IP

时间:2018-08-20 07:05:50

标签: docker asp.net-core consul

使用.net core在容器本身内获取当前docker容器IP地址的最佳方法是什么?

我尝试将容器注册到托管在Docker主机上的Consul服务器上(而不作为容器),我需要在启动时获取容器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(在启动类中为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)。

2 个答案:

答案 0 :(得分:3)

好吧,我可以正常工作了,它比我想象的要容易得多。

var name = Dns.GetHostName(); // get container id
var ip = Dns.GetHostEntry(name).AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);

使用container_id/name,如果它是IP4地址,则可以轻松比较该IP。然后,我可以使用该地址并将其传递给领事。现在,运行状况检查可以从外部主机成功调用具有IP的容器。

我对结果仍然不是100%满意,因为它依赖于AddressList中的“第一个”有效IP4地址(当前没有更多内容,因此我可以这样做)。任何更好/更通用的解决方案仍然会受到欢迎。

答案 1 :(得分:-1)

我也有一个要求,在上面我必须旋转一个docker容器并获取容器IP地址并全部使用c#(。net core)保存到某个目录(此概念也适用于其他编程语言) 。下面是实现该目标的代码。如果您愿意,请进行投票,如果您不喜欢,请发表评论。

注意:此方法非常可靠,因为它将获取您想要的特定容器的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);
           }}