Distributed James Server — Run with Kubernetes
Deploy Apache James on Kubernetes with Helm chart.
This chart bootstraps a James mail server on a Kubernetes cluster using the Helm package manager.
Before Starting
Before running the Helm chart, James should have particularly accessed to the following external products:
- Apache Cassandra
-
-
You can deploy Cassandra on Kubernetes with a Cassandra chart for testing purpose. However we would recommend running Cassandra on VirtualMachine for better stablilty.
-
- OpenSearch
-
-
OpenSearch community maintains Helm charts
-
- RabbitMQ
-
-
RabbitMQ Cluster Operator is a custom Kubernetes resource designed for the lifecycle (creation, upgrade, graceful shutdown) of a RabbitMQ cluster. Using Quickstart setup is enough for James deployment.
-
Configuration
Helm Configuration
The James helm package take parameters that will configure and determine the behavior of James. There are 2 configuration files:
-
One contains global, non-confidential, configuration:
values.yaml
-
The other one contains secrets:
secrets.yaml
. Values are encrypted with a key stored generated by sops.
You need to pass these 2 files as parameters to the James Helm package. To verify the coherence and avoid errors, the packages can validate the input.
This package contains a default values.yaml
file, but that you should override with proper configuration for your deployment (conf.yaml
).
The file secrets.sample.yaml
will show you the possible values of the secrets file. To generate the secrets.yaml
file,
you will need a plugin for Helm called helm-secrets.
Usually, you will save those configurations in different repositories, per deployment.
Have a look at values.md
and secrets.md
in our Chart documents to have more information on the configuration James is using.
You can find our Helm chart for James in here
James Configuration
The configuration files proper to James are stored in the Chart james/configs
folder. They are being stored in a ConfigMap
and then being mounted in the James pod at /root/conf path.
If you need to change a conf in James, this is where you need to look at.
For now all configuration files are the same for every deployment, except for mailetcontainer.xml
that has been excluded (see section below).
You can get the template mailetcontainer.xml
in our sample-configuration folder.
The However, the next release of Helm should allow to do something about that (hopefully). The helm package will be updated then. |
Deploy James Helm chart
Verify the configuration
We recommend to verify the configuration against the James Helm packages before deploying it. Usually it is best to have to position yourself in the repository having your deployment’s values and secrets, and linking this helm package to it, like this:
$ helm lint -f james/conf.yaml -f james/secrets.yaml /path/to/helm/james
You can also generate the whole templates with values (can be useful for debugging sometimes), by typing:
$ helm secrets templates -f james/conf.yaml -f james/secrets.yaml james /path/to/helm/james
From there, you should be able to interact with the Kubernetes cluster with kubectl
command.
A few useful commands:
kubectl get namespace # show namespaces on your cluster kubectl get pod -n mail-server # list pods running in mail-server namespace kubectl config set-context --current --namespace=mail-server # set the namespace mail-server as default one for next commands kubectl get configmaps # list configmaps depoyed on the namespace kubectl get secrets # list secrets deployed on the namespace kubectl get service # list services deployed in the namespace kubectl get nodes -o wide # list nodes related to the namespace kubectl describe pod my-pod # get a detailed description of my-pod (similar for other objects) kubectl scale --replicas=4 deployment james # scale up (or down) james to 4 pods kubectl rollout restart deployment james # force a rollout restart of your pods related to james kubectl logs my-pod -f --tail 100 # show and follow logs of a pod from the last 100 lines kubectl logs -f -l app=james --tail 100 # show and follow the combined logs of all james pods from the last 100 lines kubectl port-forward pod/my-pod 3000:3000 # allow you to access and interact with internal port 3000 of my-pod from localhost
Usually you have a namespace per deployment. Always target your deployments on the corresponding namespace, by either adding the flag -n mail-server on your kubectl and helm commands, or by setting your namespace by default (see in the above commands).
Deploy James Chart
Before doing a real deployment, you need to check that you have at least all necessary values for James to start and run smoothly on your environment. You can check the checklist.md
in our document folder for this.
Run the command when you think you are good to go:
$ helm secrets install james james/ -f james/values.yaml -f james/secrets.yaml
You can also wait for the deployment to be complete by adding a --wait flag, that is based on the readiness probe located inside the James pod.
However sometimes things might not always go well at the start of James. Usually it is good to look at the logs. If it goes without issues until you start to see some successful health check logs, then you are likely good.
Upgrade Chart version
If you want to deploy a new version of a installed package, use helm secrets upgrade:
$ helm secrets upgrade -f james/conf.yaml -f james/secrets.yaml james /path/to/helm/james
What Helm does is that it compares all the generated YAML files with those on the server. And it updates only those that changed. There are however some limitations:
-
pods in errors are not recreated during an upgrade. It allows to check the logs first. However, if you delete the pod by hand, it will be recreated from the last definition.
-
Some artifacts, such as jobs and stateful sets, have immutable properties. So, some upgrades may fail. Deleting by hand the element is sometimes a solution before doing the upgrade.
Install helm-diff plugin to display the changed configurations before run upgrade. |
$ helm secrets diff upgrade -f james/conf.yaml -f james/secrets.yaml james /path/to/helm/james