PrizmDoc® v14.2 Release - Updated
PrizmDoc / Administrator Guide / Kubernetes / Deployment to Kubernetes Guidance
In This Topic
    Deployment to Kubernetes Guidance
    In This Topic

    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