Ipv6; BGP peering (#545)

* Use ip6tables for ipv6 and handle ipv6 for egress rules

* Make the temp ipset's fit into 31 characters

This should be improved. Some hash string should be used for
temp names.
This commit is contained in:
Lars Ekman 2018-10-10 07:32:59 +02:00 committed by Murali Reddy
parent a47e0f4541
commit 077ff86bcc
4 changed files with 63 additions and 35 deletions

View File

@ -60,6 +60,7 @@ type NetworkRoutingController struct {
nodeName string nodeName string
nodeSubnet net.IPNet nodeSubnet net.IPNet
nodeInterface string nodeInterface string
isIpv6 bool
activeNodes map[string]bool activeNodes map[string]bool
mu sync.Mutex mu sync.Mutex
clientset kubernetes.Interface clientset kubernetes.Interface
@ -151,7 +152,7 @@ func (nrc *NetworkRoutingController) Run(healthChan chan<- *healthcheck.Controll
} }
glog.V(1).Info("Performing cleanup of depreciated rules/ipsets (if needed).") glog.V(1).Info("Performing cleanup of depreciated rules/ipsets (if needed).")
err = deleteBadPodEgressRules() err = nrc.deleteBadPodEgressRules()
if err != nil { if err != nil {
glog.Errorf("Error cleaning up old/bad Pod egress rules: %s", err.Error()) glog.Errorf("Error cleaning up old/bad Pod egress rules: %s", err.Error())
} }
@ -160,14 +161,14 @@ func (nrc *NetworkRoutingController) Run(healthChan chan<- *healthcheck.Controll
if nrc.enablePodEgress { if nrc.enablePodEgress {
glog.V(1).Infoln("Enabling Pod egress.") glog.V(1).Infoln("Enabling Pod egress.")
err = createPodEgressRule() err = nrc.createPodEgressRule()
if err != nil { if err != nil {
glog.Errorf("Error enabling Pod egress: %s", err.Error()) glog.Errorf("Error enabling Pod egress: %s", err.Error())
} }
} else { } else {
glog.V(1).Infoln("Disabling Pod egress.") glog.V(1).Infoln("Disabling Pod egress.")
err = deletePodEgressRule() err = nrc.deletePodEgressRule()
if err != nil { if err != nil {
glog.Warningf("Error cleaning up Pod Egress related networking: %s", err) glog.Warningf("Error cleaning up Pod Egress related networking: %s", err)
} }
@ -458,18 +459,18 @@ func (nrc *NetworkRoutingController) injectRoute(path *table.Path) error {
// Cleanup performs the cleanup of configurations done // Cleanup performs the cleanup of configurations done
func (nrc *NetworkRoutingController) Cleanup() { func (nrc *NetworkRoutingController) Cleanup() {
// Pod egress cleanup // Pod egress cleanup
err := deletePodEgressRule() err := nrc.deletePodEgressRule()
if err != nil { if err != nil {
glog.Warningf("Error deleting Pod egress iptable rule: %s", err.Error()) glog.Warningf("Error deleting Pod egress iptable rule: %s", err.Error())
} }
err = deleteBadPodEgressRules() err = nrc.deleteBadPodEgressRules()
if err != nil { if err != nil {
glog.Warningf("Error deleting Pod egress iptable rule: %s", err.Error()) glog.Warningf("Error deleting Pod egress iptable rule: %s", err.Error())
} }
// delete all ipsets created by kube-router // delete all ipsets created by kube-router
ipset, err := utils.NewIPSet(false) ipset, err := utils.NewIPSet(nrc.isIpv6)
if err != nil { if err != nil {
glog.Errorf("Failed to clean up ipsets: " + err.Error()) glog.Errorf("Failed to clean up ipsets: " + err.Error())
} }
@ -535,12 +536,20 @@ func (nrc *NetworkRoutingController) syncNodeIPSets() error {
return nil return nil
} }
func (nrc *NetworkRoutingController) newIptablesCmdHandler() (*iptables.IPTables, error) {
if nrc.isIpv6 {
return iptables.NewWithProtocol(iptables.ProtocolIPv6)
} else {
return iptables.NewWithProtocol(iptables.ProtocolIPv4)
}
}
// ensure there is rule in filter table and FORWARD chain to permit in/out traffic from pods // ensure there is rule in filter table and FORWARD chain to permit in/out traffic from pods
// this rules will be appended so that any iptable rules for network policies will take // this rules will be appended so that any iptable rules for network policies will take
// precedence // precedence
func (nrc *NetworkRoutingController) enableForwarding() error { func (nrc *NetworkRoutingController) enableForwarding() error {
iptablesCmdHandler, err := iptables.New() iptablesCmdHandler, _ := nrc.newIptablesCmdHandler()
comment := "allow outbound traffic from pods" comment := "allow outbound traffic from pods"
args := []string{"-m", "comment", "--comment", comment, "-i", "kube-bridge", "-j", "ACCEPT"} args := []string{"-m", "comment", "--comment", comment, "-i", "kube-bridge", "-j", "ACCEPT"}
@ -661,7 +670,7 @@ func (nrc *NetworkRoutingController) startBgpServer() error {
} }
if ipv6IsEnabled() { if ipv6IsEnabled() {
localAddressList = append(localAddressList, "::") localAddressList = append(localAddressList, "::1")
} }
global := &config.Global{ global := &config.Global{
@ -795,6 +804,21 @@ func NewNetworkRoutingController(clientset kubernetes.Interface,
nrc.disableSrcDstCheck = kubeRouterConfig.DisableSrcDstCheck nrc.disableSrcDstCheck = kubeRouterConfig.DisableSrcDstCheck
nrc.initSrcDstCheckDone = false nrc.initSrcDstCheckDone = false
nrc.hostnameOverride = kubeRouterConfig.HostnameOverride
node, err := utils.GetNodeObject(clientset, nrc.hostnameOverride)
if err != nil {
return nil, errors.New("Failed getting node object from API server: " + err.Error())
}
nrc.nodeName = node.Name
nodeIP, err := utils.GetNodeIP(node)
if err != nil {
return nil, errors.New("Failed getting IP address from node object: " + err.Error())
}
nrc.nodeIP = nodeIP
nrc.isIpv6 = nodeIP.To4() == nil
// lets start with assumption we hace necessary IAM creds to access EC2 api // lets start with assumption we hace necessary IAM creds to access EC2 api
nrc.ec2IamAuthorized = true nrc.ec2IamAuthorized = true
@ -808,7 +832,7 @@ func NewNetworkRoutingController(clientset kubernetes.Interface,
} }
} }
nrc.ipSetHandler, err = utils.NewIPSet(false) nrc.ipSetHandler, err = utils.NewIPSet(nrc.isIpv6)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -872,20 +896,6 @@ func NewNetworkRoutingController(clientset kubernetes.Interface,
return nil, fmt.Errorf("Error processing Global Peer Router configs: %s", err) return nil, fmt.Errorf("Error processing Global Peer Router configs: %s", err)
} }
nrc.hostnameOverride = kubeRouterConfig.HostnameOverride
node, err := utils.GetNodeObject(clientset, nrc.hostnameOverride)
if err != nil {
return nil, errors.New("Failed getting node object from API server: " + err.Error())
}
nrc.nodeName = node.Name
nodeIP, err := utils.GetNodeIP(node)
if err != nil {
return nil, errors.New("Failed getting IP address from node object: " + err.Error())
}
nrc.nodeIP = nodeIP
nrc.nodeSubnet, nrc.nodeInterface, err = getNodeSubnet(nodeIP) nrc.nodeSubnet, nrc.nodeInterface, err = getNodeSubnet(nodeIP)
if err != nil { if err != nil {
return nil, errors.New("Failed find the subnet of the node IP and interface on" + return nil, errors.New("Failed find the subnet of the node IP and interface on" +

View File

@ -4,28 +4,38 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/coreos/go-iptables/iptables"
"github.com/golang/glog" "github.com/golang/glog"
) )
// set up MASQUERADE rule so that egress traffic from the pods gets masquraded to node's IP // set up MASQUERADE rule so that egress traffic from the pods gets masquraded to node's IP
var ( var (
podEgressArgs = []string{"-m", "set", "--match-set", podSubnetsIPSetName, "src", podEgressArgs4 = []string{"-m", "set", "--match-set", podSubnetsIPSetName, "src",
"-m", "set", "!", "--match-set", podSubnetsIPSetName, "dst", "-m", "set", "!", "--match-set", podSubnetsIPSetName, "dst",
"-m", "set", "!", "--match-set", nodeAddrsIPSetName, "dst", "-m", "set", "!", "--match-set", nodeAddrsIPSetName, "dst",
"-j", "MASQUERADE"} "-j", "MASQUERADE"}
podEgressArgsBad = [][]string{{"-m", "set", "--match-set", podSubnetsIPSetName, "src", podEgressArgs6 = []string{"-m", "set", "--match-set", "inet6:" + podSubnetsIPSetName, "src",
"-m", "set", "!", "--match-set", "inet6:" + podSubnetsIPSetName, "dst",
"-m", "set", "!", "--match-set", "inet6:" + nodeAddrsIPSetName, "dst",
"-j", "MASQUERADE"}
podEgressArgsBad4 = [][]string{{"-m", "set", "--match-set", podSubnetsIPSetName, "src",
"-m", "set", "!", "--match-set", podSubnetsIPSetName, "dst", "-m", "set", "!", "--match-set", podSubnetsIPSetName, "dst",
"-j", "MASQUERADE"}} "-j", "MASQUERADE"}}
podEgressArgsBad6 = [][]string{{"-m", "set", "--match-set", "inet6:" + podSubnetsIPSetName, "src",
"-m", "set", "!", "--match-set", "inet6:" + podSubnetsIPSetName, "dst",
"-j", "MASQUERADE"}}
) )
func createPodEgressRule() error { func (nrc *NetworkRoutingController) createPodEgressRule() error {
iptablesCmdHandler, err := iptables.New() iptablesCmdHandler, err := nrc.newIptablesCmdHandler()
if err != nil { if err != nil {
return errors.New("Failed create iptables handler:" + err.Error()) return errors.New("Failed create iptables handler:" + err.Error())
} }
podEgressArgs := podEgressArgs4
if nrc.isIpv6 {
podEgressArgs = podEgressArgs6
}
err = iptablesCmdHandler.AppendUnique("nat", "POSTROUTING", podEgressArgs...) err = iptablesCmdHandler.AppendUnique("nat", "POSTROUTING", podEgressArgs...)
if err != nil { if err != nil {
return errors.New("Failed to add iptable rule to masqurade outbound traffic from pods: " + return errors.New("Failed to add iptable rule to masqurade outbound traffic from pods: " +
@ -37,12 +47,16 @@ func createPodEgressRule() error {
return nil return nil
} }
func deletePodEgressRule() error { func (nrc *NetworkRoutingController) deletePodEgressRule() error {
iptablesCmdHandler, err := iptables.New() iptablesCmdHandler, err := nrc.newIptablesCmdHandler()
if err != nil { if err != nil {
return errors.New("Failed create iptables handler:" + err.Error()) return errors.New("Failed create iptables handler:" + err.Error())
} }
podEgressArgs := podEgressArgs4
if nrc.isIpv6 {
podEgressArgs = podEgressArgs6
}
exists, err := iptablesCmdHandler.Exists("nat", "POSTROUTING", podEgressArgs...) exists, err := iptablesCmdHandler.Exists("nat", "POSTROUTING", podEgressArgs...)
if err != nil { if err != nil {
return errors.New("Failed to lookup iptable rule to masqurade outbound traffic from pods: " + err.Error()) return errors.New("Failed to lookup iptable rule to masqurade outbound traffic from pods: " + err.Error())
@ -60,12 +74,15 @@ func deletePodEgressRule() error {
return nil return nil
} }
func deleteBadPodEgressRules() error { func (nrc *NetworkRoutingController) deleteBadPodEgressRules() error {
iptablesCmdHandler, err := iptables.New() iptablesCmdHandler, err := nrc.newIptablesCmdHandler()
if err != nil { if err != nil {
return errors.New("Failed create iptables handler:" + err.Error()) return errors.New("Failed create iptables handler:" + err.Error())
} }
podEgressArgsBad := podEgressArgsBad4
if nrc.isIpv6 {
podEgressArgsBad = podEgressArgsBad6
}
for _, args := range podEgressArgsBad { for _, args := range podEgressArgsBad {
exists, err := iptablesCmdHandler.Exists("nat", "POSTROUTING", args...) exists, err := iptablesCmdHandler.Exists("nat", "POSTROUTING", args...)
if err != nil { if err != nil {

View File

@ -98,7 +98,7 @@ func getNodeSubnet(nodeIp net.IP) (net.IPNet, string, error) {
return net.IPNet{}, "", errors.New("Failed to get list of links") return net.IPNet{}, "", errors.New("Failed to get list of links")
} }
for _, link := range links { for _, link := range links {
addresses, err := netlink.AddrList(link, netlink.FAMILY_V4) addresses, err := netlink.AddrList(link, netlink.FAMILY_ALL)
if err != nil { if err != nil {
return net.IPNet{}, "", errors.New("Failed to get list of addr") return net.IPNet{}, "", errors.New("Failed to get list of addr")
} }

View File

@ -440,7 +440,8 @@ func (set *Set) Swap(setTo *Set) error {
// Refresh a Set with new entries. // Refresh a Set with new entries.
func (set *Set) Refresh(entries []string, extraOptions ...string) error { func (set *Set) Refresh(entries []string, extraOptions ...string) error {
var err error var err error
tempName := set.Name + "-temp" // The set-name must be < 32 characters!
tempName := set.Name + "-"
newSet := &Set{ newSet := &Set{
Parent: set.Parent, Parent: set.Parent,