Obtaining the images

Containerized masking utilizes three integrated containers to deliver, in essence, the same masking experience as provided on a Continuous Compliance Engine deployed on a VM. The containerized form allows for rapid spin up/tear down of ephemeral engines to handle automated workflow deployments. These three containers are delivered in a compressed archive (.tar.gz) for convenience.

Licensed versions of these bundles are available for download from the download.delphix.com site. In the folder for each version are two files. One file is HTML instructions similar to this page that can be downloaded for an offline copy of the installation instructions. The second file is the masking_docker_images.tar.gz bundle with the container images.

As an alternative to loading images from the tarball, users following the Direct Kubernetes Installation path can pull the same images from Amazon ECR (or a mirrored internal registry) by updating image references for delphix-masking-database, delphix-masking-app, and delphix-masking-proxy, and configuring registry access (for example, imagePullSecrets) in the pod spec.

Docker is employed to build the container images, which produces a set of OCI-compliant (Open Container Initiative) images for each container. The intention is to make the containers as vendor independent as possible.

The following examples show one way to configure registry access and image references in a direct Kubernetes deployment. Create an image pull secret (if your cluster does not already have pull access):

kubectl create secret docker-registry delphix-masking-image-pull-secret \ 
  --namespace delphix-masking \ 
  --docker-server=<registry> \ 
  --docker-username=<username> \ 
  --docker-password=<password>

Use the secret and set image references in the pod template:

imagePullSecrets: 
  - name: delphix-masking-image-pull-secret 
containers: 
  - name: mds 
    image: <registry>/delphix-masking-database:<version> 
    imagePullPolicy: IfNotPresent 
  - name: app 
    image: <registry>/delphix-masking-app:<version> 
    imagePullPolicy: IfNotPresent 
  - name: proxy 
    image: <registry>/delphix-masking-proxy:<version> 
    imagePullPolicy: IfNotPresent
The mds, app, and proxy containers run with readOnlyRootFilesystem: true. Writable paths required at runtime are supplied by the emptyDir volumes shown below; their contents do not persist across pod restarts.

Sample configuration

The following configuration file shows an example of how Containerized masking might be deployed. Details will vary based on the use case, environment, and product version.


apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv2
spec:
  capacity:
    storage: 500Mi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  storageClassName: nfs-storage2
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    server: {}
    path: {}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc2
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  storageClassName: nfs-storage2
  resources:
    requests:
      storage: 500Mi
---
apiVersion: v1
kind: Service
metadata:
  name: delphix-masking
spec:
  type: NodePort
  selector:
    app: masking
  ports:
    - name: http
      port: 8080
      nodePort: 30080
    - name: https
      port: 8443
      nodePort: 30443
---
apiVersion: v1
kind: Service
metadata:
  name: delphix-masking-debugging
spec:
  type: NodePort
  selector:
    app: masking
  ports:
    - port: 15213
      nodePort: 32213
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: delphix-masking
spec:
  selector:
    matchLabels:
      app: masking
  serviceName: delphix-masking
  template:
    metadata:
      labels:
        app: masking
    spec:
      securityContext:
        runAsUser: 65436
        runAsGroup: 50
        fsGroup: 50
        #
        # This is false so that we can run the initContainer as root, for
        # reasons explained below, but customers should be able to set this to
        # true in production.
        #
        runAsNonRoot: false
      initContainers:
        #
        # Ideally, we would rely on fsGroup to set ownership/permissions in the
        # mounted volumes such that they can be accessed by the containers.
        # However, some volume provisioners don't support fsGroup, including the
        # hostPath provisioner (https://github.com/kubernetes/minikube/issues/1990),
        # which is the default provisioner for Minikube and Microk8s, which we
        # use for development and testing. So that we can continue to use these
        # flavors of k8s, we run an initContainer that we set the ownership and
        # permissions to be the same as if the volume were created with
        # provisioner that honored the fsGroup setting.
        #
        - image: busybox
          name: initialize-volumes
          securityContext:
            runAsUser: 0  # Volumes are owned by root:root
          volumeMounts:
			- name: proxy-var-cache
		      mountPath: /var/cache
		    - name: proxy-var-run
		      mountPath: /var/run
		  command:
		    - "/bin/sh"
		    - "-c"
		    - |
		    set -e
		    # Persistent volume ownership/permissions:
		    chmod 2775 /var/delphix/masking && chgrp 50 /var/delphix/masking
		    chmod 2775 /var/delphix/postgresql && chgrp 50 /var/delphix/postgresql
		    # The proxy container requires these directories to exist before
		    # nginx starts. emptyDir volumes shadow the directories that ship
		    # in the container image, so anything nginx expects to find
		    # pre-existing must be re-created here by the initContainer
		    # (which runs as root):
		    mkdir -p /var/cache/nginx/client_temp
		    mkdir -p /var/cache/nginx/proxy_temp
		    mkdir -p /var/cache/nginx/fastcgi_temp
		    mkdir -p /var/cache/nginx/uwsgi_temp
		    mkdir -p /var/cache/nginx/scgi_temp
		    chgrp -R 50 /var/cache/nginx
		    chmod -R 2775 /var/cache/nginx
		    # Pre-create the nginx PID directory:
		    mkdir -p /var/run
		    chgrp 50 /var/run
		    chmod 2775 /var/run
          volumeMounts:
            - name: masking-persistent-storage
              mountPath: /var/delphix/postgresql
              subPath: postgresql
            - name: masking-persistent-storage
              mountPath: /var/delphix/masking
              subPath: masking
          command:
            - "/bin/sh"
            - "-c"
					- "chmod 2775 /var/delphix/masking && chgrp 50 /var/delphix/masking && chmod 2775 /var/delphix/postgresql && chgrp 50 /var/delphix/postgresql"
      volumes:
		- name: nfs-pv-storage
	          persistentVolumeClaim:
	          claimName: nfs-pvc
	 	#
	    # Writable emptyDir volumes for readOnlyRootFilesystem support.
	    # These provide writable scratch space at paths that the containers
	    # need to write to at runtime (tmp files, PID files, caches, etc.)
	    # without allowing writes to the rest of the root filesystem.
	    # NOTE: emptyDir volumes are ephemeral — all data is lost on pod
	    # restart. This is acceptable for temp files, caches, and PID files.
	    #
	    - name: mds-tmp
	      emptyDir: {}
	    - name: mds-var-tmp
	      emptyDir: {}
	    - name: mds-run-postgresql
	      emptyDir: {}
	    - name: app-tmp
	      emptyDir: {}
	    - name: app-var-tmp
	      emptyDir: {}
	    - name: app-ssl
	      emptyDir: {}
	    - name: app-dxrt
	      emptyDir: {}
	    - name: proxy-etc-config
	      emptyDir: {}
	    - name: proxy-var-cache
	      emptyDir: {}
	    - name: proxy-tmp
	      emptyDir: {}
	    - name: proxy-var-run
	      emptyDir: {}  
      containers:
        - image: delphix-masking-database:{}
          imagePullPolicy: Never # This image has to be built locally
          name: mds
          securityContext:
            readOnlyRootFilesystem: true
          ports:
            - containerPort: 5432
              name: mds
          volumeMounts:
            - name: masking-persistent-storage
              mountPath: /var/delphix/postgresql
              subPath: postgresql
            - name: mds-tmp
              mountPath: /tmp
            - name: mds-var-tmp
              mountPath: /var/tmp
            - name: mds-run-postgresql
              mountPath: /var/run/postgresql
        - image: delphix-masking-app:{}
          imagePullPolicy: Never # This image has to be built locally
          name: app
          securityContext:
            readOnlyRootFilesystem: true
          ports:
            - containerPort: 8284
              name: http
          volumeMounts:
            - name: masking-persistent-storage
              mountPath: /var/delphix/masking
              subPath: masking
            - name: masking-persistent-storage
              mountPath: /var/delphix/postgresql
              subPath: postgresql
            - name: nfs-pv-storage2
              mountPath: /var/delphix/masking/remote-mounts/nfs_2
            - name: app-tmp
              mountPath: /tmp
            - name: app-var-tmp
              mountPath: /var/tmp
            - name: app-ssl
              mountPath: /var/delphix/ssl
            - name: app-dxrt
              mountPath: /var/delphix/sfdc/dxrt
          env:
            - name: MASK_DEBUG
              value: "true"
        - name: proxy
          image: delphix-masking-proxy:{}
          imagePullPolicy: Never # This image has to be built locally
          securityContext:
            readOnlyRootFilesystem: true
          ports:
          - containerPort: 8080
            name: http
          - containerPort: 8443
            name: https
          volumeMounts:
            - name: proxy-tmp
              mountPath: /tmp
            - name: proxy-etc-config
              mountPath: /etc/config
            - name: proxy-var-cache
              mountPath: /var/cache
            - name: proxy-var-run
              mountPath: /var/run
  volumeClaimTemplates:
    - metadata:
        name: masking-persistent-storage
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 4Gi

Deployment

Load the container images obtained from the download site into some Kubernetes container registry, then deploy the masking Pod using a config file similar to the example provided above.

kubectl apply -f <path-to-config-file>

 

 

Last updated
May 15, 2026