How to build and deploy Containerized MID Servers in Kubernetes using StatefulSetsSummaryIn Kubernetes, Containerized MID Server runs on a pod. If the pod restarts or if it is recreated due to a failure, all changes to the pod file system are lost because pod storage is ephemeral. MID Server is a stateful application. Each MID server has a unique name and sys_id stored in config.xml. It also has its own keypair in the keystore and other working data in the work folder. Such data need to be stored on a persistent storage, so that MID can continue to work on a new pod. Kubernetes Deployment and Kubernetes StatefulSet are two main workload resources for managing containerized applications on Kubernetes. Deployments are useful for managing stateless applications, while StatefulSets are useful for managing stateful applications. We start to support StatefulSet since Utah release, but only for Containerized Linux MID Servers. We do not recommend using Deployment workload resources for MID Servers. Note: It is important to keep data on the persistent storage secure. Someone who has access to it can compromise the MID Servers. ReleaseThis KB provides a workaround for the customers who are on San Diego or Tokyo and also for the customers who want to deploy Containerized Windows MID Servers.InstructionsBuild image Prerequisites: Make sure that you have Docker Engine or Docker Desktop installed on your machine. For Windows, you need Windows Server 2019. Download the MID docker recipe from Utah Patch4 or later or use the recipes attached to this KB.Extract the recipe to a folderOn the instance, open MID Server download page, uncheck the "Download MID Server as ZIP archive" check box and download the MID installation ZIP file.Verify the ZIP file signature: jarsigner -verify -verbose -certs -strict <zip-file> Note: The jarsigner tool is available with JDK, it is not available with JRE distribution.Move the MID installation ZIP file to the asset subfolder where the recipe is extracted.Change the current directory to the recipe folderRun this command to build the image: docker build . --build-arg MID_INSTALLATION_FILE=<zip_file> --build-arg MID_SIGNATURE_VERIFICATION=false --tag <image_tag> Note: <zip_file> is the file name of the downloaded MID installation ZIP file without path, for example mid.sandiego-12-22-2021_01-31-2023_0300.linux.x86-64.zip. We recommend having the mid build timestamp in the <image_tag> to identify which mid version the image has, for example mid:sandiego-12-22-2021_01-31-2023_0300 Push the image to a remote registry where it can be pulled from your Kubernetes cluster. Deploy MID Servers in Kubernetes via StatefulSets Prerequisites: You need to have access to a Kubernetes cluster. The procedure below is tested on AKS using Azure CLI. If you want to deploy Windows MID, you will need a cluster with Windows Server 2019 nodes. Choose one of the StatefulSet deployment templates in the attachment and make a copy of it.Modify the yaml file as follows: - Replace <YOUR_SERVICE_NAME> with a K8s service name, i.e. snc-mid-server - Replace <YOUR_NAMESPACE> with a K8s namespace name, i.e. default - Replace <YOUR_STATEFULSET_NAME> with a statefulset name, i.e. statefulset-linux-mid or statefulset-windows-mid - Replace <YOUR_VOLUME_CLAIM_NAME> with a claim template name, i.e. snc-mid-server - Replace <YOUR_STORAGE_CLASS_NAME> with your storage class name, i.e. managed-csi (Tip: run 'kubectl get storageclass' to get a list of available storage classes) - Replace <YOUR_IMAGE_URL> with the url pointing to the image in the remote registry, i.e. midcontainerregistry.azurecr.io/mid:tokyo-07-08-2022_04-11-2023_0200 - Replace <YOUR_INSTANCE_URL> with the instance URL // If the image is in a private registry - Replace <YOUR_REGISTRY_SECRET> with your registry secret name, i.e. midcontainerregistry-secret // If using basic auth - Replace <YOUR_MID_INSTANCE_USER_NAME>" with the mid instance user name, i.e. mid_server_basic_auth - Replace <MID_SECRET_MOUNT_PATH> with the path where the mid secret volume is mounted, i.e. /etc/secrets (linux) or c:\snc_mid_server\secrets (windows) - Replace <YOUR_MID_SECRET_PROPERTIES_FILENAME> with the mid secret properties file name, i.e. mid-secrets.properties - Replace <YOUR_MID_SECRET_NAME> with the mid secret name, i.e. mid-secret // If using mutual auth - Replace <MID_MUTUAL_AUTH_SECRET_MOUNT_PATH> with the path where the mid mutual auth secret volume is mounted, i.e. /etc/secrets (linux) or c:\snc_mid_server\secrets (windows) - Replace <YOUR_MID_MUTUAL_AUTH_PEM_FILENAME> with the mutual auth PEM file, i.e. mid-mutual-auth.pem - Replace <YOUR_MID_MUTUAL_AUTH_SECRET_NAME> with the mid mutual auth secret name, i.e. mid-mutual-auth-secret - Verify all other parameters and make all changes as needed, for example config parameters, replicas number, memory, cpu limits/requests Run the command kubectl apply -f <yaml_file> Manual scale kubectl scale --replicas=<number> statefulset <YOUR_STATEFULSET_NAME> Delete StatefulSet kubectl delete statefulset <YOUR_STATEFULSET_NAME> * Note: after a statefulset is deleted, its persistent volume claim and persistent volume stay and can be reused. You need to explicitly delete them if needed. Related LinksTroubleshooting Note: See https://kubernetes.io/docs/reference/kubectl/cheatsheet/ for how to use kubectl commands Tip: To avoid adding the --namespace flag to every command, you can change the current namespace by running the command below: kubectl config set-context --current --namespace=<NAMESPACE> 1. Check if the statefulset, pvc and pvc is created kubectl get statefulsets kubectl describe statefulset <STATEFULSET_NAME> kubeclt get pvc kubeclt get pv 2. Check if new pods are created and running kubectl get pods kubectl logs <POD_NAME> [-f] kubectl describe pod <POD_NAME> 3. Copy files between localhost and pods kubectl cp <some-namespace>/<some-pod>:/tmp/foo /tmp/bar kubectl cp /tmp/foo <some-namespace>/<some-pod>:/tmp/bar Example: Copy the agent logs folder from pod in the default namespace to localhost Linux: mkdir agent_logs kubectl cp <POD_NAME>:/opt/snc_mid_server/agent/logs ./agent_logs Windows: mkdir agent_logs kubectl cp <POD_NAME>:c:\snc_mid_server\agent\logs .\agent_logs 4. Log on the MID container Linux: kubectl exec -it <POD_NAME> -- /bin/bash Windows: kubectl exec -it <POD_NAME> -- powershell