Skip to content

Commit

Permalink
Allow multiple peer routers specified through global BGP peer router …
Browse files Browse the repository at this point in the history
…flag '--peer-router'.

Node annotation to specifiy BGP peer routers also supports one or more BGP peers.

Fixes #37
  • Loading branch information
Murali Reddy committed Jul 3, 2017
1 parent f1823e9 commit a757ea3
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 36 deletions.
7 changes: 4 additions & 3 deletions Documentation/bgp.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,17 @@ Only nodes with in same ASN form full mesh. Two nodes with different configured

An optional global BGP peer can be configured by specifying `--peer-asn` and `--peer-router` parameters. When configured
each node in the cluster forms a peer relationship with specified global peer. Pod cidr, cluster IP's get advertised to
the global BGP peer.
the global BGP peer. For redundancy you can also configure more than one peer router by specifying comma seperated list
of BGP peers for `--peer-router` flag, like `--peer-router=192.168.1.99,192.168.1.100`

### Node specific BGP peer

Alternativley, each node can be configured with node specific BGP peer. Information regarding node specific BGP peer is
Alternativley, each node can be configured with one or mode node specific BGP peer. Information regarding node specific BGP peer is
read from node API object annotations `net.kuberouter.node.bgppeer.address` and `net.kuberouter.node.bgppeer.asn`.


For e.g users can annotate node object with below commands
```
kubectl annotate node <kube-node> “net.kuberouter.node.bgppeer.address=192.168.1.98”
kubectl annotate node <kube-node> “net.kuberouter.node.bgppeer.address=192.168.1.98,192.168.1.99
kubectl annotate node <kube-node> "net.kuberouter.node.bgppeer.asn=64513”"
```
94 changes: 61 additions & 33 deletions app/controllers/network_routes_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type NetworkRoutingController struct {
advertiseClusterIp bool
defaultNodeAsnNumber uint32
nodeAsnNumber uint32
globalPeerRouter string
globalPeerRouters []string
globalPeerAsnNumber uint32
bgpFullMeshMode bool
}
Expand Down Expand Up @@ -258,9 +258,9 @@ func (nrc *NetworkRoutingController) syncPeers() {
glog.Infof("Not peering with the Node %s as ASN number of the node is invalid.", nodeIP.String())
continue
}

// if the nodes ASN number is different from ASN number of current node skipp peering
if nrc.nodeAsnNumber != uint32(asnNo) {
if nrc.nodeAsnNumber != uint32(asnNo) {
glog.Infof("Not peering with the Node %s as ASN number of the node is different.", nodeIP.String())
continue
}
Expand Down Expand Up @@ -396,47 +396,64 @@ func (nrc *NetworkRoutingController) startBgpServer() bool {

// if the global routing peer is configured then peer with it
// else peer with node specific BGP peer
if len(nrc.globalPeerRouter) != 0 && nrc.globalPeerAsnNumber != 0 {
n := &config.Neighbor{
Config: config.NeighborConfig{
NeighborAddress: nrc.globalPeerRouter,
PeerAs: nrc.globalPeerAsnNumber,
},
}
if err := nrc.bgpServer.AddNeighbor(n); err != nil {
panic("Failed to peer with global peer router due to: " + nrc.globalPeerRouter)
if len(nrc.globalPeerRouters) != 0 && nrc.globalPeerAsnNumber != 0 {
for _, peer := range nrc.globalPeerRouters {
n := &config.Neighbor{
Config: config.NeighborConfig{
NeighborAddress: peer,
PeerAs: nrc.globalPeerAsnNumber,
},
}
if err := nrc.bgpServer.AddNeighbor(n); err != nil {
panic("Failed to peer with global peer router due to: " + peer)
}
}
} else {
nodeBgpPeer, ok := node.ObjectMeta.Annotations["net.kuberouter.node.bgppeer.address"]
if !ok {
glog.Infof("Could not find BGP peer info for the node in the node annotations so skipping configuring peer.")
return true
}

nodeBgpPeerAsn, ok := node.ObjectMeta.Annotations["net.kuberouter.node.bgppeer.asn"]
if !ok {
glog.Infof("Could not find BGP peer info for the node in the node annotations so skipping configuring peer.")
return true
}

asnNo, err := strconv.ParseUint(nodeBgpPeerAsn, 0, 32)
if err != nil {
panic("Failed to parse ASN number specified for the the node in the annotations")
}

peerAsnNo := uint32(asnNo)
glog.Infof("Node is configured to peer with %s in ASN %v from the node annotations", nodeBgpPeer, peerAsnNo)
n := &config.Neighbor{
Config: config.NeighborConfig{
NeighborAddress: nodeBgpPeer,
PeerAs: peerAsnNo,
},

nodeBgpPeersAnnotation, ok := node.ObjectMeta.Annotations["net.kuberouter.node.bgppeer.address"]
if !ok {
glog.Infof("Could not find BGP peer info for the node in the node annotations so skipping configuring peer.")
return true
}
if err := nrc.bgpServer.AddNeighbor(n); err != nil {
panic("Failed to peer with node specific BGP peer router: " + nodeBgpPeer + " due to " + err.Error())
nodePeerRouters := make([]string, 0)
if strings.Contains(nodeBgpPeersAnnotation, ",") {
ips := strings.Split(nodeBgpPeersAnnotation, ",")
for _, ip := range ips {
if net.ParseIP(ip) == nil {
panic("Invalid node BGP peer router ip in the annotation: " + ip)
}
}
nodePeerRouters = append(nodePeerRouters, ips...)
} else {
if net.ParseIP(nodeBgpPeersAnnotation) == nil {
panic("Invalid node BGP peer router ip: " + nodeBgpPeersAnnotation)
}
nodePeerRouters = append(nodePeerRouters, nodeBgpPeersAnnotation)
}
for _, peer := range nodePeerRouters {
glog.Infof("Node is configured to peer with %s in ASN %v from the node annotations", peer, peerAsnNo)
n := &config.Neighbor{
Config: config.NeighborConfig{
NeighborAddress: peer,
PeerAs: peerAsnNo,
},
}
if err := nrc.bgpServer.AddNeighbor(n); err != nil {
panic("Failed to peer with node specific BGP peer router: " + peer + " due to " + err.Error())
}
}

glog.Infof("Successfully configured %s in ASN %v as BGP peer to the node", nodeBgpPeer, peerAsnNo)
glog.Infof("Successfully configured %s in ASN %v as BGP peer to the node", nodeBgpPeersAnnotation, peerAsnNo)
}

return true
Expand Down Expand Up @@ -472,11 +489,22 @@ func NewNetworkRoutingController(clientset *kubernetes.Clientset, kubeRouterConf
}

if len(kubeRouterConfig.PeerRouter) != 0 && len(kubeRouterConfig.PeerAsn) != 0 {
if net.ParseIP(kubeRouterConfig.PeerRouter) == nil {
panic("Invalid global BGP peer router ip: " + nrc.globalPeerRouter)
}

nrc.globalPeerRouter = kubeRouterConfig.PeerRouter
if strings.Contains(kubeRouterConfig.PeerRouter, ",") {
ips := strings.Split(kubeRouterConfig.PeerRouter, ",")
for _, ip := range ips {
if net.ParseIP(ip) == nil {
panic("Invalid global BGP peer router ip: " + kubeRouterConfig.PeerRouter)
}
}
nrc.globalPeerRouters = append(nrc.globalPeerRouters, ips...)

} else {
if net.ParseIP(kubeRouterConfig.PeerRouter) == nil {
panic("Invalid global BGP peer router ip: " + kubeRouterConfig.PeerRouter)
}
nrc.globalPeerRouters = append(nrc.globalPeerRouters, kubeRouterConfig.PeerRouter)
}

asn, err := strconv.ParseUint(kubeRouterConfig.PeerAsn, 0, 32)
if err != nil {
Expand Down

0 comments on commit a757ea3

Please sign in to comment.