Introduction
This section provides general guidance about deploying PrizmDoc Viewer 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
- Resources Used in PrizmDoc Viewer Deployment
- Checking PrizmDoc Viewer Kubernetes Cluster Health
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 Viewer Deployment for details on PrizmDoc Kubernetes cluster resources and how they can be adjusted for production use.
Resources Used in PrizmDoc Viewer Deployment
PrizmDoc Viewer 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: Some of the PrizmDoc Viewer features, such as "v2" Viewing Packages or "v3" Viewing Packages, require setting up 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 a future release in order to move towards eliminating server affinity.
PrizmDoc Server
You will need the following resources for the PrizmDoc Server:
- ConfigMap for PrizmDoc Server Central Configuration Parameters
- StatefulSet for the PrizmDoc Server Application
- Storage for the Application Logs
- Storage for the Application Data
- Service Resource to expose multiple PrizmDoc Server pods as a single network service inside the cluster
- Ingress Resource to provide external access to public HTTP endpoints exposed by the PrizmDoc Server service
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):
- ConfigMap for PAS Configuration Parameters
- Deployment for the PAS Application
- Storage for the Application Logs
- Storage for the Application Data
- Service Resource to expose multiple PrizmDoc Application Services pods as a single network service inside the cluster
- Ingress Resource to provide external access to public HTTP endpoints exposed by the PrizmDoc Application Services
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 Viewer Deployment for details on setting up probes for each kind of PrizmDoc Viewer 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.