From 118c1740da309545fa6db7caa165eb6da50a701f Mon Sep 17 00:00:00 2001 From: Yu Yang Date: Mon, 21 Aug 2023 14:14:58 +0800 Subject: [PATCH] fetch ip address fort NIC when IPAddress is null (#106) --- .golangci.yml | 2 +- go.mod | 1 + go.sum | 2 ++ runtime/docker/docker.go | 49 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b29f6a7..6fd02de 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -19,7 +19,7 @@ linters: enable: - bodyclose - deadcode - # - depguard + # - depguard - dogsled - gochecknoinits - goconst diff --git a/go.mod b/go.mod index 1f3ecd8..9a598ec 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible github.com/stretchr/testify v1.8.2 github.com/urfave/cli/v2 v2.25.1 + github.com/vishvananda/netns v0.0.4 go.uber.org/automaxprocs v1.5.2 golang.org/x/sys v0.8.0 gopkg.in/yaml.v2 v2.4.0 diff --git a/go.sum b/go.sum index 881706f..b35ca93 100644 --- a/go.sum +++ b/go.sum @@ -292,6 +292,8 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBn github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= +github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= diff --git a/runtime/docker/docker.go b/runtime/docker/docker.go index 6615044..45361f5 100644 --- a/runtime/docker/docker.go +++ b/runtime/docker/docker.go @@ -6,8 +6,10 @@ import ( "fmt" "io" "math" + "net" "net/http/httputil" "os" + "runtime" "strings" "time" @@ -16,6 +18,7 @@ import ( "github.com/projecteru2/agent/utils" "github.com/projecteru2/core/cluster" coreutils "github.com/projecteru2/core/utils" + "github.com/vishvananda/netns" enginetypes "github.com/docker/docker/api/types" enginecontainer "github.com/docker/docker/api/types/container" @@ -169,6 +172,36 @@ func (d *Docker) checkHostname(env []string) bool { return false } +func getAddrsFromNS(cid string, ifname string) ([]net.Addr, error) { + // Lock the OS Thread so we don't accidentally switch namespaces + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + // Save the current network namespace + origns, _ := netns.Get() + defer origns.Close() + defer netns.Set(origns) //nolint:errcheck + + containerNS, err := netns.GetFromDocker(cid) + if err != nil { + return nil, err + } + defer containerNS.Close() + + if err := netns.Set(containerNS); err != nil { + return nil, err + } + eth0, err := net.InterfaceByName(ifname) + if err != nil { + return nil, err + } + addrs, err := eth0.Addrs() + if err != nil { + return nil, err + } + return addrs, nil +} + // detectWorkload detect a container by ID func (d *Docker) detectWorkload(ctx context.Context, ID string) (*Container, error) { // 标准化为 inspect 的数据 @@ -205,7 +238,7 @@ func (d *Docker) detectWorkload(ctx context.Context, ID string) (*Container, err container.Memory = d.memory } // 活着才有发布必要 - if c.NetworkSettings != nil && container.Running { + if c.NetworkSettings != nil && container.Running { //nolint:nestif networks := map[string]string{} for name, endpoint := range c.NetworkSettings.Networks { networkmode := enginecontainer.NetworkMode(name) @@ -216,6 +249,20 @@ func (d *Docker) detectWorkload(ctx context.Context, ID string) (*Container, err container.LocalIP = endpoint.IPAddress networks[name] = endpoint.IPAddress } + if networks[name] == "" { + addrs, err := getAddrsFromNS(c.ID, "eth0") + if err != nil { + log.Error(ctx, err, "failed to get eth0 addrs") + } + if len(addrs) > 0 { + ip, _, err := net.ParseCIDR(addrs[0].String()) + if err == nil { + networks[name] = ip.String() + } else { + log.Error(ctx, err, "failed to parse cidr %s", addrs[0].String()) + } + } + } break } container.Networks = networks