From 953cde381c262322a9b5b2c589c7e227f5f310af Mon Sep 17 00:00:00 2001 From: Gerrit Date: Tue, 1 Oct 2024 15:24:36 +0200 Subject: [PATCH 1/4] Implement mutating webhook for calico with ebpf configuration. --- pkg/webhook/shoot/mutator.go | 55 +++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/pkg/webhook/shoot/mutator.go b/pkg/webhook/shoot/mutator.go index 9cac9c02..f845f9a0 100644 --- a/pkg/webhook/shoot/mutator.go +++ b/pkg/webhook/shoot/mutator.go @@ -5,6 +5,11 @@ import ( "fmt" extensionswebhook "github.com/gardener/gardener/extensions/pkg/webhook" + extensionscontextwebhook "github.com/gardener/gardener/extensions/pkg/webhook/context" + gcontext "github.com/gardener/gardener/extensions/pkg/webhook/context" + "github.com/metal-stack/gardener-extension-provider-metal/pkg/apis/metal/helper" + + calicoextensionv1alpha1 "github.com/gardener/gardener-extension-networking-calico/pkg/apis/calico/v1alpha1" "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" @@ -42,12 +47,21 @@ func (m *mutator) Mutate(ctx context.Context, new, _ client.Object) error { return nil } + gctx := extensionscontextwebhook.NewGardenContext(m.client, new) + switch x := new.(type) { case *appsv1.Deployment: switch x.Name { case "vpn-shoot": extensionswebhook.LogMutation(logger, x.Kind, x.Namespace, x.Name) return m.mutateVPNShootDeployment(ctx, x) + + } + case *appsv1.DaemonSet: + switch x.Name { + case "calico-node": + extensionswebhook.LogMutation(logger, x.Kind, x.Namespace, x.Name) + return m.mutateCalicoNode(ctx, gctx, x) } } return nil @@ -59,7 +73,7 @@ func (m *mutator) mutateVPNShootDeployment(_ context.Context, deployment *appsv1 // raising the timeout to 15 minutes leads to additional 15 minutes of provisioning time because // the nodes cidr will only be set on next shoot reconcile // with the following mutation we can immediately provide the proper nodes cidr and save time - logger.Info("ensuring nodes cidr from shoot-node-cidr configmap in vpn-shoot deployment") + m.logger.Info("ensuring nodes cidr from shoot-node-cidr configmap in vpn-shoot deployment") c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ Name: "NODE_NETWORK", Value: "", @@ -76,3 +90,42 @@ func (m *mutator) mutateVPNShootDeployment(_ context.Context, deployment *appsv1 return nil } + +func (m *mutator) mutateCalicoNode(ctx context.Context, gctx gcontext.GardenContext, ds *appsv1.DaemonSet) error { + cluster, err := gctx.GetCluster(ctx) + if err != nil { + return fmt.Errorf("unable to extract cluster from ctx: %w", err) + } + + networkConfig := &calicoextensionv1alpha1.NetworkConfig{} + err = helper.DecodeRawExtension(cluster.Shoot.Spec.Networking.ProviderConfig, networkConfig, m.decoder) + if err != nil { + return err + } + + if networkConfig.EbpfDataplane == nil || !networkConfig.EbpfDataplane.Enabled { + return nil + } + + if c := extensionswebhook.ContainerWithName(ds.Spec.Template.Spec.Containers, "calico-node"); c != nil { + m.logger.Info("patching calico-node daemon set due to ebpf dataplane being enabled") + + c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ + Name: "FELIX_BPFDATAIFACEPATTERN", + // including "lan" interface name to default value + Value: "^((en|wl|ww|sl|ib)[Popsx].*|(lan|eth|wlan|wwan).*|tunl0$|vxlan.calico$|wireguard.cali$|wg-v6.cali$)", + }) + + c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ + Name: "FELIX_BPFEXTERNALSERVICEMODE", + Value: "DSR", + }) + + c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ + Name: "FELIX_MTUIFACEPATTERN", + Value: "lan", + }) + } + + return nil +} From 8d68e130fc46a488a946b3ebbddd7a91860fea5c Mon Sep 17 00:00:00 2001 From: Gerrit Date: Tue, 15 Oct 2024 13:41:55 +0200 Subject: [PATCH 2/4] Mutate DSs. --- pkg/webhook/shoot/add.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/webhook/shoot/add.go b/pkg/webhook/shoot/add.go index e3fed946..fe2ed840 100644 --- a/pkg/webhook/shoot/add.go +++ b/pkg/webhook/shoot/add.go @@ -25,6 +25,7 @@ func AddToManagerWithOptions(mgr manager.Manager, opts AddOptions) (*extensionsw return shoot.New(mgr, shoot.Args{ Types: []extensionswebhook.Type{ {Obj: &appsv1.Deployment{}}, + {Obj: &appsv1.DaemonSet{}}, {Obj: &corev1.ConfigMap{}}, {Obj: &corev1.Secret{}}, }, From 0fbb8db9ca1e47fae912a0c27cbd6eb895e9d618 Mon Sep 17 00:00:00 2001 From: Gerrit Date: Tue, 15 Oct 2024 13:51:20 +0200 Subject: [PATCH 3/4] Do it without the gctx. --- pkg/webhook/shoot/mutator.go | 38 +++++++++++++++--------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/pkg/webhook/shoot/mutator.go b/pkg/webhook/shoot/mutator.go index f845f9a0..222b5a8d 100644 --- a/pkg/webhook/shoot/mutator.go +++ b/pkg/webhook/shoot/mutator.go @@ -3,13 +3,10 @@ package shoot import ( "context" "fmt" + "slices" + "strconv" extensionswebhook "github.com/gardener/gardener/extensions/pkg/webhook" - extensionscontextwebhook "github.com/gardener/gardener/extensions/pkg/webhook/context" - gcontext "github.com/gardener/gardener/extensions/pkg/webhook/context" - "github.com/metal-stack/gardener-extension-provider-metal/pkg/apis/metal/helper" - - calicoextensionv1alpha1 "github.com/gardener/gardener-extension-networking-calico/pkg/apis/calico/v1alpha1" "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" @@ -47,8 +44,6 @@ func (m *mutator) Mutate(ctx context.Context, new, _ client.Object) error { return nil } - gctx := extensionscontextwebhook.NewGardenContext(m.client, new) - switch x := new.(type) { case *appsv1.Deployment: switch x.Name { @@ -61,7 +56,7 @@ func (m *mutator) Mutate(ctx context.Context, new, _ client.Object) error { switch x.Name { case "calico-node": extensionswebhook.LogMutation(logger, x.Kind, x.Namespace, x.Name) - return m.mutateCalicoNode(ctx, gctx, x) + return m.mutateCalicoNode(ctx, x) } } return nil @@ -91,23 +86,22 @@ func (m *mutator) mutateVPNShootDeployment(_ context.Context, deployment *appsv1 return nil } -func (m *mutator) mutateCalicoNode(ctx context.Context, gctx gcontext.GardenContext, ds *appsv1.DaemonSet) error { - cluster, err := gctx.GetCluster(ctx) - if err != nil { - return fmt.Errorf("unable to extract cluster from ctx: %w", err) - } +func (m *mutator) mutateCalicoNode(_ context.Context, ds *appsv1.DaemonSet) error { + if c := extensionswebhook.ContainerWithName(ds.Spec.Template.Spec.Containers, "calico-node"); c != nil { + ebpfEnabled := slices.ContainsFunc(c.Env, func(e corev1.EnvVar) bool { + if e.Name != "FELIX_BPFENABLED" { + return false + } - networkConfig := &calicoextensionv1alpha1.NetworkConfig{} - err = helper.DecodeRawExtension(cluster.Shoot.Spec.Networking.ProviderConfig, networkConfig, m.decoder) - if err != nil { - return err - } + enabled, _ := strconv.ParseBool(e.Value) - if networkConfig.EbpfDataplane == nil || !networkConfig.EbpfDataplane.Enabled { - return nil - } + return enabled + }) + + if !ebpfEnabled { + return nil + } - if c := extensionswebhook.ContainerWithName(ds.Spec.Template.Spec.Containers, "calico-node"); c != nil { m.logger.Info("patching calico-node daemon set due to ebpf dataplane being enabled") c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ From 78859fd09a04b4d8066119da467ce319cf484edb Mon Sep 17 00:00:00 2001 From: Gerrit Date: Mon, 21 Oct 2024 11:37:20 +0200 Subject: [PATCH 4/4] Add comment. --- pkg/webhook/shoot/mutator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/webhook/shoot/mutator.go b/pkg/webhook/shoot/mutator.go index 222b5a8d..8fcedb7f 100644 --- a/pkg/webhook/shoot/mutator.go +++ b/pkg/webhook/shoot/mutator.go @@ -107,6 +107,7 @@ func (m *mutator) mutateCalicoNode(_ context.Context, ds *appsv1.DaemonSet) erro c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ Name: "FELIX_BPFDATAIFACEPATTERN", // including "lan" interface name to default value + // (see https://github.com/projectcalico/calico/blob/3f7fe4d290541bbdd73c97bdc89a29a29855a48a/felix/config/config_params.go#L180) Value: "^((en|wl|ww|sl|ib)[Popsx].*|(lan|eth|wlan|wwan).*|tunl0$|vxlan.calico$|wireguard.cali$|wg-v6.cali$)", })