-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: allow proxies to be injected using a native sidecar #1442
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -154,8 +154,14 @@ func (m *podMutator) Handle(ctx context.Context, req admission.Request) (respons | |||||||||||||||||||||
return admission.Errored(http.StatusBadRequest, err) | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
useNativeSidecar := useNativeProxySidecar(pod) | ||||||||||||||||||||||
|
||||||||||||||||||||||
pod.Spec.InitContainers = m.injectProxyInitContainer(pod.Spec.InitContainers, proxyPort) | ||||||||||||||||||||||
pod.Spec.Containers = m.injectProxySidecarContainer(pod.Spec.Containers, proxyPort) | ||||||||||||||||||||||
if useNativeSidecar { | ||||||||||||||||||||||
pod.Spec.InitContainers = m.injectProxySidecarContainer(pod.Spec.InitContainers, proxyPort, ptr.To(corev1.ContainerRestartPolicyAlways)) | ||||||||||||||||||||||
} else { | ||||||||||||||||||||||
pod.Spec.Containers = m.injectProxySidecarContainer(pod.Spec.Containers, proxyPort, nil) | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+160
to
+164
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// get service account token expiration | ||||||||||||||||||||||
|
@@ -228,13 +234,18 @@ func (m *podMutator) injectProxyInitContainer(containers []corev1.Container, pro | |||||||||||||||||||||
return containers | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
func (m *podMutator) injectProxySidecarContainer(containers []corev1.Container, proxyPort int32) []corev1.Container { | ||||||||||||||||||||||
func (m *podMutator) injectProxySidecarContainer(containers []corev1.Container, proxyPort int32, restartPolicy *corev1.ContainerRestartPolicy) []corev1.Container { | ||||||||||||||||||||||
imageRepository := strings.Join([]string{ProxyImageRegistry, ProxySidecarImageName}, "/") | ||||||||||||||||||||||
for _, container := range containers { | ||||||||||||||||||||||
if container.Name == ProxySidecarContainerName { | ||||||||||||||||||||||
return containers | ||||||||||||||||||||||
// proxy-init starts with proxy, so we append ":" to imageRepository when checking | ||||||||||||||||||||||
if strings.HasPrefix(container.Image, fmt.Sprintf("%s:", imageRepository)) || container.Name == ProxySidecarContainerName { | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this check was removed as part of #1443 |
||||||||||||||||||||||
return containers | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
logLevel := currentLogLevel() // run the proxy at the same log level as the webhook | ||||||||||||||||||||||
|
||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
containers = append([]corev1.Container{{ | ||||||||||||||||||||||
Name: ProxySidecarContainerName, | ||||||||||||||||||||||
Image: m.proxyImage, | ||||||||||||||||||||||
|
@@ -267,6 +278,7 @@ func (m *podMutator) injectProxySidecarContainer(containers []corev1.Container, | |||||||||||||||||||||
ReadOnlyRootFilesystem: ptr.To(true), | ||||||||||||||||||||||
RunAsNonRoot: ptr.To(true), | ||||||||||||||||||||||
}, | ||||||||||||||||||||||
RestartPolicy: restartPolicy, | ||||||||||||||||||||||
}}, containers...) | ||||||||||||||||||||||
|
||||||||||||||||||||||
return containers | ||||||||||||||||||||||
|
@@ -280,6 +292,14 @@ func shouldInjectProxySidecar(pod *corev1.Pod) bool { | |||||||||||||||||||||
return ok | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
func useNativeProxySidecar(pod *corev1.Pod) bool { | ||||||||||||||||||||||
if len(pod.Annotations) == 0 { | ||||||||||||||||||||||
return false | ||||||||||||||||||||||
} | ||||||||||||||||||||||
_, ok := pod.Annotations[UseNativeSidecarAnnotation] | ||||||||||||||||||||||
return ok | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// getSkipContainers gets the list of containers to skip based on the annotation | ||||||||||||||||||||||
func getSkipContainers(pod *corev1.Pod) map[string]struct{} { | ||||||||||||||||||||||
skipContainers := pod.Annotations[SkipContainersAnnotation] | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1151,7 +1151,7 @@ func TestInjectProxySidecarContainer(t *testing.T) { | |
m := &podMutator{proxyImage: imageURL} | ||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
containers := m.injectProxySidecarContainer(test.containers, proxyPort) | ||
containers := m.injectProxySidecarContainer(test.containers, proxyPort, nil) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update this table test to include restart policy and ensure the return result contains the desired restart policy |
||
if !reflect.DeepEqual(containers, test.expectedContainers) { | ||
t.Errorf("expected: %v, got: %v", test.expectedContainers, containers) | ||
} | ||
|
@@ -1198,6 +1198,45 @@ func TestShouldInjectProxySidecar(t *testing.T) { | |
} | ||
} | ||
|
||
func TestShouldUseNativeSidecar(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
pod *corev1.Pod | ||
expected bool | ||
}{ | ||
{ | ||
name: "pod not annotated", | ||
pod: &corev1.Pod{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "pod", | ||
}, | ||
}, | ||
expected: false, | ||
}, | ||
{ | ||
name: "pod is annotated with azure.workload.identity/use-native-sidecar=true", | ||
pod: &corev1.Pod{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "pod", | ||
Annotations: map[string]string{ | ||
UseNativeSidecarAnnotation: "true", | ||
}, | ||
}, | ||
}, | ||
expected: true, | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
actual := useNativeProxySidecar(test.pod) | ||
if actual != test.expected { | ||
t.Fatalf("expected: %v, got: %v", test.expected, actual) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestGetProxyPort(t *testing.T) { | ||
type args struct { | ||
pod *corev1.Pod | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a note about the minimum required kubernetes version this annotation can be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the wrong approach IMO. I think we should instead detect at runtime (once at webhook start up time) if the cluster supports native sidecars, and if it does, we should simply always use them for the proxy sidecar. If for some reason we cannot detect this at runtime, we can make it a CLI flag based config to the webhook (possibly enabled by default since in a few days Kube v1.30 will be the oldest supported upstream version).