mirror of
https://github.com/netbirdio/kubernetes-operator.git
synced 2026-05-22 17:11:40 -07:00
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:
@@ -105,7 +105,6 @@ func main() {
|
||||
"",
|
||||
"Default labels used for all resources, in format key=value,key=value",
|
||||
)
|
||||
|
||||
// Controller generic flags
|
||||
var (
|
||||
metricsAddr string
|
||||
|
||||
+17
-8
@@ -49,6 +49,15 @@ Since v0.27.0, NetBird supports extra DNS labels, which extends the DNS names th
|
||||
```
|
||||
With this setup, all peers with the same extra label would be used in a DNS round-robin fashion.
|
||||
|
||||
### Init Sidecar Mode
|
||||
|
||||
By default, the NetBird container is injected as a regular sidecar container. For workloads like Jobs and CronJobs where the pod should terminate after the main container completes, you can use init sidecar mode. This injects NetBird as an init container with `restartPolicy: Always`.
|
||||
|
||||
To enable init sidecar mode, add the following annotation:
|
||||
```yaml
|
||||
netbird.io/init-sidecar: "true"
|
||||
```
|
||||
|
||||
## Provisioning Networks (Ingress Functionality)
|
||||
|
||||
### Granting controller access to NetBird Management
|
||||
@@ -89,10 +98,10 @@ cluster:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority: /home/user/.minikube/ca.crt
|
||||
server: https://kubernetes.default.svc.cluster.local
|
||||
name: minikube
|
||||
- cluster:
|
||||
certificate-authority: /home/user/.minikube/ca.crt
|
||||
server: https://kubernetes.default.svc.cluster.local
|
||||
name: minikube
|
||||
```
|
||||
|
||||
### Exposing a Service
|
||||
@@ -175,12 +184,12 @@ ingress:
|
||||
name: Kubernetes Default Policy # Required, name of policy in NetBird console
|
||||
description: Default # Optional
|
||||
sourceGroups: # Required, name of groups to assign as source in Policy.
|
||||
- All
|
||||
- All
|
||||
ports: # Optional, resources annotated 'netbird.io/policy=default' will append to this.
|
||||
- 443
|
||||
- 443
|
||||
protocols: # Optional, restricts protocols allowed to resources, defaults to ['tcp', 'udp'].
|
||||
- tcp
|
||||
- udp
|
||||
- tcp
|
||||
- udp
|
||||
bidirectional: true # Optional, defaults to true
|
||||
```
|
||||
2. Reference policies in Services using `netbird.io/policy=default,otherpolicy,...`, this will add relevant ports and destination groups to policies.
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: test
|
||||
namespace: default
|
||||
stringData:
|
||||
SETUP_KEY: 50445ABC-8901-4050-8047-0A390658A79B # Replace with valid setup key
|
||||
---
|
||||
apiVersion: netbird.io/v1
|
||||
kind: NBSetupKey
|
||||
metadata:
|
||||
name: test
|
||||
namespace: default
|
||||
spec:
|
||||
secretKeyRef:
|
||||
name: test
|
||||
key: SETUP_KEY
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: job
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
netbird.io/setup-key: test
|
||||
netbird.io/init-sidecar: "true"
|
||||
spec:
|
||||
containers:
|
||||
- name: worker
|
||||
image: curlimages/curl:latest
|
||||
command: ["sh", "-c", "curl -s https://example.com && echo done && sleep 60"]
|
||||
restartPolicy: Never
|
||||
backoffLimit: 3
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: cronjob
|
||||
spec:
|
||||
schedule: "*/30 * * * *"
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
netbird.io/setup-key: test
|
||||
netbird.io/init-sidecar: "true"
|
||||
spec:
|
||||
containers:
|
||||
- name: worker
|
||||
image: curlimages/curl:latest
|
||||
command: ["sh", "-c", "curl -s https://example.com && echo done"]
|
||||
restartPolicy: Never
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user