|
|
.. _kubernetes:
|
|
|
|
|
|
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 an ``Ingress``-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 the ``YAML`` 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``:
|
|
|
|
|
|
.. code:: yaml
|
|
|
|
|
|
# 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
|
|
|
|
|
|
.. code:: yaml
|
|
|
|
|
|
# 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 the ``namespace`` value in **every** file
|
|
|
- Check the ``storage-class`` field in the ``pvc.yaml`` file, you can also change the sizes to your liking. Note that you need ``RWX`` (read-write-many) and ``RWO`` (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
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
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 :ref:`admin_account`
|
|
|
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:
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
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:
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
flask mailu admin root example.com password
|
|
|
|
|
|
- ``admin`` Make it an admin user
|
|
|
- ``root`` The first part of the e-mail address (ROOT@example.com)
|
|
|
- ``example.com`` the domain appendix
|
|
|
- ``password`` 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:
|
|
|
|
|
|
.. code:: bash
|
|
|
|
|
|
kubectl -n mailu-mailserver get po
|
|
|
kubectl -n mailu-mailserver exec -it mailu-imap-.... /bin/sh
|
|
|
|
|
|
Create the file ``overrides/dovecot.conf``
|
|
|
|
|
|
.. code:: bash
|
|
|
|
|
|
vi /overrides/dovecot.conf
|
|
|
|
|
|
And enter following contents:
|
|
|
|
|
|
.. code:: bash
|
|
|
|
|
|
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.
|
|
|
|
|
|
.. code:: bash
|
|
|
|
|
|
kubectl -n mailu-mailserver delete po/mailu-imap-....
|
|
|
|
|
|
Wait for the pod to recreate and you're online!
|
|
|
Happy mailing!
|
|
|
|
|
|
.. _here: https://github.com/hacor/Mailu/blob/master/core/postfix/conf/main.cf#L35
|
|
|
.. _cert-manager: https://github.com/jetstack/cert-manager
|
|
|
.. _docs: https://cert-manager.io/docs/installation/kubernetes/#installing-with-helm
|
|
|
|
|
|
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:
|
|
|
|
|
|
.. code:: bash
|
|
|
|
|
|
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 configuration
|
|
|
- Depending 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 login
|
|
|
- If 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 the ``configmap.yaml`` file and add the IP range of your pod network bridge (the range that sadly has failed the ``allowed_nets`` test)
|
|
|
- Delete the Admin pod and wait for it to restart
|
|
|
|
|
|
.. code:: bash
|
|
|
|
|
|
kubectl -n mailu-mailserver get po
|
|
|
kubectl -n mailu-mailserver delete po/mailu-admin...
|
|
|
|
|
|
Happy mailing!
|