Skip to content

Using a Utility Sidecar

Why Use a Sidecar

When running containerized software, each individual container should represent one process. This model allows containers to be minimal, more easily secured, and to be configured with the proper resource allocations accurately.

There are common situations where running commands and tools on a pod running Ping Identity software is useful. These situations include collecting a support archive, exporting data, or running a backup. However, because many of these processes might introduce unexpected contention for CPU and memory resources, executing such commands inside the container running the actual server process can be risky. The container for the product is sized for the server process without consideration for auxiliary processes that might be executed at the same time.

To avoid these issues, one practice is to use a utility sidecar for tools that need to run alongside the main server process. This sidecar runs as a separate container on the pod. However, in the Kubernetes model, all containers in the same pod can share a process namespace (if enabled), and can also be configured to share a persistent volume. This co-location allows any required processes to run in the sidecar without competing with the main server process for the same resources.

The major downside of running a utility sidecar is that it must always be running because new containers cannot be attached to existing pods. The sidecar can be configured with minimal memory and CPU resources, but will continue to run even when it is not actively in use.

StatefulSets

You cannot remove a sidecar from a running StatefulSet without rolling all the pods.

How to Deploy a Sidecar

If you are using the Ping Identity Helm charts, you can update your custom values.yaml file to enable a sidecar for any product. For example:

pingdirectory:
  enabled: true
  workload:
    # Share process namespace for sidecar to get a view inside the main container
    shareProcessNamespace: true
  # Share /tmp so sidecar can see Java processes. Don't keep /tmp around between restarts though.
  volumes:
  - name: temp
    emptyDir: {}
  volumeMounts:
  - name: temp
    mountPath: /tmp
  # Backups, restores, and other CLI tools should be run from the sidecar to prevent interfering
  # with the main PingDirectory container process.
  utilitySidecar:
    enabled: true

These values will add a sidecar container using the same image as the main server container, configured with minimal resources and waiting in an endless loop. The generated yaml will look like the following example and could be applied directly outside of Helm:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app.kubernetes.io/name: pingdirectory
  name: sidecar-pingdirectory
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: pingdirectory
  serviceName: sidecar-pingdirectory-cluster
  template:
    metadata:
      labels:
        app.kubernetes.io/name: pingdirectory
    spec:
      containers:
      - envFrom:
        - secretRef:
            name: devops-secret
            optional: true
        image: pingidentity/pingdirectory:latest
        livenessProbe:
          exec:
            command:
            - /opt/liveness.sh
          failureThreshold: 4
          initialDelaySeconds: 30
          periodSeconds: 30
          successThreshold: 1
          timeoutSeconds: 5
        name: pingdirectory
        ports:
        - containerPort: 1443
          name: https
        - containerPort: 1389
          name: ldap
        - containerPort: 1636
          name: ldaps
        readinessProbe:
          exec:
            command:
            - /opt/readiness.sh
          failureThreshold: 4
          initialDelaySeconds: 30
          periodSeconds: 30
          successThreshold: 1
          timeoutSeconds: 5
        resources:
          limits:
            cpu: 2
            memory: 8Gi
          requests:
            cpu: 50m
            memory: 2Gi
        startupProbe:
          exec:
            command:
            - /opt/liveness.sh
          failureThreshold: 180
          periodSeconds: 10
          timeoutSeconds: 5
        volumeMounts:
        - mountPath: /tmp
          name: temp
        - mountPath: /opt/out
          name: out-dir
      - args:
        - -f
        - /dev/null
        command:
        - tail
        image: pingidentity/pingdirectory:latest
        name: utility-sidecar
        resources:
          limits:
            cpu: "1"
            memory: 2Gi
          requests:
            cpu: "0"
            memory: 128Mi
        volumeMounts:
        - mountPath: /opt/out
          name: out-dir
        - mountPath: /tmp
          name: temp
      securityContext:
        fsGroup: 0
        runAsGroup: 0
        runAsUser: 9031
      shareProcessNamespace: true
      terminationGracePeriodSeconds: 300
      volumes:
      - emptyDir: {}
        name: temp
      - name: out-dir
        persistentVolumeClaim:
          claimName: out-dir
  volumeClaimTemplates:
  - metadata:
      name: out-dir
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 8Gi
      storageClassName: null