mirror of
https://github.com/Mailu/Mailu.git
synced 2025-01-26 03:52:50 +02:00
Merge #1158
1158: Use nginx for kubernetes ingress r=kaiyou a=micw ## What type of PR? enhancement ## What does this PR do? Currently, kubernetes uses a complex ingress setting which is not portable across different ingress controllers. This PR simplifies the ingress and delegates everythins special to Mailu to the front container, ### Related issue(s) - closes #1121 - closes #1117 - closes #1021 - closes #1045 ## Prerequistes - [x] In case of feature or enhancement: documentation updated accordingly - [x] Unless it's docs or a minor change: add [changelog] Co-authored-by: Michael Wyraz <michael@wyraz.de>
This commit is contained in:
commit
20e00ac0c4
@ -34,8 +34,6 @@ http {
|
|||||||
'' $scheme;
|
'' $scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Disable the main http server when on kubernetes (port 80 and 443)
|
|
||||||
{% if KUBERNETES_INGRESS != 'true' %}
|
|
||||||
# Main HTTP server
|
# Main HTTP server
|
||||||
server {
|
server {
|
||||||
# Favicon stuff
|
# Favicon stuff
|
||||||
@ -54,8 +52,8 @@ http {
|
|||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
|
|
||||||
# Only enable HTTPS if TLS is enabled with no error
|
# Only enable HTTPS if TLS is enabled with no error and not on kubernetes
|
||||||
{% if TLS and not TLS_ERROR %}
|
{% if KUBERNETES_INGRESS != 'true' and TLS and not TLS_ERROR %}
|
||||||
listen 443 ssl http2;
|
listen 443 ssl http2;
|
||||||
listen [::]:443 ssl http2;
|
listen [::]:443 ssl http2;
|
||||||
|
|
||||||
@ -76,15 +74,15 @@ http {
|
|||||||
add_header X-XSS-Protection '1; mode=block';
|
add_header X-XSS-Protection '1; mode=block';
|
||||||
add_header Referrer-Policy 'same-origin';
|
add_header Referrer-Policy 'same-origin';
|
||||||
|
|
||||||
# In any case, enable the proxy for certbot if the flavor is letsencrypt
|
# In any case, enable the proxy for certbot if the flavor is letsencrypt and not on kubernetes
|
||||||
{% if TLS_FLAVOR in [ 'letsencrypt', 'mail-letsencrypt' ] %}
|
{% if KUBERNETES_INGRESS != 'true' and TLS_FLAVOR in [ 'letsencrypt', 'mail-letsencrypt' ] %}
|
||||||
location ^~ /.well-known/acme-challenge/ {
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
proxy_pass http://127.0.0.1:8008;
|
proxy_pass http://127.0.0.1:8008;
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# If TLS is failing, prevent access to anything except certbot
|
# If TLS is failing, prevent access to anything except certbot
|
||||||
{% if TLS_ERROR and not TLS_FLAVOR == "mail" %}
|
{% if KUBERNETES_INGRESS != 'true' and TLS_ERROR and not TLS_FLAVOR == "mail" %}
|
||||||
location / {
|
location / {
|
||||||
return 403;
|
return 403;
|
||||||
}
|
}
|
||||||
@ -167,7 +165,6 @@ http {
|
|||||||
return 204;
|
return 204;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# Forwarding authentication server
|
# Forwarding authentication server
|
||||||
server {
|
server {
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
apiVersion: extensions/v1beta1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: mailu-admin-ingress
|
|
||||||
namespace: mailu-mailserver
|
|
||||||
annotations:
|
|
||||||
kubernetes.io/tls-acme: "true"
|
|
||||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
|
||||||
certmanager.k8s.io/cluster-issuer: letsencrypt-stage
|
|
||||||
ingress.kubernetes.io/permanent-redirect: "https://mail.example.com/admin/ui/"
|
|
||||||
ingress.kubernetes.io/follow-redirects: "true"
|
|
||||||
labels:
|
|
||||||
app: mailu
|
|
||||||
role: mail
|
|
||||||
tier: backend
|
|
||||||
spec:
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- "mail.example.com"
|
|
||||||
secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt
|
|
||||||
rules:
|
|
||||||
- host: "mail.example.com"
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: "/admin"
|
|
||||||
backend:
|
|
||||||
serviceName: admin
|
|
||||||
servicePort: 80
|
|
||||||
---
|
|
||||||
apiVersion: extensions/v1beta1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: mailu-admin-ui-ingress
|
|
||||||
namespace: mailu-mailserver
|
|
||||||
annotations:
|
|
||||||
kubernetes.io/tls-acme: "true"
|
|
||||||
certmanager.k8s.io/cluster-issuer: letsencrypt-stage
|
|
||||||
ingress.kubernetes.io/rewrite-target: "/ui"
|
|
||||||
ingress.kubernetes.io/configuration-snippet: |
|
|
||||||
proxy_set_header X-Forwarded-Prefix /admin;
|
|
||||||
labels:
|
|
||||||
app: mailu
|
|
||||||
role: mail
|
|
||||||
tier: backend
|
|
||||||
spec:
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- "mail.example.com"
|
|
||||||
secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt
|
|
||||||
rules:
|
|
||||||
- host: "mail.example.com"
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: "/admin/ui"
|
|
||||||
backend:
|
|
||||||
serviceName: admin
|
|
||||||
servicePort: 80
|
|
||||||
---
|
|
||||||
apiVersion: extensions/v1beta1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: mailu-admin-static-ingress
|
|
||||||
namespace: mailu-mailserver
|
|
||||||
annotations:
|
|
||||||
kubernetes.io/tls-acme: "true"
|
|
||||||
certmanager.k8s.io/cluster-issuer: letsencrypt-stage
|
|
||||||
ingress.kubernetes.io/rewrite-target: "/static"
|
|
||||||
ingress.kubernetes.io/configuration-snippet: |
|
|
||||||
proxy_set_header X-Forwarded-Prefix /admin;
|
|
||||||
labels:
|
|
||||||
app: mailu
|
|
||||||
role: mail
|
|
||||||
tier: backend
|
|
||||||
spec:
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- "mail.example.com"
|
|
||||||
secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt
|
|
||||||
rules:
|
|
||||||
- host: "mail.example.com"
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: "/admin/static"
|
|
||||||
backend:
|
|
||||||
serviceName: admin
|
|
||||||
servicePort: 80
|
|
@ -27,7 +27,6 @@ spec:
|
|||||||
- matchExpressions:
|
- matchExpressions:
|
||||||
- key: node-role.kubernetes.io/node
|
- key: node-role.kubernetes.io/node
|
||||||
operator: Exists
|
operator: Exists
|
||||||
hostNetwork: true
|
|
||||||
nodeSelector:
|
nodeSelector:
|
||||||
node-role.kubernetes.io/node: ""
|
node-role.kubernetes.io/node: ""
|
||||||
dnsPolicy: ClusterFirstWithHostNet
|
dnsPolicy: ClusterFirstWithHostNet
|
||||||
@ -46,34 +45,45 @@ spec:
|
|||||||
ports:
|
ports:
|
||||||
- name: pop3
|
- name: pop3
|
||||||
containerPort: 110
|
containerPort: 110
|
||||||
|
hostPort: 110
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
- name: pop3s
|
- name: pop3s
|
||||||
containerPort: 995
|
containerPort: 995
|
||||||
|
hostPort: 995
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
- name: imap
|
- name: imap
|
||||||
containerPort: 143
|
containerPort: 143
|
||||||
|
hostPort: 143
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
- name: imaps
|
- name: imaps
|
||||||
containerPort: 993
|
containerPort: 993
|
||||||
|
hostPort: 993
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
- name: smtp
|
- name: smtp
|
||||||
containerPort: 25
|
containerPort: 25
|
||||||
|
hostPort: 25
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
|
- name: smtps
|
||||||
|
containerPort: 465
|
||||||
|
hostPort: 465
|
||||||
|
protocol: TCP
|
||||||
|
- name: smtpd
|
||||||
|
containerPort: 587
|
||||||
|
hostPort: 587
|
||||||
|
protocol: TCP
|
||||||
|
# internal services (not exposed externally)
|
||||||
- name: smtp-auth
|
- name: smtp-auth
|
||||||
containerPort: 10025
|
containerPort: 10025
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
- name: imap-auth
|
- name: imap-auth
|
||||||
containerPort: 10143
|
containerPort: 10143
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
- name: smtps
|
|
||||||
containerPort: 465
|
|
||||||
protocol: TCP
|
|
||||||
- name: smtpd
|
|
||||||
containerPort: 587
|
|
||||||
protocol: TCP
|
|
||||||
- name: auth
|
- name: auth
|
||||||
containerPort: 8000
|
containerPort: 8000
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
|
- name: http
|
||||||
|
containerPort: 80
|
||||||
|
protocol: TCP
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
memory: 100Mi
|
memory: 100Mi
|
||||||
@ -133,3 +143,6 @@ spec:
|
|||||||
- name: imap-auth
|
- name: imap-auth
|
||||||
port: 10143
|
port: 10143
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
protocol: TCP
|
||||||
|
@ -15,7 +15,7 @@ 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.
|
- ``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.
|
- ``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,...)
|
- ``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
|
- ``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
|
What you need
|
||||||
@ -24,7 +24,9 @@ What you need
|
|||||||
- A working Kubernetes cluster (tested with 1.10.5)
|
- A working Kubernetes cluster (tested with 1.10.5)
|
||||||
- A working `cert-manager`_ installation
|
- A working `cert-manager`_ installation
|
||||||
- A working nginx-ingress controller needed for the lets-encrypt
|
- A working nginx-ingress controller needed for the lets-encrypt
|
||||||
certificates. You can find those files in the ``nginx`` subfolder
|
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
|
Cert manager
|
||||||
^^^^^^^^^^^^
|
^^^^^^^^^^^^
|
||||||
@ -67,8 +69,8 @@ An example of a production and a staging ``clusterIssuer``:
|
|||||||
name: letsencrypt-prod
|
name: letsencrypt-prod
|
||||||
server: https://acme-v02.api.letsencrypt.org/directory
|
server: https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
|
||||||
**IMPORTANT**: All ``*-ingress.yaml`` files use the ``letsencrypt-stage`` ``clusterIssuer``. If you are ready for production,
|
**IMPORTANT**: ``ingress.yaml`` uses the ``letsencrypt-stage`` ``clusterIssuer``. If you are ready for production,
|
||||||
change this field in all ``*-ingress.yaml`` files to ``letsencrypt-prod`` or whatever name you chose for the 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``
|
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
|
Deploying Mailu
|
||||||
@ -83,7 +85,7 @@ 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
|
- 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 ``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 ``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`` files and change it to the domain you want (this is for the kubernetes ingress controller to handle the admin, webmail, webdav and auth connections)
|
- 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
|
Installation
|
||||||
------------
|
------------
|
||||||
@ -107,10 +109,7 @@ To start Mailu, run the following commands from the ``docs/kubernetes/mailu`` di
|
|||||||
kubectl create -f fetchmail.yaml
|
kubectl create -f fetchmail.yaml
|
||||||
kubectl create -f admin.yaml
|
kubectl create -f admin.yaml
|
||||||
kubectl create -f webdav.yaml
|
kubectl create -f webdav.yaml
|
||||||
kubectl create -f admin-ingress.yaml
|
kubectl create -f ingress.yaml
|
||||||
kubectl create -f webdav-ingress.yaml
|
|
||||||
kubectl create -f security-ingress.yaml
|
|
||||||
kubectl create -f webmail-ingress.yaml
|
|
||||||
|
|
||||||
|
|
||||||
Create the first admin account
|
Create the first admin account
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
name: mailu-antispam-ingress
|
name: mailu-ingress
|
||||||
namespace: mailu-mailserver
|
namespace: mailu-mailserver
|
||||||
annotations:
|
annotations:
|
||||||
kubernetes.io/tls-acme: "true"
|
kubernetes.io/tls-acme: "true"
|
||||||
certmanager.k8s.io/cluster-issuer: letsencrypt-stage
|
certmanager.k8s.io/cluster-issuer: letsencrypt-stage
|
||||||
ingress.kubernetes.io/configuration-snippet: |
|
|
||||||
rewrite ^/admin/antispam/(.*) /$1 break;
|
|
||||||
auth_request /internal/auth/admin;
|
|
||||||
proxy_set_header X-Real-IP "";
|
|
||||||
proxy_set_header X-Forwarded-For "";
|
|
||||||
labels:
|
labels:
|
||||||
app: mailu
|
app: mailu
|
||||||
role: mail
|
role: mail
|
||||||
tier: frontend
|
tier: backend
|
||||||
spec:
|
spec:
|
||||||
tls:
|
tls:
|
||||||
- hosts:
|
- hosts:
|
||||||
@ -24,7 +19,7 @@ spec:
|
|||||||
- host: "mail.example.com"
|
- host: "mail.example.com"
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: "/admin/antispam"
|
- path: "/"
|
||||||
backend:
|
backend:
|
||||||
serviceName: antispam
|
serviceName: front
|
||||||
servicePort: 11334
|
servicePort: 80
|
@ -1,46 +0,0 @@
|
|||||||
apiVersion: extensions/v1beta1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: mailu-webdav-ingress
|
|
||||||
namespace: mailu-mailserver
|
|
||||||
annotations:
|
|
||||||
kubernetes.io/tls-acme: "true"
|
|
||||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
|
||||||
certmanager.k8s.io/cluster-issuer: letsencrypt-stage
|
|
||||||
#ingress.kubernetes.io/auth-url: http://admin.mailu-mailserver.svc.cluster.local/internal/auth/basic
|
|
||||||
ingress.kubernetes.io/configuration-snippet: |
|
|
||||||
rewrite ^/webdav/(.*) /$1 break;
|
|
||||||
auth_request /internal/auth/basic;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
auth_request_set $user $upstream_http_x_user;
|
|
||||||
proxy_set_header X-Remote-User $user;
|
|
||||||
proxy_set_header X-Script-Name /webdav;
|
|
||||||
ingress.kubernetes.io/server-snippet: |
|
|
||||||
location /internal {
|
|
||||||
internal;
|
|
||||||
|
|
||||||
proxy_set_header Authorization $http_authorization;
|
|
||||||
proxy_pass_header Authorization;
|
|
||||||
proxy_pass http://admin.mailu-mailserver.svc.cluster.local;
|
|
||||||
proxy_pass_request_body off;
|
|
||||||
proxy_set_header Content-Length "";
|
|
||||||
}
|
|
||||||
labels:
|
|
||||||
app: mailu
|
|
||||||
role: mail
|
|
||||||
tier: frontend
|
|
||||||
spec:
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- "mail.example.com"
|
|
||||||
secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt
|
|
||||||
rules:
|
|
||||||
- host: "mail.example.com"
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: "/webdav"
|
|
||||||
backend:
|
|
||||||
serviceName: webdav
|
|
||||||
servicePort: 5232
|
|
@ -1,31 +0,0 @@
|
|||||||
apiVersion: extensions/v1beta1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: mailu-webmail-ingress
|
|
||||||
namespace: mailu-mailserver
|
|
||||||
annotations:
|
|
||||||
kubernetes.io/tls-acme: "true"
|
|
||||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
|
||||||
certmanager.k8s.io/cluster-issuer: letsencrypt-stage
|
|
||||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
|
|
||||||
labels:
|
|
||||||
app: mailu
|
|
||||||
role: mail
|
|
||||||
tier: backend
|
|
||||||
spec:
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- "webmail.example.com"
|
|
||||||
secretName: letsencrypt-webmail # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt
|
|
||||||
rules:
|
|
||||||
- host: "webmail.example.com"
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: "/"
|
|
||||||
backend:
|
|
||||||
serviceName: webmail
|
|
||||||
servicePort: 80
|
|
1
towncrier/newsfragments/1158.feature
Normal file
1
towncrier/newsfragments/1158.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
- Use nginx as http endpoint on kubernetes to simplify ingress
|
Loading…
x
Reference in New Issue
Block a user