Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch container IPs directly from the namespace instead of calling 'weave ps' #3207

Merged
merged 6 commits into from
Jun 4, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.9.2-stretch
FROM golang:1.10.2-stretch
ENV SCOPE_SKIP_UI_ASSETS true
RUN apt-get update && \
apt-get install -y libpcap-dev python-requests time file shellcheck git gcc-arm-linux-gnueabihf curl build-essential python-pip && \
Expand Down
21 changes: 21 additions & 0 deletions probe/docker/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ func isIPv4(addr string) bool {
return ip != nil && ip.To4() != nil
}

func contains(strs []string, str string) bool {
for _, s := range strs {
if s == str {
return true
}
}
return false
}

func (c *container) NetworkInfo(localAddrs []net.IP) report.Sets {
c.RLock()
defer c.RUnlock()
Expand All @@ -277,6 +286,18 @@ func (c *container) NetworkInfo(localAddrs []net.IP) report.Sets {
ips = append(ips, c.container.NetworkSettings.IPAddress)
}

// Fetch IP addresses from the container's namespace
cidrs, err := namespaceIPAddresses(c.container.State.Pid)
if err != nil {
log.Debugf("container %s: failed to get addresses: %s", c.container.ID, err)
}
for _, cidr := range cidrs {
ip := cidr.IP.String()
if !contains(ips, ip) {

This comment was marked as abuse.

ips = append(ips, ip)
}
}

// For now, for the proof-of-concept, we just add networks as a set of
// names. For the next iteration, we will probably want to create a new
// Network topology, populate the network nodes with all of the details
Expand Down
85 changes: 85 additions & 0 deletions probe/docker/network.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// withNetNS function requires a fix that first appeared in Go version 1.10
// +build go1.10

package docker

import (
"fmt"
"net"
"runtime"

"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
"golang.org/x/sys/unix"
)

// Code adapted from github.com/weaveworks/weave/net/netdev.go

// Return any non-local IP addresses for processID if in a non-root namespace
func namespaceIPAddresses(processID int) ([]*net.IPNet, error) {
// Ignore if this process is running in the root namespace
netnsRoot, err := netns.GetFromPid(1)
if err != nil {
return nil, fmt.Errorf("unable to open root namespace: %s", err)
}
defer netnsRoot.Close()
netnsContainer, err := netns.GetFromPid(processID)
if err != nil {
return nil, err
}
defer netnsContainer.Close()
if netnsRoot.Equal(netnsContainer) {
return nil, nil
}

var cidrs []*net.IPNet
err = withNetNS(netnsContainer, func() error {
cidrs, err = allNonLocalAddresses()
return err
})

return cidrs, err
}

// return all non-local IP addresses from the current namespace
func allNonLocalAddresses() ([]*net.IPNet, error) {
var cidrs []*net.IPNet
links, err := netlink.LinkList()
if err != nil {
return nil, err
}

for _, link := range links {
addrs, err := netlink.AddrList(link, netlink.FAMILY_ALL)
if err != nil {
return nil, err
}
for _, addr := range addrs {
// Exclude link-local ipv6 addresses, localhost, etc. Hope this is the correct test.
if addr.Scope == unix.RT_SCOPE_UNIVERSE {
cidrs = append(cidrs, addr.IPNet)
}
}
}
return cidrs, nil
}

// Run the 'work' function in a different network namespace
func withNetNS(ns netns.NsHandle, work func() error) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()

oldNs, err := netns.Get()
if err == nil {
defer oldNs.Close()

err = netns.Set(ns)
if err == nil {
defer netns.Set(oldNs)

err = work()
}
}

return err
}
192 changes: 192 additions & 0 deletions vendor/github.com/vishvananda/netlink/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions vendor/github.com/vishvananda/netlink/addr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading