Kubernetes setup¶
Prequisites¶
Structure¶
There’s chosen to have a double NGINX stack for Mailu, this way the main ingress can still be used to access other websites/domains on your cluster. This is the current structure:
NGINX Ingress controller
: Listens to the nodes ports 80 & 443. We have chosen to have a double NGINX stack for Mailu.Cert manager
: Creates automatic Lets Encrypt certificates based on anIngress
-objects domain name.Mailu NGINX Front daemonset
: This daemonset runs in parallel with the Nginx Ingress Controller and only listens on all E-mail specific ports (25, 110, 143, 587,…). It also listens on 80 and delegates the various http endpoints to the correct services.Mailu components
: All Mailu components (imap, smtp, security, webmail,…) are split into separate files to make them more handy to use, you can find theYAML
files in this directory
What you need¶
A working Kubernetes cluster (tested with 1.10.5)
A working cert-manager installation
A working nginx-ingress controller needed for the lets-encrypt certificates. You can find those files in the
nginx
subfolder. Other ingress controllers that support cert-manager (e.g. traefik) should also work.
Cert manager¶
The Cert-manager
is quite easy to deploy using Helm when reading the
docs. After booting the Cert-manager
you’ll need a
ClusterIssuer
which takes care of all required certificates through
Ingress
items. We chose to provide a clusterIssuer
so you can provide SSL certificates
for other namespaces (different websites/services), if you don’t need this option, you can easily change this by
changing clusterIssuer
to Issuer
and adding the namespace: mailu-mailserver
to the metadata.
An example of a production and a staging clusterIssuer
:
# This clusterIssuer example uses the staging environment for testing first
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-stage
spec:
acme:
email: something@example.com
http01: {}
privateKeySecretRef:
name: letsencrypt-stage
server: https://acme-staging-v02.api.letsencrypt.org/directory
# This clusterIssuer example uses the production environment
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: something@example.com
http01: {}
privateKeySecretRef:
name: letsencrypt-prod
server: https://acme-v02.api.letsencrypt.org/directory
IMPORTANT: ingress.yaml
uses the letsencrypt-stage
clusterIssuer
. If you are ready for production,
change this field in ingress.yaml
file to letsencrypt-prod
or whatever name you chose for the production.
If you choose for Issuer
instead of clusterIssuer
you also need to change the annotation to certmanager.k8s.io/issuer
instead of certmanager.k8s.io/cluster-issuer
Deploying Mailu¶
All manifests can be found in the mailu
subdirectory. All commands
below need to be run from this subdirectory
Personalization¶
All services run in the same namespace, currently
mailu-mailserver
. So if you want to use a different one, change thenamespace
value in every fileCheck the
storage-class
field in thepvc.yaml
file, you can also change the sizes to your liking. Note that you needRWX
(read-write-many) andRWO
(read-write-once) storageclasses.Check the
configmap.yaml
and adapt it to your needs. Be sure to check the kubernetes DNS values at the end (if you use a different namespace)Check the
ingress.yaml
file and change it to the domain you want (this is for the kubernetes ingress controller to handle the admin, webmail, webdav and auth connections)
Installation¶
Boot the Mailu components¶
To start Mailu, run the following commands from the docs/kubernetes/mailu
directory
kubectl create -f rbac.yaml
kubectl create -f configmap.yaml
kubectl create -f pvc.yaml
kubectl create -f redis.yaml
kubectl create -f front.yaml
kubectl create -f webmail.yaml
kubectl create -f imap.yaml
kubectl create -f security.yaml
kubectl create -f smtp.yaml
kubectl create -f fetchmail.yaml
kubectl create -f admin.yaml
kubectl create -f webdav.yaml
kubectl create -f ingress.yaml
Create the first admin account¶
When the cluster is online you need to create you master user to access https://mail.example.com/admin
You can create it now manually, or have the system create it automatically.
If you want the system to create the admin user account automatically, see Admin account - automatic creation
about the environment variables needed (INITIAL_ADMIN_*
).
Also, important, taking into consideration that a pod in Kubernetes can be stopped/rescheduled at
any time, you should set INITIAL_ADMIN_MODE
to either update
or ifmissing
- depending on what you
want to happen to its password.
To create the admin user account manually, enter the main admin
pod:
kubectl -n mailu-mailserver get po
kubectl -n mailu-mailserver exec -it mailu-admin-.... /bin/sh
And in the pod run the following command. The command uses following entries:
flask mailu admin root example.com password
admin
Make it an admin userroot
The first part of the e-mail address (ROOT@example.com)example.com
the domain appendixpassword
the chosen password for the user
Now you should be able to login on the mail account: https://mail.example.com/admin
Adaptations¶
Dovecot¶
If you are using Dovecot on a shared file system (Glusterfs, NFS,…), you need to create a special override otherwise a lot of indexing errors will occur on your Dovecot pod.
I also higher the number of max connections per IP. Now it’s limited to 10.
Enter the dovecot pod:
kubectl -n mailu-mailserver get po
kubectl -n mailu-mailserver exec -it mailu-imap-.... /bin/sh
Create the file overrides/dovecot.conf
vi /overrides/dovecot.conf
And enter following contents:
mail_nfs_index = yes
mail_nfs_storage = yes
mail_fsync = always
mmap_disable = yes
mail_max_userip_connections=100
Save and close the file and delete the imap pod to get it recreated.
kubectl -n mailu-mailserver delete po/mailu-imap-....
Wait for the pod to recreate and you’re online! Happy mailing!
Imap login fix¶
If it seems you’re not able to login using IMAP on your Mailu accounts, check the logs of the imap container to see whether it’s a permissions problem on the database. This problem can be easily fixed by running following commands:
kubectl -n mailu-mailserver exec -it mailu-imap-... /bin/sh
chmod 777 /data/main.db
If the login problem still persists, or more specific, happens now and then and you see some Auth problems on your webmail or mail client, try following steps:
Add
auth_debug=yes
to the/overrides/dovecot.conf
file and delete the pod in order to start a new one, which loads the configurationDepending on your network configuration you could still see some
allow_nets check failed
results in the logs. This means that the IP is not allowed a loginIf this is happening your network plugin has troubles with the Nginx Ingress Controller using the
hostNetwork: true
option. Known cases: Flannel and Calico.You should uncomment
POD_ADDRESS_RANGE
in theconfigmap.yaml
file and add the IP range of your pod network bridge (the range that sadly has failed theallowed_nets
test)Delete the Admin pod and wait for it to restart
kubectl -n mailu-mailserver get po
kubectl -n mailu-mailserver delete po/mailu-admin...
Happy mailing!