Kubernetes
CloudSQL-proxy
sidecar container
multi-container Pod
container management

Kubernetes stop CloudSQL-proxy sidecar container in multi container Pod/Job

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

In Kubernetes Jobs with a Cloud SQL Proxy sidecar, the main container can finish while the sidecar keeps running, so the Pod never reaches completed state. This is a common operational problem in batch workloads. A reliable solution requires explicit sidecar shutdown coordination, not only successful completion of the main process.

Why Jobs Get Stuck With Sidecars

A Job Pod is complete only when all regular containers terminate successfully. If your app container exits but proxy container continues to run, the Pod remains active and the Job does not complete.

This behavior is expected from Kubernetes perspective, because sidecar has not been told to stop.

Typical symptoms:

  • Main container logs show successful completion.
  • Cloud SQL Proxy sidecar remains healthy and running.
  • Job object shows active Pod count not decreasing.

Baseline Pattern With Shared Process Namespace

One practical pattern is enabling shared process namespace and letting main container signal sidecar when work is done.

yaml
1apiVersion: batch/v1
2kind: Job
3metadata:
4  name: report-job
5spec:
6  template:
7    spec:
8      shareProcessNamespace: true
9      restartPolicy: Never
10      containers:
11        - name: app
12          image: bash:5.2
13          command:
14            - /bin/sh
15            - -c
16            - |
17              echo "run batch work"
18              sleep 3
19              echo "stop proxy sidecar"
20              pkill -f cloud-sql-proxy || true
21        - name: cloudsql-proxy
22          image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.11.0
23          args:
24            - "--port=5432"
25            - "project:region:instance"

This pattern is simple and effective when security policy allows shared process namespace.

Add Graceful Shutdown and Timing Controls

To avoid abrupt termination issues, configure graceful termination behavior.

yaml
1spec:
2  template:
3    spec:
4      terminationGracePeriodSeconds: 30
5      containers:
6        - name: cloudsql-proxy
7          lifecycle:
8            preStop:
9              exec:
10                command:
11                  - /bin/sh
12                  - -c
13                  - sleep 2

Grace periods reduce the chance of interrupted DB sessions during shutdown.

Coordination Through a File Signal

If you prefer avoiding process-kill from the main container, use a shared volume and a stop file signal.

Main container writes marker file at completion. Sidecar loop watches for that file and exits.

yaml
1apiVersion: batch/v1
2kind: Job
3metadata:
4  name: export-job
5spec:
6  template:
7    spec:
8      restartPolicy: Never
9      volumes:
10        - name: control
11          emptyDir: {}
12      containers:
13        - name: app
14          image: bash:5.2
15          volumeMounts:
16            - name: control
17              mountPath: /control
18          command:
19            - /bin/sh
20            - -c
21            - |
22              echo "work"
23              sleep 2
24              touch /control/stop-proxy
25        - name: cloudsql-proxy
26          image: bash:5.2
27          volumeMounts:
28            - name: control
29              mountPath: /control
30          command:
31            - /bin/sh
32            - -c
33            - |
34              cloud-sql-proxy --port=5432 project:region:instance &
35              PROXY_PID=$!
36              while [ ! -f /control/stop-proxy ]; do sleep 1; done
37              kill "$PROXY_PID"
38              wait "$PROXY_PID"

This approach is explicit and easy to reason about during audits.

Prefer Native Job-Friendly Designs When Possible

If batch task only needs DB connectivity for short periods, consider alternatives:

  • Move proxy to a dedicated Deployment and connect over service.
  • Use language-level connector libraries if operationally acceptable.
  • Keep Job Pod single-container if security and networking allow.

Fewer containers in Job Pods means fewer completion edge cases.

Observability and Debugging Checklist

When Job does not complete:

  1. Check container states with kubectl get pod -o json.
  2. Confirm which container remains running.
  3. Inspect sidecar logs for signal handling behavior.
  4. Verify main container reached shutdown logic path.
  5. Confirm Pod spec has expected namespace and lifecycle settings.

Basic commands:

bash
1kubectl get jobs
2kubectl get pods -l job-name=report-job
3kubectl describe pod <pod-name>
4kubectl logs <pod-name> -c app
5kubectl logs <pod-name> -c cloudsql-proxy

Common Pitfalls

  • Assuming Job completes when main container exits, while sidecar still runs.
  • Forgetting explicit sidecar termination path.
  • Using process signaling without shared process namespace.
  • Missing grace period settings and causing unclean DB shutdown.
  • Shipping multi-container Job without logs that prove shutdown sequence.

Summary

  • In Job Pods, all regular containers must exit for completion.
  • Cloud SQL Proxy sidecars need explicit stop coordination.
  • Shared process namespace plus signal, or shared-file signaling, are practical patterns.
  • Add graceful termination settings for cleaner shutdown.
  • Keep observability around shutdown paths so stuck Jobs are quickly diagnosable.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.