Skip to content

Commit 5a4b586

Browse files
authored
Merge pull request #241 from skyerus/issue-222_flagd-resource-limits
feat: introduce configurable resource limits for flagd sidecar
2 parents 4820493 + 5d924a7 commit 5a4b586

File tree

5 files changed

+67
-10
lines changed

5 files changed

+67
-10
lines changed

chart/templates/rendered.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,8 @@ spec:
812812
- --health-probe-bind-address=:8081
813813
- --metrics-bind-address=127.0.0.1:8080
814814
- --leader-elect
815+
- --flagd-cpu-limit=0.5
816+
- --flagd-ram-limit=64M
815817
command:
816818
- /manager
817819
env:

config/default/manager_auth_proxy_patch.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ spec:
3232
- "--health-probe-bind-address=:8081"
3333
- "--metrics-bind-address=127.0.0.1:8080"
3434
- "--leader-elect"
35+
- "--flagd-cpu-limit=0.5" # cores
36+
- "--flagd-ram-limit=64M"

config/manager/manager.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ spec:
3131
- /manager
3232
args:
3333
- --leader-elect
34+
- --flagd-cpu-limit=0.5
35+
- --flagd-ram-limit=64M
3436
imagePullPolicy: IfNotPresent
3537
image: controller:main
3638
name: manager

main.go

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package main
1818

1919
import (
2020
"flag"
21+
corev1 "k8s.io/api/core/v1"
22+
"k8s.io/apimachinery/pkg/api/resource"
2123
"os"
2224

2325
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
@@ -40,12 +42,13 @@ import (
4042
)
4143

4244
var (
43-
scheme = runtime.NewScheme()
44-
setupLog = ctrl.Log.WithName("setup")
45-
metricsAddr string
46-
enableLeaderElection bool
47-
probeAddr string
48-
verbose bool
45+
scheme = runtime.NewScheme()
46+
setupLog = ctrl.Log.WithName("setup")
47+
metricsAddr string
48+
enableLeaderElection bool
49+
probeAddr string
50+
verbose bool
51+
flagDCpuLimit, flagDRamLimit, flagDCpuRequest, flagDRamRequest string
4952
)
5053

5154
func init() {
@@ -60,11 +63,17 @@ func main() {
6063

6164
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
6265
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
63-
flag.BoolVar(&verbose, "verbose", true, "Disable verbose logging (default: true)")
66+
flag.BoolVar(&verbose, "verbose", true, "Disable verbose logging")
6467
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
6568
"Enable leader election for controller manager. "+
6669
"Enabling this will ensure there is only one active controller manager.")
6770

71+
// the following default values are chosen as a result of load testing: https://github.com/open-feature/flagd/blob/main/tests/loadtest/README.MD#performance-observations
72+
flag.StringVar(&flagDCpuLimit, "flagd-cpu-limit", "0.5", "flagd CPU limit, in cores. (500m = .5 cores)")
73+
flag.StringVar(&flagDRamLimit, "flagd-ram-limit", "64M", "flagd memory limit, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)")
74+
flag.StringVar(&flagDCpuRequest, "flagd-cpu-request", "0.2", "flagd CPU minimum, in cores. (500m = .5 cores)")
75+
flag.StringVar(&flagDRamRequest, "flagd-ram-request", "32M", "flagd memory minimum, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)")
76+
6877
level := zapcore.InfoLevel
6978
if verbose {
7079
level = zapcore.DebugLevel
@@ -78,6 +87,36 @@ func main() {
7887

7988
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
8089

90+
flagDCpuLimitResource, err := resource.ParseQuantity(flagDCpuLimit)
91+
if err != nil {
92+
setupLog.Error(err, "parse flagd cpu limit", "flagd-cpu-limit", flagDCpuLimit)
93+
os.Exit(1)
94+
}
95+
96+
flagDRamLimitResource, err := resource.ParseQuantity(flagDRamLimit)
97+
if err != nil {
98+
setupLog.Error(err, "parse flagd ram limit", "flagd-ram-limit", flagDRamLimit)
99+
os.Exit(1)
100+
}
101+
102+
flagDCpuRequestResource, err := resource.ParseQuantity(flagDCpuRequest)
103+
if err != nil {
104+
setupLog.Error(err, "parse flagd cpu request", "flagd-cpu-request", flagDCpuRequest)
105+
os.Exit(1)
106+
}
107+
108+
flagDRamRequestResource, err := resource.ParseQuantity(flagDRamRequest)
109+
if err != nil {
110+
setupLog.Error(err, "parse flagd ram request", "flagd-ram-request", flagDRamRequest)
111+
os.Exit(1)
112+
}
113+
114+
if flagDCpuRequestResource.Value() > flagDCpuLimitResource.Value() ||
115+
flagDRamRequestResource.Value() > flagDRamLimitResource.Value() {
116+
setupLog.Error(err, "flagd resource request is higher than the resource maximum")
117+
os.Exit(1)
118+
}
119+
81120
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
82121
Scheme: scheme,
83122
MetricsBindAddress: metricsAddr,
@@ -111,6 +150,16 @@ func main() {
111150
//+kubebuilder:scaffold:builder
112151
hookServer := mgr.GetWebhookServer()
113152
hookServer.Register("/mutate-v1-pod", &webhook.Admission{Handler: &webhooks.PodMutator{
153+
FlagDResourceRequirements: corev1.ResourceRequirements{
154+
Limits: map[corev1.ResourceName]resource.Quantity{
155+
corev1.ResourceCPU: flagDCpuLimitResource,
156+
corev1.ResourceMemory: flagDRamLimitResource,
157+
},
158+
Requests: map[corev1.ResourceName]resource.Quantity{
159+
corev1.ResourceCPU: flagDCpuRequestResource,
160+
corev1.ResourceMemory: flagDRamRequestResource,
161+
},
162+
},
114163
Client: mgr.GetClient(),
115164
Log: ctrl.Log.WithName("mutating-pod-webhook"),
116165
}})

webhooks/pod_webhook.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ var flagdMetricsPort int32 = 8014
4141

4242
// PodMutator annotates Pods
4343
type PodMutator struct {
44-
Client client.Client
45-
decoder *admission.Decoder
46-
Log logr.Logger
44+
Client client.Client
45+
FlagDResourceRequirements corev1.ResourceRequirements
46+
decoder *admission.Decoder
47+
Log logr.Logger
4748
}
4849

4950
// Handle injects the flagd sidecar (if the prerequisites are all met)
@@ -352,6 +353,7 @@ func (m *PodMutator) injectSidecar(pod *corev1.Pod, featureFlags []*corev1alpha1
352353
},
353354
},
354355
SecurityContext: setSecurityContext(),
356+
Resources: m.FlagDResourceRequirements,
355357
})
356358
return json.Marshal(pod)
357359
}

0 commit comments

Comments
 (0)