From db078dbea4efef593933fe0a86e6ce9fea790b1e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 21 Jun 2016 16:58:30 -0500 Subject: [PATCH] kubelet/cni/kubenet: use common container IP address functions --- pkg/kubelet/network/cni/cni.go | 32 +---------------- pkg/kubelet/network/kubenet/kubenet_linux.go | 15 ++------ pkg/kubelet/network/plugins.go | 38 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 43 deletions(-) diff --git a/pkg/kubelet/network/cni/cni.go b/pkg/kubelet/network/cni/cni.go index 06d7fcabf04..2356cb5bcfb 100644 --- a/pkg/kubelet/network/cni/cni.go +++ b/pkg/kubelet/network/cni/cni.go @@ -18,9 +18,7 @@ package cni import ( "fmt" - "net" "sort" - "strings" "github.com/appc/cni/libcni" cnitypes "github.com/appc/cni/pkg/types" @@ -138,30 +136,6 @@ func (plugin *cniNetworkPlugin) TearDownPod(namespace string, name string, id ku return plugin.defaultNetwork.deleteFromNetwork(name, namespace, id, netnsPath) } -func (plugin *cniNetworkPlugin) getContainerIPAddress(netnsPath, addrType string) (net.IP, error) { - // Try to retrieve ip inside container network namespace - output, err := plugin.execer.Command(plugin.nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--", - "ip", "-o", addrType, "addr", "show", "dev", network.DefaultInterfaceName, "scope", "global").CombinedOutput() - if err != nil { - return nil, fmt.Errorf("Unexpected command output %s with error: %v", output, err) - } - - lines := strings.Split(string(output), "\n") - if len(lines) < 1 { - return nil, fmt.Errorf("Unexpected command output %s", output) - } - fields := strings.Fields(lines[0]) - if len(fields) < 4 { - return nil, fmt.Errorf("Unexpected address output %s ", lines[0]) - } - ip, _, err := net.ParseCIDR(fields[3]) - if err != nil { - return nil, fmt.Errorf("CNI failed to parse ip from output %s due to %v", output, err) - } - - return ip, nil -} - // TODO: Use the addToNetwork function to obtain the IP of the Pod. That will assume idempotent ADD call to the plugin. // Also fix the runtime's call to Status function to be done only in the case that the IP is lost, no need to do periodic calls func (plugin *cniNetworkPlugin) GetPodNetworkStatus(namespace string, name string, id kubecontainer.ContainerID) (*network.PodNetworkStatus, error) { @@ -170,11 +144,7 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(namespace string, name strin return nil, fmt.Errorf("CNI failed to retrieve network namespace path: %v", err) } - ip, err := plugin.getContainerIPAddress(netnsPath, "-4") - if err != nil { - // Fall back to IPv6 address if no IPv4 address is present - ip, err = plugin.getContainerIPAddress(netnsPath, "-6") - } + ip, err := network.GetPodIP(plugin.execer, plugin.nsenterPath, netnsPath, network.DefaultInterfaceName) if err != nil { return nil, err } diff --git a/pkg/kubelet/network/kubenet/kubenet_linux.go b/pkg/kubelet/network/kubenet/kubenet_linux.go index 8ced3032dd6..4685529ca4c 100644 --- a/pkg/kubelet/network/kubenet/kubenet_linux.go +++ b/pkg/kubelet/network/kubenet/kubenet_linux.go @@ -468,20 +468,11 @@ func (plugin *kubenetNetworkPlugin) GetPodNetworkStatus(namespace string, name s if err != nil { return nil, err } - // Try to retrieve ip inside container network namespace - output, err := plugin.execer.Command(nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--", - "ip", "-o", "-4", "addr", "show", "dev", network.DefaultInterfaceName).CombinedOutput() + ip, err := network.GetPodIP(plugin.execer, nsenterPath, netnsPath, network.DefaultInterfaceName) if err != nil { - return nil, fmt.Errorf("Unexpected command output %s with error: %v", output, err) - } - fields := strings.Fields(string(output)) - if len(fields) < 4 { - return nil, fmt.Errorf("Unexpected command output %s ", output) - } - ip, _, err := net.ParseCIDR(fields[3]) - if err != nil { - return nil, fmt.Errorf("Kubenet failed to parse ip from output %s due to %v", output, err) + return nil, err } + plugin.podIPs[id] = ip.String() return &network.PodNetworkStatus{IP: ip}, nil } diff --git a/pkg/kubelet/network/plugins.go b/pkg/kubelet/network/plugins.go index 405a2d1564c..25c14937e97 100644 --- a/pkg/kubelet/network/plugins.go +++ b/pkg/kubelet/network/plugins.go @@ -199,3 +199,41 @@ func (plugin *NoopNetworkPlugin) GetPodNetworkStatus(namespace string, name stri func (plugin *NoopNetworkPlugin) Status() error { return nil } + +func getOnePodIP(execer utilexec.Interface, nsenterPath, netnsPath, interfaceName, addrType string) (net.IP, error) { + // Try to retrieve ip inside container network namespace + output, err := execer.Command(nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--", + "ip", "-o", addrType, "addr", "show", "dev", interfaceName, "scope", "global").CombinedOutput() + if err != nil { + return nil, fmt.Errorf("Unexpected command output %s with error: %v", output, err) + } + + lines := strings.Split(string(output), "\n") + if len(lines) < 1 { + return nil, fmt.Errorf("Unexpected command output %s", output) + } + fields := strings.Fields(lines[0]) + if len(fields) < 4 { + return nil, fmt.Errorf("Unexpected address output %s ", lines[0]) + } + ip, _, err := net.ParseCIDR(fields[3]) + if err != nil { + return nil, fmt.Errorf("CNI failed to parse ip from output %s due to %v", output, err) + } + + return ip, nil +} + +// GetPodIP gets the IP of the pod by inspecting the network info inside the pod's network namespace. +func GetPodIP(execer utilexec.Interface, nsenterPath, netnsPath, interfaceName string) (net.IP, error) { + ip, err := getOnePodIP(execer, nsenterPath, netnsPath, interfaceName, "-4") + if err != nil { + // Fall back to IPv6 address if no IPv4 address is present + ip, err = getOnePodIP(execer, nsenterPath, netnsPath, interfaceName, "-6") + } + if err != nil { + return nil, err + } + + return ip, nil +}