@@ -3,7 +3,6 @@ package linode
3
3
import (
4
4
"context"
5
5
"encoding/json"
6
- "errors"
7
6
"fmt"
8
7
"net/http"
9
8
"slices"
@@ -29,6 +28,8 @@ const (
29
28
ciliumLBClass = "io.cilium/bgp-control-plane"
30
29
ipHolderLabelPrefix = "linode-ccm-ip-holder"
31
30
ciliumBGPPeeringPolicyName = "linode-ccm-bgp-peering"
31
+
32
+ commonControlPlaneLabel = "node-role.kubernetes.io/control-plane"
32
33
)
33
34
34
35
// This mapping is unfortunately necessary since there is no way to get the
63
64
"ap-southeast" : 16 , // Sydney (Australia)
64
65
"ap-northeast" : 11 , // Tokyo (Japan)
65
66
}
66
- errNoBGPSelector = errors .New ("no BGP node selector set to configure IP sharing" )
67
67
)
68
68
69
69
// getExistingSharedIPsInCluster determines the list of addresses to share on nodes by checking the
@@ -123,6 +123,9 @@ func (l *loadbalancers) shareIPs(ctx context.Context, addrs []string, node *v1.N
123
123
if err != nil {
124
124
return err
125
125
}
126
+ if node .Labels == nil {
127
+ node .Labels = make (map [string ]string )
128
+ }
126
129
node .Labels [annotations .AnnLinodeNodeIPSharingUpdated ] = "true"
127
130
retryErr := retry .RetryOnConflict (retry .DefaultRetry , func () error {
128
131
_ , err := l .kubeClient .CoreV1 ().Nodes ().Update (ctx , node , metav1.UpdateOptions {})
@@ -148,15 +151,17 @@ func (l *loadbalancers) handleIPSharing(ctx context.Context, node *v1.Node) erro
148
151
klog .Info ("skipping IP while providerID is unset" )
149
152
return nil
150
153
}
151
- if Options .BGPNodeSelector == "" {
152
- return errNoBGPSelector
153
- }
154
154
// If performing Service load-balancing via IP sharing + BGP, check for a special annotation
155
155
// added by the CCM gets set when load-balancer IPs have been successfully shared on the node
156
- kv := strings .Split (Options .BGPNodeSelector , "=" )
157
- // Check if node should be participating in IP sharing via the given selector
158
- if val , ok := node .Labels [kv [0 ]]; ! ok || len (kv ) != 2 || val != kv [1 ] {
159
- // not a selected Node
156
+ if Options .BGPNodeSelector != "" {
157
+ kv := strings .Split (Options .BGPNodeSelector , "=" )
158
+ // Check if node should be participating in IP sharing via the given selector
159
+ if val , ok := node .Labels [kv [0 ]]; ! ok || len (kv ) != 2 || val != kv [1 ] {
160
+ // not a selected Node
161
+ return nil
162
+ }
163
+ } else if _ , ok := node .Labels [commonControlPlaneLabel ]; ok {
164
+ // If there is no node selector specified, default to sharing across worker nodes only
160
165
return nil
161
166
}
162
167
// check if node has been updated with IPs to share
@@ -200,10 +205,6 @@ func (l *loadbalancers) handleIPSharing(ctx context.Context, node *v1.Node) erro
200
205
// createSharedIP requests an additional IP that can be shared on Nodes to support
201
206
// loadbalancing via Cilium LB IPAM + BGP Control Plane.
202
207
func (l * loadbalancers ) createSharedIP (ctx context.Context , nodes []* v1.Node ) (string , error ) {
203
- if Options .BGPNodeSelector == "" {
204
- return "" , errNoBGPSelector
205
- }
206
-
207
208
ipHolder , err := l .ensureIPHolder (ctx )
208
209
if err != nil {
209
210
return "" , err
@@ -237,11 +238,21 @@ func (l *loadbalancers) createSharedIP(ctx context.Context, nodes []*v1.Node) (s
237
238
}
238
239
239
240
// share the IPs with nodes participating in Cilium BGP peering
240
- kv := strings .Split (Options .BGPNodeSelector , "=" )
241
- for _ , node := range nodes {
242
- if val , ok := node .Labels [kv [0 ]]; ok && len (kv ) == 2 && val == kv [1 ] {
243
- if err = l .shareIPs (ctx , addrs , node ); err != nil {
244
- return "" , err
241
+ if Options .BGPNodeSelector == "" {
242
+ for _ , node := range nodes {
243
+ if _ , ok := node .Labels [commonControlPlaneLabel ]; ! ok {
244
+ if err = l .shareIPs (ctx , addrs , node ); err != nil {
245
+ return "" , err
246
+ }
247
+ }
248
+ }
249
+ } else {
250
+ kv := strings .Split (Options .BGPNodeSelector , "=" )
251
+ for _ , node := range nodes {
252
+ if val , ok := node .Labels [kv [0 ]]; ok && len (kv ) == 2 && val == kv [1 ] {
253
+ if err = l .shareIPs (ctx , addrs , node ); err != nil {
254
+ return "" , err
255
+ }
245
256
}
246
257
}
247
258
}
@@ -252,9 +263,6 @@ func (l *loadbalancers) createSharedIP(ctx context.Context, nodes []*v1.Node) (s
252
263
// deleteSharedIP cleans up the shared IP for a LoadBalancer Service if it was assigned
253
264
// by Cilium LB IPAM, removing it from the ip-holder
254
265
func (l * loadbalancers ) deleteSharedIP (ctx context.Context , service * v1.Service ) error {
255
- if Options .BGPNodeSelector == "" {
256
- return errNoBGPSelector
257
- }
258
266
err := l .retrieveKubeClient ()
259
267
if err != nil {
260
268
return err
@@ -421,9 +429,6 @@ func (l *loadbalancers) getCiliumLBIPPool(ctx context.Context, service *v1.Servi
421
429
422
430
// NOTE: Cilium CRDs must be installed for this to work
423
431
func (l * loadbalancers ) ensureCiliumBGPPeeringPolicy (ctx context.Context ) error {
424
- if Options .BGPNodeSelector == "" {
425
- return errNoBGPSelector
426
- }
427
432
regionID , ok := regionIDMap [l .zone ]
428
433
if ! ok {
429
434
return fmt .Errorf ("unsupported region for BGP: %s" , l .zone )
@@ -443,16 +448,32 @@ func (l *loadbalancers) ensureCiliumBGPPeeringPolicy(ctx context.Context) error
443
448
}
444
449
445
450
// otherwise create it
446
- kv := strings .Split (Options .BGPNodeSelector , "=" )
447
- if len (kv ) != 2 {
448
- return fmt .Errorf ("invalid node selector %s" , Options .BGPNodeSelector )
451
+ var nodeSelector slimv1.LabelSelector
452
+ // If no BGPNodeSelector is specified, select all worker nodes.
453
+ if Options .BGPNodeSelector == "" {
454
+ nodeSelector = slimv1.LabelSelector {
455
+ MatchExpressions : []slimv1.LabelSelectorRequirement {
456
+ {
457
+ Key : commonControlPlaneLabel ,
458
+ Operator : slimv1 .LabelSelectorOpDoesNotExist ,
459
+ },
460
+ },
461
+ }
462
+ } else {
463
+ kv := strings .Split (Options .BGPNodeSelector , "=" )
464
+ if len (kv ) != 2 {
465
+ return fmt .Errorf ("invalid node selector %s" , Options .BGPNodeSelector )
466
+ }
467
+
468
+ nodeSelector = slimv1.LabelSelector {MatchLabels : map [string ]string {kv [0 ]: kv [1 ]}}
449
469
}
470
+
450
471
ciliumBGPPeeringPolicy := & v2alpha1.CiliumBGPPeeringPolicy {
451
472
ObjectMeta : metav1.ObjectMeta {
452
473
Name : ciliumBGPPeeringPolicyName ,
453
474
},
454
475
Spec : v2alpha1.CiliumBGPPeeringPolicySpec {
455
- NodeSelector : & slimv1. LabelSelector { MatchLabels : map [ string ] string { kv [ 0 ]: kv [ 1 ]}} ,
476
+ NodeSelector : & nodeSelector ,
456
477
VirtualRouters : []v2alpha1.CiliumBGPVirtualRouter {{
457
478
LocalASN : 65001 ,
458
479
ExportPodCIDR : ptr .To (true ),
0 commit comments