浏览代码

pkg/mesh: ignore CNI IP from private IPs

We need to ignore the CNI IP address from the searched IPs, as this will
not be a routable IP address.
Lucas Servén Marín 7 年之前
父节点
当前提交
d7ad946ff4
共有 3 个文件被更改,包括 60 次插入9 次删除
  1. 16 0
      pkg/mesh/cni.go
  2. 39 8
      pkg/mesh/ip.go
  3. 5 1
      pkg/mesh/mesh.go

+ 16 - 0
pkg/mesh/cni.go

@@ -25,8 +25,24 @@ import (
 	"github.com/containernetworking/cni/pkg/types"
 	ipamallocator "github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
 	"github.com/go-kit/kit/log/level"
+	"github.com/vishvananda/netlink"
 )
 
+const cniDeviceName = "kube-bridge"
+
+// Try to get the CNI device index.
+// Return 0 if not found and any error encountered.
+func cniDeviceIndex() (int, error) {
+	i, err := netlink.LinkByName(cniDeviceName)
+	if _, ok := err.(netlink.LinkNotFoundError); ok {
+		return 0, nil
+	}
+	if err != nil {
+		return 0, err
+	}
+	return i.Attrs().Index, nil
+}
+
 // updateCNIConfig will try to update the local node's CNI config.
 func (m *Mesh) updateCNIConfig() {
 	m.mu.Lock()

+ 39 - 8
pkg/mesh/ip.go

@@ -39,7 +39,26 @@ import (
 // - private IP assigned to interface of default route
 // - private IP assigned to local interface
 // - if no IP was found, return nil and an error.
-func getIP(hostname string) (*net.IPNet, *net.IPNet, error) {
+func getIP(hostname string, ignoreIfaces ...int) (*net.IPNet, *net.IPNet, error) {
+	ignore := make(map[string]struct{})
+	for i := range ignoreIfaces {
+		if ignoreIfaces[i] == 0 {
+			// Only ignore valid interfaces.
+			continue
+		}
+		iface, err := net.InterfaceByIndex(ignoreIfaces[i])
+		if err != nil {
+			return nil, nil, fmt.Errorf("failed to find interface %d: %v", ignoreIfaces[i], err)
+		}
+		ips, err := ipsForInterface(iface)
+		if err != nil {
+			return nil, nil, err
+		}
+		for _, ip := range ips {
+			ignore[ip.String()] = struct{}{}
+			ignore[oneAddressCIDR(ip.IP).String()] = struct{}{}
+		}
+	}
 	var hostPriv, hostPub []*net.IPNet
 	{
 		// Check IPs to which hostname resolves first.
@@ -112,13 +131,25 @@ func getIP(hostname string) (*net.IPNet, *net.IPNet, error) {
 		sortIPs(interfacePub)
 	}
 
-	var priv, pub []*net.IPNet
-	priv = append(priv, hostPriv...)
-	priv = append(priv, defaultPriv...)
-	priv = append(priv, interfacePriv...)
-	pub = append(pub, hostPub...)
-	pub = append(pub, defaultPub...)
-	pub = append(pub, interfacePub...)
+	var priv, pub, tmpPriv, tmpPub []*net.IPNet
+	tmpPriv = append(tmpPriv, hostPriv...)
+	tmpPriv = append(tmpPriv, defaultPriv...)
+	tmpPriv = append(tmpPriv, interfacePriv...)
+	tmpPub = append(tmpPub, hostPub...)
+	tmpPub = append(tmpPub, defaultPub...)
+	tmpPub = append(tmpPub, interfacePub...)
+	for i := range tmpPriv {
+		if _, ok := ignore[tmpPriv[i].String()]; ok {
+			continue
+		}
+		priv = append(priv, tmpPriv[i])
+	}
+	for i := range tmpPub {
+		if _, ok := ignore[tmpPub[i].String()]; ok {
+			continue
+		}
+		pub = append(pub, tmpPub[i])
+	}
 	if len(priv) == 0 && len(pub) == 0 {
 		return nil, nil, errors.New("no valid IP was found")
 	}

+ 5 - 1
pkg/mesh/mesh.go

@@ -234,7 +234,11 @@ func New(backend Backend, encapsulate Encapsulate, granularity Granularity, host
 	if err := ioutil.WriteFile(PrivateKeyPath, private, 0600); err != nil {
 		return nil, fmt.Errorf("failed to write private key to disk: %v", err)
 	}
-	privateIP, publicIP, err := getIP(hostname)
+	cniIndex, err := cniDeviceIndex()
+	if err != nil {
+		return nil, fmt.Errorf("failed to query netlink for CNI device: %v", err)
+	}
+	privateIP, publicIP, err := getIP(hostname, cniIndex)
 	if err != nil {
 		return nil, fmt.Errorf("failed to find public IP: %v", err)
 	}