kube-mail is a policy-based SMTP server designed for running in a Kubernetes cluster. It is configurable using Kubernetes Custom Resources and allows you to define policies for outgoing emails based on Pod labels (much like NetworkPolicies).
- Installation
- Basic architecture
- Custom Resources
- How-Tos
- Sending mails from within a Pod
- Pending features
This project is licensed under the Apache-2.0 license.
Copyright 2023 Martin Helmich, Mittwald CM Service GmbH & Co. KG and other contributors.
The helm chart of this controller can be found under ./deploy/helm-chart/kube-mail.
Alternatively, you can use the Mittwald Kubernetes Helm Charts repository:
helm repo add mittwald https://helm.mittwald.de
helm repo update
helm install kube-mail mittwald/kube-mail --namespace kube-system
When installed, kube-mail acts as an SMTP server that Pods in your cluster can use to send outgoing mails. This server works without any of the typical SMTP authentication mechanisms; instead, the kube-mail SMTP server authenticates a Pod by its IP address and then tries to find a EmailPolicy
resource that matches the source Pod (by label).
If an EmailPolicy
has been found for a Pod, kube-mail will forward the email that should be sent to the upstream SMTP server configured in the EmailPolicy
. If no EmailPolicy
matches, kube-mail will reject the email.
Within your Pod, simply use kube-mail.<namespace>.svc
as SMTP server without any authentication. kube-mail will do the rest.
This controller adds two Custom Resources to your Kubernetes cluster: A SMTPServer
and a EmailPolicy
resource, both from the kube-mail.helmich.me/v1alpha1
API group.
An SMTPServer
resource describes an SMTP server that should be used for outgoing mails. It is defined like follows:
apiVersion: kube-mail.helmich.me/v1alpha1
kind: SMTPServer
metadata:
name: default
spec:
server: smtp.yourserver.example
port: 465
tls: true
authType: PLAIN
Concerning the individual properties:
.spec.server
- The host name of your upstream SMTP server. This may be either an external service, or a cluster-internal service (for example, specified by its
.svc.cluster.local
address) .spec.port
- The port that the upstream SMTP server is listening on. If omitted, 587 is assumed as default.
.spec.tls
- Defines if the upstream server uses TLS.
.spec.authType
- The SMTP authentation type. Supported values are
PLAIN
,LOGIN
,CRAM-MD5
andSCRAM-SHA-1
.
An EmailPolicy
defines what kube-mail should do with mails received from a certain pod. An email policy will forward the received email to one of the SMTP servers configured using the SMTPServer
resources.
A forwarding email policy is defined like follows:
apiVersion: kube-mail.helmich.me/v1alpha1
kind: EmailPolicy
metadata:
name: my-policy
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: my-name
ratelimiting:
maximum: 100
period: hour
sink:
smtp:
server:
name: default
namespace: default
credentials:
name: default-credentials
namespace: default
Concerning the individual properties:
.spec.podSelector
- This is a selector for the Pods this EmailPolicy should apply to. When a SMTP connection is opened to kube-mail, it will identity the source Pod by its Pod IP address and then test if the source Pod matches this label selector.
.spec.ratelimiting
- Rate limiting may be configured per Policy. Allowed periods are
"hour"
and"minute"
. Messages are counted per policy, not per Pod. .spec.sink
-
sink
describes where kube-mail should deliver received emails. This may either be an SMTP server (described by aSMTPServer
resource) or kube-mail's internal database..spec.sink.smtp.server
server
is a reference to aSMTPServer
resource. It may be placed in a different namespace..spec.sink.smtp.credentials
credentials
is a reference to aSecret
resource with a"username"
and"password"
key. It may be placed in a different namespace. NOTE: If omitted, kube-mail will attempt an unauthenticated connection to the SMTP server.
Forwarding all outgoing emails into a mail catcher (like MailHog) is a common use case in development environments, where an application should not be allowed to actually send emails out into the world. To configure kube-mail to forward all emails into a mail catcher, proceed as follows.
-
Make sure that kube-mail is up and running in a namespace of your choice (for this example, we'll assume that kube-mail is running in the
kube-system
namespace). -
Install the mail catcher of your choice. MailHog, for example, has a Helm chart that makes it easy to install:
$ helm repo add codecentric https://codecentric.github.io/helm-charts $ helm install \ --namespace kube-system \ --name mailhog \ codecentric/mailhog
-
Configure an
SMTPServer
resource pointing to your MailHog service:apiVersion: kube-mail.helmich.me/v1alpha1 kind: SMTPServer metadata: name: mailhog namespace: kube-system spec: server: mailhog.kubemail-system.svc.cluster.local port: 1025 tls: false
-
Configure an
EmailPolicy
to catch emails from a Pod and forward them to the configuredSMTPServer
. The policy resource needs to be in the same namespace as the Pod that's sending mails.apiVersion: kube-mail.helmich.me/v1alpha1 kind: EmailPolicy metadata: name: pod-to-mailhog namespace: default # needs to be same namespace as Pod spec: podSelector: matchLabels: app.kubernetes.io/name: my-name sink: smtp: server: # server may be in a different namespace than policy name: mailhog namespace: kube-system
Provide ssmtp
in your Pod; use the following configuration (/etc/ssmtp/ssmtp.conf
):
mailhub=kube-mail.kube-system.svc.cluster.local
hostname=foo
FromLineOverride=yes
Then in the php.ini:
sendmail_path = /usr/sbin/ssmtp -t
- Rate limiting
- TLS for cluster-internal communication