Skip to content

Commit 82410c1

Browse files
esandrewsykim
authored andcommitted
Add support for BGP path prepending through node annotations (#476)
1 parent 57f4eea commit 82410c1

File tree

4 files changed

+338
-6
lines changed

4 files changed

+338
-6
lines changed

docs/bgp.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ get peered.
3737

3838
### Route-Reflector setup Without Full Mesh
3939

40-
This model support the common scheme of using Route Reflector Server node to concentrate
40+
This model support the common scheme of using Route Reflector Server node to concentrate
4141
peering from Client Peer. This has the big advantage of not needing full mesh, and
42-
scale better. In this mode kube-router expects each node is configured either in
43-
Route Reflector server mode or in Route Reflector client mode. This is done
42+
scale better. In this mode kube-router expects each node is configured either in
43+
Route Reflector server mode or in Route Reflector client mode. This is done
4444
with node `kube-router.io/rr.server=ClusterID`, `kube-router.io/rr.client=ClusterId`
4545
respectively. In this mode each Route Reflector Client will only peer with Route
4646
Reflector Servers. Each Route Route Reflector Server will peer other Route Reflector
@@ -52,7 +52,7 @@ Users can annotate node objects with the following command:
5252
kubectl annotate node <kube-node> "kube-router.io/rr.server=42"
5353
```
5454

55-
for Route Reflector server mode, and
55+
for Route Reflector server mode, and
5656

5757
```
5858
kubectl annotate node <kube-node> "kube-router.io/rr.client=42"
@@ -92,6 +92,20 @@ kubectl annotate node <kube-node> "kube-router.io/peer.ips=192.168.1.99,192.168.
9292
kubectl annotate node <kube-node> "kube-router.io/peer.asns=65000,65000"
9393
```
9494

95+
### AS Path Prepending
96+
97+
For traffic shaping purposes, you may want to prepend the AS path announced to peers.
98+
This can be accomplished on a per-node basis with annotations:
99+
- `kube-router.io/path-prepend.as`
100+
- `kube-router.io/path-prepend.repeat-n`
101+
102+
If you wanted to prepend all routes from a particular node with the AS 65000 five times,
103+
you would run the following commands:
104+
```
105+
kubectl annotate node <kube-node> "kube-router.io/path-prepend.as=65000"
106+
kubectl annotate node <kube-node> "kube-router.io/path-prepend.repeat-n=5"
107+
```
108+
95109
### BGP Peer Password Authentication
96110

97111
The examples above have assumed there is no password authentication with BGP

pkg/controllers/routing/export_policies.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
6666

6767
statements := make([]config.Statement, 0)
6868

69+
var bgpActions config.BgpActions
70+
if nrc.pathPrepend {
71+
bgpActions = config.BgpActions{
72+
SetAsPathPrepend: config.SetAsPathPrepend{
73+
As: nrc.pathPrependAS,
74+
RepeatN: nrc.pathPrependCount,
75+
},
76+
}
77+
}
78+
6979
if nrc.bgpEnableInternal {
7080
// Get the current list of the nodes from the local cache
7181
nodes := nrc.nodeLister.List()
@@ -136,6 +146,7 @@ func (nrc *NetworkRoutingController) addExportPolicies() error {
136146
},
137147
Actions: config.Actions{
138148
RouteDisposition: config.ROUTE_DISPOSITION_ACCEPT_ROUTE,
149+
BgpActions: bgpActions,
139150
},
140151
})
141152
if nrc.advertisePodCidr {

pkg/controllers/routing/network_routes_controller.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ const (
4141
nodeAddrsIPSetName = "kube-router-node-ips"
4242

4343
nodeASNAnnotation = "kube-router.io/node.asn"
44+
pathPrependASNAnnotation = "kube-router.io/path-prepend.as"
45+
pathPrependRepeatNAnnotation = "kube-router.io/path-prepend.repeat-n"
4446
peerASNAnnotation = "kube-router.io/peer.asns"
4547
peerIPAnnotation = "kube-router.io/peer.ips"
4648
peerPasswordAnnotation = "kube-router.io/peer.passwords"
@@ -87,6 +89,9 @@ type NetworkRoutingController struct {
8789
cniConfFile string
8890
initSrcDstCheckDone bool
8991
ec2IamAuthorized bool
92+
pathPrependAS string
93+
pathPrependCount uint8
94+
pathPrepend bool
9095

9196
nodeLister cache.Indexer
9297
svcLister cache.Indexer
@@ -610,6 +615,28 @@ func (nrc *NetworkRoutingController) startBgpServer() error {
610615
nrc.bgpRRClient = true
611616
}
612617

618+
if prependASN, okASN := node.ObjectMeta.Annotations[pathPrependASNAnnotation]; okASN {
619+
prependRepeatN, okRepeatN := node.ObjectMeta.Annotations[pathPrependRepeatNAnnotation]
620+
621+
if !okRepeatN {
622+
return fmt.Errorf("Both %s and %s must be set", pathPrependASNAnnotation, pathPrependRepeatNAnnotation)
623+
}
624+
625+
_, err := strconv.ParseUint(prependASN, 0, 32)
626+
if err != nil {
627+
return errors.New("Failed to parse ASN number specified to prepend")
628+
}
629+
630+
repeatN, err := strconv.ParseUint(prependRepeatN, 0, 8)
631+
if err != nil {
632+
return errors.New("Failed to parse number of times ASN should be repeated")
633+
}
634+
635+
nrc.pathPrepend = true
636+
nrc.pathPrependAS = prependASN
637+
nrc.pathPrependCount = uint8(repeatN)
638+
}
639+
613640
nrc.bgpServer = gobgp.NewBgpServer()
614641
go nrc.bgpServer.Serve()
615642

@@ -787,7 +814,6 @@ func NewNetworkRoutingController(clientset kubernetes.Interface,
787814
nrc.advertiseExternalIP = kubeRouterConfig.AdvertiseExternalIp
788815
nrc.advertiseLoadBalancerIP = kubeRouterConfig.AdvertiseLoadBalancerIp
789816
nrc.advertisePodCidr = kubeRouterConfig.AdvertiseNodePodCidr
790-
791817
nrc.enableOverlays = kubeRouterConfig.EnableOverlay
792818

793819
// Convert ints to uint32s

0 commit comments

Comments
 (0)