Add support for running as a init sidecar container (#99)

Adds support for injecting the client as a [sidecar
container](https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/)
using the `netbird.io/init-sidecar: "true"` pod annotation.
This commit is contained in:
Bethuel Mmbaga
2026-02-11 15:20:52 +03:00
committed by GitHub
parent d548240320
commit 5fb144559c
5 changed files with 123 additions and 17 deletions
+24 -8
View File
@@ -33,6 +33,7 @@ import (
const (
setupKeyAnnotation = "netbird.io/setup-key"
sidecarAnnotation = "netbird.io/init-sidecar"
)
// nolint:unused
@@ -121,8 +122,27 @@ func (d *PodNetbirdInjector) Default(ctx context.Context, obj runtime.Object) er
}
}
// Append the netbird container with the constructed env vars.
pod.Spec.Containers = append(pod.Spec.Containers, corev1.Container{
// Build the netbird container spec.
nbContainer := d.buildNetbirdContainer(envVars, nbSetupKey.Spec.VolumeMounts)
// If sidecar mode is requested, inject as a sidecar (init container with restartPolicy: Always).
if pod.Annotations[sidecarAnnotation] == "true" {
restartPolicy := corev1.ContainerRestartPolicyAlways
nbContainer.RestartPolicy = &restartPolicy
pod.Spec.InitContainers = append(pod.Spec.InitContainers, nbContainer)
} else {
pod.Spec.Containers = append(pod.Spec.Containers, nbContainer)
}
pod.Spec.Volumes = append(pod.Spec.Volumes, nbSetupKey.Spec.Volumes...)
return nil
}
// buildNetbirdContainer constructs the NetBird container spec with the given
// environment variables and volume mounts.
func (d *PodNetbirdInjector) buildNetbirdContainer(envVars []corev1.EnvVar, volumeMounts []corev1.VolumeMount) corev1.Container {
return corev1.Container{
Name: "netbird",
Image: d.clientImage,
Env: envVars,
@@ -131,10 +151,6 @@ func (d *PodNetbirdInjector) Default(ctx context.Context, obj runtime.Object) er
Add: []corev1.Capability{"NET_ADMIN"},
},
},
VolumeMounts: nbSetupKey.Spec.VolumeMounts,
})
pod.Spec.Volumes = append(pod.Spec.Volumes, nbSetupKey.Spec.Volumes...)
return nil
VolumeMounts: volumeMounts,
}
}
+27
View File
@@ -125,6 +125,33 @@ var _ = Describe("Pod Webhook", func() {
Expect(obj.Spec.Containers).To(HaveLen(2))
Expect(obj.Spec.Containers[1].Name).To(Equal("netbird"))
})
It("Should inject NB container as native sidecar when init-sidecar annotation is true", func() {
obj.Annotations[sidecarAnnotation] = "true"
Expect(defaulter.Default(context.Background(), obj)).NotTo(HaveOccurred())
Expect(obj.Spec.Containers).To(HaveLen(1), "original containers should be unchanged")
Expect(obj.Spec.InitContainers).To(HaveLen(1))
Expect(obj.Spec.InitContainers[0].Name).To(Equal("netbird"))
Expect(obj.Spec.InitContainers[0].RestartPolicy).NotTo(BeNil())
Expect(*obj.Spec.InitContainers[0].RestartPolicy).To(Equal(corev1.ContainerRestartPolicyAlways))
})
It("Should inject NB as regular container when init-sidecar annotation is false", func() {
obj.Annotations[sidecarAnnotation] = "false"
Expect(defaulter.Default(context.Background(), obj)).NotTo(HaveOccurred())
Expect(obj.Spec.Containers).To(HaveLen(2))
Expect(obj.Spec.Containers[1].Name).To(Equal("netbird"))
Expect(obj.Spec.InitContainers).To(BeEmpty())
})
It("Should inject NB as regular container when init-sidecar annotation is absent", func() {
delete(obj.Annotations, sidecarAnnotation)
Expect(defaulter.Default(context.Background(), obj)).NotTo(HaveOccurred())
Expect(obj.Spec.Containers).To(HaveLen(2))
Expect(obj.Spec.Containers[1].Name).To(Equal("netbird"))
Expect(obj.Spec.InitContainers).To(BeEmpty())
})
})
})
})