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-systemWhen 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: PLAINConcerning 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.localaddress) .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-MD5andSCRAM-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: defaultConcerning 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-
sinkdescribes where kube-mail should deliver received emails. This may either be an SMTP server (described by aSMTPServerresource) or kube-mail's internal database..spec.sink.smtp.serverserveris a reference to aSMTPServerresource. It may be placed in a different namespace..spec.sink.smtp.credentialscredentialsis a reference to aSecretresource 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-systemnamespace). -
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
SMTPServerresource 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
EmailPolicyto 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