PrizmDoc® v14.3 Release - Updated January 14, 2025
PrizmDoc / Administrator Guide / Kubernetes / Deployment to Kubernetes Guidance
Deployment to Kubernetes Guidance

Introduction

This section provides general guidance about deploying PrizmDoc to Kubernetes. This guidance assumes that you will use YAML manifest files to configure the required resources. See Managing Resources Kubernetes documentation for more information.

Getting Started

We recommend you use our hello-prizmdoc-viewer-with-kubernetes sample as a starting point. It contains complete manifest files which are ready for deployment to Kubernetes. Once you have the cluster up and running, proceed to Resources Used in PrizmDoc Deployment for details on PrizmDoc Kubernetes cluster resources and how they can be adjusted for production use.

Resources Used in PrizmDoc Deployment

PrizmDoc deployment uses three kinds of workload resources, which are described in more detail below:

  • PrizmDoc Server is a document processing and conversion engine. It is compute intensive; most likely, you will use multiple PrizmDoc Server pods in your cluster, and increase or decrease the number of pods depending on the load.
  • PrizmDoc Cluster Manager is a small add-on that automatically notifies PrizmDoc Server instances in the cluster about the availability of other PrizmDoc Server instances in this cluster. Although this feature is most important when the cluster is scaled, we highly recommend using the Cluster Manager even in the case of a static cluster.
  • PrizmDoc Application Services is a layer in front of PrizmDoc Server responsible for viewing concerns, such as saving and loading annotations.

NOTE: PrizmDoc Viewer requires a database. The hello-prizmdoc-viewer-with-kubernetes sample includes an example manifest for a MySql resource. In production, you may use a standalone database instead.

NOTE: Use of a Central Database for PrizmDoc will be required in order to move towards eliminating server affinity.

PrizmDoc Server

You will need the following resources for the PrizmDoc Server:

We recommend that you define all those resources in a single YAML file.

ConfigMap for PrizmDoc Server Central Configuration Parameters

Use the ConfigMap resource to configure the PrizmDoc Server. See Central Configuration for a detailed description of PrizmDoc Server configuration parameters.

We recommend that you start with the prizmdoc-server-config ConfigMap included in the prizmdoc-server.yaml manifest of the hello-prizmdoc-viewer-with-kubernetes sample, and then modify or add the necessary parameters. You will likely need to change the license.key and possibly (for some types of licenses) the license.solutionName. If you need to change parameters which are not included in the sample configuration, you can create a PrizmDoc Server config file to get the full list of parameters with default values, and add the necessary ones to your ConfigMap.

NOTE: We recommend that you keep some of the parameters, such as port numbers and directory paths, unchanged. See Central Configuration for details.

Below is a shortened example of a ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prizmdoc-server-config
data:
  prizm-services-config.yml: |-
    license.key: YOUR_LICENSE_KEY
    license.solutionName: YOUR_SOLUTION_NAME
    ...

StatefulSet for the PrizmDoc Server Application

PrizmDoc Server should be deployed as a stateful application.

Create a StatefulSet resource which is running the accusoft/prizmdoc-server containers. Make sure you set the required environment variables, expose public ports, and define the Central Configuration mapping. You will also need to create a Headless Service, which is a requirement for using the stateful set.

We recommend that you use equal resource requests and limits for your PrizmDoc server containers, and choose the values according to the Server Sizing guide.

Make sure to set up the readinessProbe, which tells whether the PrizmDoc Server container is ready to receive traffic through Kubernetes Services and the livenessProbe which tells whether the instance is healthy. Use the GET /PCCIS/V1/Service/Current/Health request for each of those probes. Kubernetes will automatically restart the instance if it becomes unhealthy, and block the traffic to the instance while it is restarting.

Below is a shortened example of a StatefulSet resource definition for PrizmDoc Server.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: prizmdoc-server
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: prizmdoc-server
  serviceName: prizmdoc-server-headless
  replicas: 2
  template:
    spec:
      containers:
        - name: prizmdoc-server
          image: accusoft/prizmdoc-server
          ports:
            - name: public
              containerPort: 18681
              protocol: TCP
            - name: internal
              containerPort: 18682
              protocol: TCP
          volumeMounts:
            - name: prizmdoc-server-config
              mountPath: /config
              readOnly: true
            - name: prizmdoc-server-data
              mountPath: /data
          env:
            - name: ACCEPT_EULA
              value: "YES"
      volumes:
        - name: prizmdoc-server-config
          configMap:
            name: prizmdoc-server-config


You can find a complete resource definition in the prizmdoc-server.yaml manifest included with the hello-prizmdoc-viewer-with-kubernetes sample.

Storage for the Application Logs

It is important to store PrizmDoc Server log files in a persistent storage so that you can control log file sizes and package log files for support if needed. It is possible to use one volume to keep log files from all PrizmDoc instances in your cluster. We recommend you to use a sidecar container with the logging agent with Fluent Bit as a lightweight logging agent.

You can use the prizmdoc-server-logging-agent container in the prizmdoc-server.yaml manifest included with the hello-prizmdoc-viewer-with-kubernetes sample as an example of a logging sidecar container.

NOTE: You may want to consider configuring external log rotation tools to automatically compress or delete old log files in the logging agent output storage to avoid overflowing.

Storage for the Application Data

Each PrizmDoc Server pod should use a separate Persistent Volume Claim for storing its data. Add a volumeClaimTemplate to the StatefulSet to let the Persistent Volume Provisioner provide the storage.

You will find an example volumeClaimTemplate for storing PrizmDoc Server data in the prizmdoc-server.yaml manifest included with the hello-prizmdoc-viewer-with-kubernetes sample.

See Server Sizing for recommendations on capacity and performance for the data storage.

Service Resource

The Service resource exposes multiple PrizmDoc Server pods as a single network service inside the cluster. Make sure to expose PrizmDoc public and internal (cluster) ports.

Ingress Resource

The Ingress Resource provides external access to public HTTP endpoints exposed by the PrizmDoc Server service.

In our hello-prizmdoc-viewer-with-kubernetes sample we configure the Ingress resource for PrizmDoc Server with an HTTP rewrite rule, so that Ingress can route requests starting with a /prizmdoc-server prefix to the PrizmDoc Server. In a production environment, consider using a separate hostname for PrizmDoc Server instead.

We recommend that you adjust the Ingress settings to allow uploading of large files. This minimal example assumes the use of the NGINX Ingress Controller, so it uses annotations supported by this controller.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prizmdoc-server
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "120"
    nginx.ingress.kubernetes.io/rewrite-target: $2
spec:
  rules:
    - http:
        paths:
          - backend:
              service:
                name: prizmdoc-server
                port:
                  name: public
            path: /prizmdoc-server(/|$)(.*)
            pathType: Prefix

PrizmDoc Cluster Manager

The PrizmDoc Cluster Manager is a Kubernetes add-on that automatically notifies PrizmDoc Server instances in the cluster about the availability of other PrizmDoc Server instances in this cluster. It takes care of the Configuration, Start-Up and Scaling steps described in the Clustering topic.

You will need the following resources for the PrizmDoc Cluster Manager:

  • ServiceAccount to be able to access the Kubernetes API, so the PrizmDoc Cluster Manager can watch for Endpoints
  • Role allowing watching endpoints in the namespace
  • RoleBinding to link the role with the service account
  • Deployment describes the desired state for the PrizmDoc Cluster Manager

We recommend that you define all those resources in a single YAML file.

You can find a complete resource definition for the Cluster Manager in the prizmdoc-cluster-manager.yaml manifest included with the hello-prizmdoc-viewer-with-kubernetes sample.

PrizmDoc Application Services

You will need the following resources for PrizmDoc Application Services (PAS):

We recommend that you define all those resources in a single YAML file.

ConfigMap for PAS Configuration Parameters

Use the ConfigMap resource to configure the PAS. See PAS Configuration for a detailed description of PAS configuration parameters.

We recommend you start with the prizmdoc-application-services-config ConfigMap included in the prizmdoc-application-services.yaml manifest of the hello-prizmdoc-viewer-with-kubernetes sample, and then modify or add the necessary parameters. If you need to change parameters which are not included in the sample configuration, you can create a PAS config file to get the full list of parameters with default values, and add the necessary ones to your ConfigMap.

NOTE: We recommend you keep some of the parameters, such as port numbers and directory paths, unchanged. See PAS Configuration for details.

Below is a shortened example of a ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prizmdoc-application-services-config
data:
  pcc.nix.yml: |-
    port: 3000
    pccServer.hostName: "prizmdoc-server.prizmdoc.svc.cluster.local"
    pccServer.port: 18681
    ...

Deployment for the PAS Application

Create a Deployment resource which is running the accusoft/prizmdoc-application-services Docker containers. Make sure you set required environment variables, expose public ports, and define the PAS Configuration mapping.

We recommend that you use equal resource requests and limits for your prizmdoc-application-services containers, and choose the values according to the Server Sizing guide.

Make sure to set up the readinessProbe, which tells whether the PAS container is ready to receive traffic through Kubernetes Services and the livenessProbe which tells whether the instance is healthy. Use the GET /health request for each of those probes. Kubernetes will automatically restart the instance if it becomes unhealthy, and block the traffic to the instance while it is restarting.

Below is a shortened example of a Deployment resource definition for the PrizmDoc Application Services.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prizmdoc-application-services
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: prizmdoc-application-services
  replicas: 1
  template:
    spec:
      containers:
        - name: prizmdoc-application-services
          env:
            - name: ACCEPT_EULA
              value: "YES"
          image: accusoft/prizmdoc-application-services
          ports:
            - name: public
              containerPort: 3000
              protocol: TCP
          volumeMounts:
            - name: prizmdoc-application-services-config
              mountPath: /config
              readOnly: true
            - name: prizmdoc-application-services-data
              mountPath: /data
      volumes:
        - name: prizmdoc-application-services-config
          configMap:
            name: prizmdoc-application-services-config
        - name: prizmdoc-application-services-data
          persistentVolumeClaim:
            claimName: prizmdoc-application-services-data

You can find a complete resource definition in the prizmdoc-application-services.yaml manifest included with the hello-prizmdoc-viewer-with-kubernetes sample.

Storage for the Application Logs

It is important to store PAS log files in a persistent storage so that you can control log file sizes and package log files for support if needed. It is possible to use one volume to keep log files from all PrizmDoc instances in your cluster. We recommend you to use a sidecar container with the logging agent with Fluent Bit as a lightweight logging agent.

You can use the prizmdoc-application-services-logging-agent in the prizmdoc-application-services.yaml manifest included with the hello-prizmdoc-viewer-with-kubernetes sample as an example of a logging sidecar container.

NOTE: You may want to consider configuring external log rotation tools to automatically compress or delete old log files in the logging agent output storage to avoid overflowing.

The PAS container uses standard output to report fatal errors. You can use kubectl logs --previous to retrieve logs from a previous instantiation of a container, see the kubectl logs documentation for more details. Additionally, you can consider to use a node logging agent to collect information about such errors.

Storage for the Application Data

Some storage entities of PrizmDoc Application Services can be configured to use a filesystem. In this case, the filesystem must be shared between all PAS replicas. On a single-node cluster, you can mount a Persistent Volume Claim (PVC) with ReadWriteOnce access mode. Otherwise, you need to use a PVC with ReadWriteMany access mode; usually Network File System (NFS) volume types are used in such case.

If you prefer to use S3 or Azure Blob for the storage, take a look at the Configuring Storage topic for further details.

Service Resource

The Service resource exposes multiple PrizmDoc Application Services pods as a single network service inside the cluster. You will need to expose the PAS public port.

Ingress Resource

The Ingress resource provides external access to public HTTP endpoints exposed by the PrizmDoc Application Services.

In our hello-prizmdoc-viewer-with-kubernetes sample we configure the Ingress resource for the PrizmDoc Application Services with an HTTP rewrite rule, so that Ingress can route requests starting with the /prizmdoc-application-services prefix to the PrizmDoc Application Services. In a production environment, consider using a separate hostname for the PrizmDoc Application Services instead.

We recommend that you adjust the Ingress settings to allow uploading of large files. This minimal example assumes the use of the NGINX Ingress Controller, so it uses annotations supported by this controller.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prizmdoc-application-services
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "120"
    nginx.ingress.kubernetes.io/rewrite-target: $2
spec:
  rules:
    - http:
        paths:
          - backend:
              service:
                name: prizmdoc-application-services
                port:
                  name: public
            path: /prizmdoc-application-services(/|$)(.*)
            pathType: Prefix

Checking PrizmDoc Kubernetes Cluster Health

For each kind of PrizmDoc resources, make sure to set up the readinessProbe, which tells whether a container is ready to receive traffic through Kubernetes Services and the livenessProbe which tells whether the instance is healthy. Kubernetes will automatically restart the instance if it becomes unhealthy, and block the traffic to the instance while it is restarting.

As long as probes are set up, pods are running and don't keep restarting, the cluster is healthy.

See Resources Used in PrizmDoc Deployment for details on setting up probes for each kind of PrizmDoc resources.

NOTE: PrizmDoc Health APIs for Server and PAS are accessible outside of the cluster. However, requests are routed randomly to a specific pod, and responses reflect the state of the instance running on that pod rather than the state of the whole cluster.

Autoscaling

Manifests that we provide in the hello-prizmdoc-viewer-with-kubernetes sample allow you to explicitly scale the cluster, using the kubectl scale command. The cluster manager component ensures that all instances in the cluster can properly communicate after the scaling (you don't need to deal with the Cluster Management API).

If you want to auto-scale the cluster depending on the load, you will need to configure a horizontal pod autoscaler for your Kubernetes deployment, such as HorizontalPodAutoscaler; you will also need to install a metrics-server.

For example, you can add the following configuration at the end of your prizmdoc-server.yaml file. Kubernetes will keep the average utilization of the pods CPU in the scaling target at 80%, but it will start no more than 10 prizmdoc-server pods.

---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: prizmdoc-server
  labels:
    app.kubernetes.io/name: prizmdoc-server
spec:
  maxReplicas: 10
  metrics:
    - resource:
        name: cpu
        target:
          averageUtilization: 80
          type: Utilization
      type: Resource
  scaleTargetRef:
    apiVersion: apps/v1
    kind: StatefulSet
    name: prizmdoc-server