Skip to content

Commit f673ea3

Browse files
authored
Merge pull request #412 from mars1024/ipam_selector
implement pod selector and use it in predication of pod reconciliations
2 parents 33b4865 + 30cd2f7 commit f673ea3

File tree

5 files changed

+406
-0
lines changed

5 files changed

+406
-0
lines changed

cmd/manager/main.go

+19
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"os"
2323

24+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2425
kubevirtv1 "kubevirt.io/api/core/v1"
2526

2627
"github.com/spf13/pflag"
@@ -34,6 +35,7 @@ import (
3435
networkingv1 "github.com/alibaba/hybridnet/pkg/apis/networking/v1"
3536
"github.com/alibaba/hybridnet/pkg/controllers/multicluster"
3637
"github.com/alibaba/hybridnet/pkg/controllers/networking"
38+
"github.com/alibaba/hybridnet/pkg/controllers/utils"
3739
"github.com/alibaba/hybridnet/pkg/feature"
3840
zapinit "github.com/alibaba/hybridnet/pkg/zap"
3941
)
@@ -56,13 +58,15 @@ func main() {
5658
clientQPS float32
5759
clientBurst int
5860
metricsPort int
61+
selectorStr string
5962
)
6063

6164
// register flags
6265
pflag.StringToIntVar(&controllerConcurrency, "controller-concurrency", map[string]int{}, "The specified concurrency of different controllers.")
6366
pflag.Float32Var(&clientQPS, "kube-client-qps", 300, "The QPS limit of apiserver client.")
6467
pflag.IntVar(&clientBurst, "kube-client-burst", 600, "The Burst limit of apiserver client.")
6568
pflag.IntVar(&metricsPort, "metrics-port", 9899, "The port to listen on for prometheus metrics.")
69+
pflag.StringVar(&selectorStr, "pod-label-selector", "", "The label selector to select specified pods for IPAM.")
6670

6771
// parse flags
6872
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
@@ -82,6 +86,20 @@ func main() {
8286
clientConfig.QPS = clientQPS
8387
clientConfig.Burst = clientBurst
8488

89+
// initialize objects from flags
90+
// if selector string is empty, it means select everything
91+
labelSelector, err := metav1.ParseToLabelSelector(selectorStr)
92+
if err != nil {
93+
entryLog.Error(err, "unable to parse label selector")
94+
os.Exit(1)
95+
}
96+
97+
var podSelector utils.PodSelector
98+
if podSelector, err = utils.LabelSelectorAsPodSelector(labelSelector); err != nil {
99+
entryLog.Error(err, "unable to create pod selector")
100+
os.Exit(1)
101+
}
102+
85103
mgr, err := ctrl.NewManager(clientConfig, ctrl.Options{
86104
Scheme: scheme,
87105
Logger: ctrl.Log.WithName("manager"),
@@ -120,6 +138,7 @@ func main() {
120138

121139
if err = networking.RegisterToManager(globalContext, mgr, networking.RegisterOptions{
122140
ConcurrencyMap: controllerConcurrency,
141+
PodSelector: podSelector,
123142
}); err != nil {
124143
entryLog.Error(err, "unable to register networking controllers")
125144
os.Exit(1)

pkg/controllers/networking/manager.go

+3
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ import (
2525
"sigs.k8s.io/controller-runtime/pkg/manager"
2626

2727
"github.com/alibaba/hybridnet/pkg/controllers/concurrency"
28+
"github.com/alibaba/hybridnet/pkg/controllers/utils"
2829
)
2930

3031
type RegisterOptions struct {
3132
NewIPAMManager NewIPAMManagerFunction
3233
ConcurrencyMap map[string]int
34+
PodSelector utils.PodSelector
3335
}
3436

3537
func RegisterToManager(ctx context.Context, mgr manager.Manager, options RegisterOptions) error {
@@ -93,6 +95,7 @@ func RegisterToManager(ctx context.Context, mgr manager.Manager, options Registe
9395
IPAMStore: ipamStore,
9496
IPAMManager: ipamManager,
9597
ControllerConcurrency: concurrency.ControllerConcurrency(options.ConcurrencyMap[ControllerPod]),
98+
PodSelector: options.PodSelector,
9699
}).SetupWithManager(mgr); err != nil {
97100
return fmt.Errorf("unable to inject controller %s: %v", ControllerPod, err)
98101
}

pkg/controllers/networking/pod_controller.go

+14
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ type PodReconciler struct {
8080
IPAMManager IPAMManager
8181

8282
concurrency.ControllerConcurrency
83+
PodSelector utils.PodSelector
8384
}
8485

8586
//+kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch;create;update;patch;delete
@@ -773,6 +774,19 @@ func (r *PodReconciler) SetupWithManager(mgr ctrl.Manager) (err error) {
773774
builder.WithPredicates(
774775
&utils.IgnoreDeletePredicate{},
775776
&predicate.ResourceVersionChangedPredicate{},
777+
predicate.NewPredicateFuncs(func(obj client.Object) bool {
778+
if r.PodSelector == nil {
779+
return true
780+
}
781+
782+
pod, ok := obj.(*corev1.Pod)
783+
if !ok {
784+
return false
785+
}
786+
787+
// Only selected pods should be processed
788+
return r.PodSelector.Matches(pod)
789+
}),
776790
predicate.NewPredicateFuncs(func(obj client.Object) bool {
777791
pod, ok := obj.(*corev1.Pod)
778792
if !ok {

pkg/controllers/utils/selector.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright 2024 The Hybridnet Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package utils
18+
19+
import (
20+
corev1 "k8s.io/api/core/v1"
21+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
"k8s.io/apimachinery/pkg/labels"
23+
)
24+
25+
type PodSelector interface {
26+
Matches(pod *corev1.Pod) bool
27+
}
28+
29+
type podSelector struct {
30+
selector labels.Selector
31+
}
32+
33+
func (p *podSelector) Matches(pod *corev1.Pod) bool {
34+
// non-blocking during exception cases
35+
if p == nil || pod == nil {
36+
return true
37+
}
38+
39+
return p.selector.Matches(labels.Set(pod.Labels))
40+
}
41+
42+
func LabelSelectorAsPodSelector(labelSelector *metav1.LabelSelector) (PodSelector, error) {
43+
selector, err := metav1.LabelSelectorAsSelector(labelSelector)
44+
if err != nil {
45+
return nil, err
46+
}
47+
48+
return &podSelector{
49+
selector: selector,
50+
}, nil
51+
}

0 commit comments

Comments
 (0)