Mailu: Kubernetes Support?

Created on 15 Jan 2017  路  4Comments  路  Source: Mailu/Mailu

This is a great project which seems ideal for a deployment on Kubernetes. Has anyone tried to do so?

Currently it seems not possible to connect the different containers to each other. For example, the postfix container wants to reach the dovecot container on imap/2102, but the "hostname" imap is not present in a Kubernetes pod.

It would be easier, if mailu was to provide some additional environment variables for the internal endpoints. As hostname resolution is always problematic a distributed cluster environment - is there any chance that this project implements the needed environment variables?

Most helpful comment

The following Kubernetes deployment config for mailu is working:

apiVerapiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:    
  - name: redis
    port: 6379
    protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: antispam
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:    
  - name: antispam
    port: 11333
    protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: antivirus
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:    
  - name: antivirus
    port: 3310
    protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: imap
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:
  - name: imap-auth
    port: 2102
    protocol: TCP
  - name: imap-transport
    port: 2525
    protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: mailu
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:
  - name: http
    port: 80
    protocol: TCP
  - name: imap-default
    port: 143
    protocol: TCP
  - name: imap-ssl
    port: 993
    protocol: TCP
  - name: sieve
    port: 4190
    protocol: TCP
  - name: smtp
    port: 25
    protocol: TCP
  - name: smtp-ssl
    port: 465
    protocol: TCP
  - name: smtp-starttls
    port: 587
    protocol: TCP

---

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mailu
  namespace: default
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: mailu
        role: mail
        tier: backend
    spec:
      containers:
      - name: admin
        image: mailu/admin:stable
        imagePullPolicy: Always
        env:
          - name  : DOMAIN
            value : example.com
          - name  : HOSTNAME
            value : mail.example.com
          - name  : POSTMASTER
            value : admin
          - name  : SECRET_KEY
            value : ChangeMeChangeMe
          - name  : DEBUG
            value : "True"
        volumeMounts:
          - name: maildata
            mountPath: /data
          - name: dkim
            mountPath: /dkim
          - name: certs
            mountPath: /certs
            readOnly: true
#          - name: docker
#            mountPath: /var/run/docker.sock
#            readOnly: true
        ports:
          - name: http
            containerPort: 80
            protocol: TCP
      - name: redis
        image: redis:latest
        imagePullPolicy: Always
        volumeMounts:
          - mountPath: /data
            name: redisdata
        ports:
          - containerPort: 6379
            name: redis
            protocol: TCP
      - name: imap
        image: mailu/dovecot:stable
        imagePullPolicy: Always
        env:
          - name  : DOMAIN
            value : example.com
          - name  : HOSTNAME
            value : mail.example.com
          - name  : POSTMASTER
            value : admin
        volumeMounts:
          - mountPath: /data
            name: maildata
          - mountPath: /mail
            name: mailstate
          - mountPath: /overrides
            name: overrides
          - mountPath: /certs
            name: certs
            readOnly: true
        ports:
          - containerPort: 2102
            name: imap-auth
            protocol: TCP
          - containerPort: 2525
            name: imap-transport
            protocol: TCP       
          - containerPort: 143
            name: imap-default
            protocol: TCP          
          - containerPort: 993
            name: imap-ssl
            protocol: TCP
          - containerPort: 4190
            name: sieve
            protocol: TCP
      - name: smtp
        image: mailu/postfix:stable
        imagePullPolicy: Always
        env:
          - name  : DOMAIN
            value : example.com
          - name  : HOSTNAME
            value : mail.example.com
          - name  : MESSAGE_SIZE_LIMIT
            value : "50000000"
          - name  : RELAYHOST
            value : ""
        volumeMounts:
          - mountPath: /data
            name: maildata
          - mountPath: /overrides
            name: overrides
          - mountPath: /certs
            name: certs
            readOnly: true
        ports:
          - name: smtp
            containerPort: 25
            protocol: TCP
          - name: smtp-ssl
            containerPort: 465
            protocol: TCP
          - name: smtp-starttls
            containerPort: 587
            protocol: TCP
      - name: milter
        image: mailu/rmilter:stable
        imagePullPolicy: Always
        ports:
          - name: milter
            containerPort: 9900
            protocol: TCP
        volumeMounts:
          - name: maildata
            mountPath: /data
          - name: dkim
            mountPath: /dkim
          - name: overrides
            mountPath: /overrides
          - name: certs
            mountPath: /certs
            readOnly: true
      - name: antispam
        image: mailu/rspamd:stable
        imagePullPolicy: Always
        ports:
          - name: antispam
            containerPort: 11333
            protocol: TCP          
        volumeMounts:
          - name: filter
            mountPath: /var/lib/rspamd
      - name: antivirus
        image: mailu/clamav:stable
        imagePullPolicy: Always
        ports:
          - name: antivirus
            containerPort: 3310
            protocol: TCP
        volumeMounts:
          - name: filter
            mountPath: /data
      volumes:
        - name: redisdata
          emptyDir: {}        
        - name: maildata
          emptyDir: {}
        - name: mailstate
          emptyDir: {}
        - name: overrides
          emptyDir: {}
        - name: dkim
          emptyDir: {}       
        - name: filter
          emptyDir: {}   
        - name: certs
          secret:
            items:
              - key: tls.crt
                path: cert.pem
              - key: tls.key
                path: key.pem
            secretName: mail-example-com-letsencrypt-ssl
#        - name: docker
#          hostPath:
#            path: /var/run/docker.sock
      imagePullSecrets:
        - name: myregistrykey

Note the extra services at the top which are needed to solve the initial problem of finding the correct endpoints. In order to reach the mailu container externally, I put a Kubernetes ingress in front of it (not shown here), that's why the mailu nginx container has been omitted.

Only remaining problem is the container mount of /var/run/docker.sock, which does not work with Kubernetes, but that only affects the status page in the admin interface. Any comments on this topic are welcome.

I also noted that the memory requirement is quite large (approx 1.2 GB) which is mostly due to the modular approach of putting every service into a separate docker image.

All 4 comments

There is. How would you do it properly to work both with Kubernete and in a standard environment?

Thanks for the quick answer. Actually, I was now able to solve this within Kubernetes intself by adding additional services for imap and milter. I will post my config here, once it is working smoothly.

The following Kubernetes deployment config for mailu is working:

apiVerapiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:    
  - name: redis
    port: 6379
    protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: antispam
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:    
  - name: antispam
    port: 11333
    protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: antivirus
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:    
  - name: antivirus
    port: 3310
    protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: imap
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:
  - name: imap-auth
    port: 2102
    protocol: TCP
  - name: imap-transport
    port: 2525
    protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: mailu
  namespace: default
  labels:
    app: mailu
    role: mail
    tier: backend
spec:
  selector:
    app: mailu
    role: mail
    tier: backend
  ports:
  - name: http
    port: 80
    protocol: TCP
  - name: imap-default
    port: 143
    protocol: TCP
  - name: imap-ssl
    port: 993
    protocol: TCP
  - name: sieve
    port: 4190
    protocol: TCP
  - name: smtp
    port: 25
    protocol: TCP
  - name: smtp-ssl
    port: 465
    protocol: TCP
  - name: smtp-starttls
    port: 587
    protocol: TCP

---

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: mailu
  namespace: default
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: mailu
        role: mail
        tier: backend
    spec:
      containers:
      - name: admin
        image: mailu/admin:stable
        imagePullPolicy: Always
        env:
          - name  : DOMAIN
            value : example.com
          - name  : HOSTNAME
            value : mail.example.com
          - name  : POSTMASTER
            value : admin
          - name  : SECRET_KEY
            value : ChangeMeChangeMe
          - name  : DEBUG
            value : "True"
        volumeMounts:
          - name: maildata
            mountPath: /data
          - name: dkim
            mountPath: /dkim
          - name: certs
            mountPath: /certs
            readOnly: true
#          - name: docker
#            mountPath: /var/run/docker.sock
#            readOnly: true
        ports:
          - name: http
            containerPort: 80
            protocol: TCP
      - name: redis
        image: redis:latest
        imagePullPolicy: Always
        volumeMounts:
          - mountPath: /data
            name: redisdata
        ports:
          - containerPort: 6379
            name: redis
            protocol: TCP
      - name: imap
        image: mailu/dovecot:stable
        imagePullPolicy: Always
        env:
          - name  : DOMAIN
            value : example.com
          - name  : HOSTNAME
            value : mail.example.com
          - name  : POSTMASTER
            value : admin
        volumeMounts:
          - mountPath: /data
            name: maildata
          - mountPath: /mail
            name: mailstate
          - mountPath: /overrides
            name: overrides
          - mountPath: /certs
            name: certs
            readOnly: true
        ports:
          - containerPort: 2102
            name: imap-auth
            protocol: TCP
          - containerPort: 2525
            name: imap-transport
            protocol: TCP       
          - containerPort: 143
            name: imap-default
            protocol: TCP          
          - containerPort: 993
            name: imap-ssl
            protocol: TCP
          - containerPort: 4190
            name: sieve
            protocol: TCP
      - name: smtp
        image: mailu/postfix:stable
        imagePullPolicy: Always
        env:
          - name  : DOMAIN
            value : example.com
          - name  : HOSTNAME
            value : mail.example.com
          - name  : MESSAGE_SIZE_LIMIT
            value : "50000000"
          - name  : RELAYHOST
            value : ""
        volumeMounts:
          - mountPath: /data
            name: maildata
          - mountPath: /overrides
            name: overrides
          - mountPath: /certs
            name: certs
            readOnly: true
        ports:
          - name: smtp
            containerPort: 25
            protocol: TCP
          - name: smtp-ssl
            containerPort: 465
            protocol: TCP
          - name: smtp-starttls
            containerPort: 587
            protocol: TCP
      - name: milter
        image: mailu/rmilter:stable
        imagePullPolicy: Always
        ports:
          - name: milter
            containerPort: 9900
            protocol: TCP
        volumeMounts:
          - name: maildata
            mountPath: /data
          - name: dkim
            mountPath: /dkim
          - name: overrides
            mountPath: /overrides
          - name: certs
            mountPath: /certs
            readOnly: true
      - name: antispam
        image: mailu/rspamd:stable
        imagePullPolicy: Always
        ports:
          - name: antispam
            containerPort: 11333
            protocol: TCP          
        volumeMounts:
          - name: filter
            mountPath: /var/lib/rspamd
      - name: antivirus
        image: mailu/clamav:stable
        imagePullPolicy: Always
        ports:
          - name: antivirus
            containerPort: 3310
            protocol: TCP
        volumeMounts:
          - name: filter
            mountPath: /data
      volumes:
        - name: redisdata
          emptyDir: {}        
        - name: maildata
          emptyDir: {}
        - name: mailstate
          emptyDir: {}
        - name: overrides
          emptyDir: {}
        - name: dkim
          emptyDir: {}       
        - name: filter
          emptyDir: {}   
        - name: certs
          secret:
            items:
              - key: tls.crt
                path: cert.pem
              - key: tls.key
                path: key.pem
            secretName: mail-example-com-letsencrypt-ssl
#        - name: docker
#          hostPath:
#            path: /var/run/docker.sock
      imagePullSecrets:
        - name: myregistrykey

Note the extra services at the top which are needed to solve the initial problem of finding the correct endpoints. In order to reach the mailu container externally, I put a Kubernetes ingress in front of it (not shown here), that's why the mailu nginx container has been omitted.

Only remaining problem is the container mount of /var/run/docker.sock, which does not work with Kubernetes, but that only affects the status page in the admin interface. Any comments on this topic are welcome.

I also noted that the memory requirement is quite large (approx 1.2 GB) which is mostly due to the modular approach of putting every service into a separate docker image.

I think the main reason for the large memory requirement is Clamav loading all the rules to memory. I haven't found a workaround yet. I juste pasted your configuration to Wiki, thank you so much for sharing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SJS28092018 picture SJS28092018  路  3Comments

elektro-wolle picture elektro-wolle  路  3Comments

v1ru535 picture v1ru535  路  4Comments

micw picture micw  路  4Comments

muhlemmer picture muhlemmer  路  4Comments