Repository: cdk8s-team/cdk8s-plus
Pull request #4574 (2024-08-27 10:52:19)

fix(pod): allow sidecar containers to have probes (#4483)
# Backport

This will backport the following commits from `k8s-30/main` to `k8s-28/main`:
 - [fix(pod): allow sidecar containers to have probes (#4483)](https://github.com/cdk8s-team/cdk8s-plus/pull/4483)

<!--- Backport version: 8.9.9 -->

### Questions ?
Please refer to the [Backport tool documentation](https://github.com/sqren/backport)


Patch:
diff --git a/src/pod.ts b/src/pod.ts
index c7f4ea6b..3ac602bc 100644
--- a/src/pod.ts
+++ b/src/pod.ts
@@ -122,15 +122,15 @@ export abstract class AbstractPod extends base.Resource implements IPodSelector,
   public addInitContainer(cont: container.ContainerProps): container.Container {
 
     // https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#differences-from-regular-containers
-    if (cont.readiness) {
+    if (!this.isSidecarContainer(cont) && cont.readiness) {
       throw new Error('Init containers must not have a readiness probe');
     }
 
-    if (cont.liveness) {
+    if (!this.isSidecarContainer(cont) && cont.liveness) {
       throw new Error('Init containers must not have a liveness probe');
     }
 
-    if (cont.startup) {
+    if (!this.isSidecarContainer(cont) && cont.startup) {
       throw new Error('Init containers must not have a startup probe');
     }
 
@@ -143,6 +143,13 @@ export abstract class AbstractPod extends base.Resource implements IPodSelector,
     return impl;
   }
 
+  // Any initContainer that has `restartPolicy=Always` is a sidecar container. Please refer to
+  // documentation for more details:
+  // https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/#differences-from-init-containers
+  private isSidecarContainer(cont: container.ContainerProps) {
+    return cont.restartPolicy === container.ContainerRestartPolicy.ALWAYS;
+  }
+
   public addHostAlias(hostAlias: HostAlias): void {
     this._hostAliases.push(hostAlias);
   }


Test patch:
diff --git a/test/pod.test.ts b/test/pod.test.ts
index 977e64da..17f44567 100644
--- a/test/pod.test.ts
+++ b/test/pod.test.ts
@@ -254,6 +254,45 @@ test('init containers cannot have startup probe', () => {
 
 });
 
+test('sidecar containers can have liveness probe', () => {
+
+  const chart = Testing.chart();
+  const pod = new kplus.Pod(chart, 'Pod', { containers: [{ image: 'image' }] });
+
+  pod.addInitContainer({ image: 'image', liveness: Probe.fromTcpSocket(), restartPolicy: ContainerRestartPolicy.ALWAYS });
+
+  const spec = Testing.synth(chart)[0].spec;
+
+  expect(spec.initContainers[0].livenessProbe).toBeTruthy();
+
+});
+
+test('sidecar containers can have readiness probe', () => {
+
+  const chart = Testing.chart();
+  const pod = new kplus.Pod(chart, 'Pod', { containers: [{ image: 'image' }] });
+
+  pod.addInitContainer({ image: 'image', readiness: Probe.fromTcpSocket(), restartPolicy: ContainerRestartPolicy.ALWAYS });
+
+  const spec = Testing.synth(chart)[0].spec;
+
+  expect(spec.initContainers[0].readinessProbe).toBeTruthy();
+
+});
+
+test('sidecar containers can have startup probe', () => {
+
+  const chart = Testing.chart();
+  const pod = new kplus.Pod(chart, 'Pod', { containers: [{ image: 'image' }] });
+
+  pod.addInitContainer({ image: 'image', startup: Probe.fromTcpSocket(), restartPolicy: ContainerRestartPolicy.ALWAYS });
+
+  const spec = Testing.synth(chart)[0].spec;
+
+  expect(spec.initContainers[0].startupProbe).toBeTruthy();
+
+});
+
 test('can specify init containers at instantiation', () => {
 
   const chart = Testing.chart();