Appearance
SMTP 郵件伺服器(Kubernetes 部署)
在 Kubernetes 上部署輕量 SMTP 轉發伺服器,透過公司 Smarthost 實現叢集內應用程式的郵件發送能力。
概述
許多部署在 Kubernetes 叢集內的應用程式需要發送郵件(告警通知、報表寄送、使用者驗證信等),但讓每個應用自行處理 SMTP 連線既冗餘又難以管理。透過在叢集內部署一個共用的 SMTP 轉發伺服器(relay),所有應用只需將郵件送往內部固定 IP 的 Port 25,由轉發伺服器統一處理外送。
本部署使用 egos-tech/smtp 映像檔(託管於 registry.gitlab.com/egos-tech/smtp),這是一個基於 Exim 的輕量 SMTP 伺服器,設定簡單且支援 Smarthost 轉發。搭配公司的 Exchange Online Protection(wiwynn-com.mail.protection.outlook.com)作為 Smarthost,可將郵件送往任意外部信箱。透過 Azure Internal LoadBalancer 暴露服務,僅限內部網路存取。
核心內容
Smarthost 轉發架構
本部署的郵件流向為:應用程式 → SMTP Pod (Port 25) → 公司 Smarthost → 收件人信箱。
關鍵設計決策:
- 設定 Smarthost:將
SMARTHOST_ADDRESS指向公司的 Exchange Online Protection 端點,所有外送郵件經由公司 SMTP 基礎設施轉發。這樣做能解鎖所有寄信限制,支援發送至任意外部信箱。 - 不設定 Smarthost:若省略此設定,SMTP 伺服器會嘗試直接投遞,但受限於網路環境與 DNS 設定,通常僅能寄送至公司內部信箱。
網路與安全考量
- RELAY_NETWORKS:設定為
:10.30.0.0/16,僅允許該網段的主機使用本 SMTP 服務轉發郵件,防止成為開放式轉發(open relay)。 - TLS 加密:透過掛載 Kubernetes Secret 中的 TLS 憑證,啟用 STARTTLS 加密傳輸。此為可選配置,若不需要加密可省略相關 Volume 與環境變數設定。
- 網路環境前提:本部署依賴特定的網路環境(AKS VNet 可直接連線至公司 Smarthost),在不同網路拓撲下可能需要額外的網路設定。
部署架構
部署架構非常精簡:單一 Deployment(1 副本)搭配一個 Internal LoadBalancer Service。由於郵件轉發為無狀態服務,不需要 PVC 或額外的 ConfigMap。所有設定透過環境變數注入。
關鍵要點
- 使用
registry.gitlab.com/egos-tech/smtp:latest映像檔,基於 Exim 的輕量 SMTP 轉發伺服器 - Smarthost 設定是決定能否寄送外部郵件的關鍵開關
RELAY_NETWORKS必須正確設定,避免成為開放式轉發- TLS 加密為可選配置,不影響基本功能
- 需在正確的網路環境下才能以極簡設定直接使用
實際應用
本 SMTP 伺服器部署於 AKS 叢集的 ingress-basic namespace,作為叢集內所有應用程式的統一郵件發送出口。應用程式只需將 SMTP 設定指向 10.30.196.60:25 即可發送郵件,無需各自處理 SMTP 認證與 TLS 握手。典型使用場景包括 Prometheus AlertManager 告警郵件、CI/CD Pipeline 通知、應用系統自動報表寄送等。
部署設定參考
以下為實際部署時使用的完整設定,供日後查詢與複製使用。
環境參數
| 項目 | 值 |
|---|---|
| Namespace | ingress-basic |
| 容器映像 | registry.gitlab.com/egos-tech/smtp:latest |
| 副本數 | 1 |
| Service 類型 | LoadBalancer(Azure Internal) |
| Internal LB IP | 10.30.196.60 |
| Port | 25 |
| Smarthost | wiwynn-com.mail.protection.outlook.com:25 |
| Relay Networks | 10.30.0.0/16 |
| TLS 憑證 Secret | aks-ingress-tls |
Deployment YAML
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: smtp-server
namespace: ingress-basic
spec:
replicas: 1
selector:
matchLabels:
app: smtp-server
template:
metadata:
labels:
app: smtp-server
spec:
containers:
- name: smtp
image: registry.gitlab.com/egos-tech/smtp:latest
ports:
- containerPort: 25
env:
- name: RELAY_NETWORKS
value: ":10.30.0.0/16"
- name: SMARTHOST_ADDRESS
value: "wiwynn-com.mail.protection.outlook.com"
- name: SMARTHOST_PORT
value: "25"
- name: KEY_PATH
value: "/etc/ssl/private/smtp.key"
- name: CERTIFICATE_PATH
value: "/etc/ssl/certs/smtp.crt"
volumeMounts:
- name: tls-certs
mountPath: /etc/ssl/certs/smtp.crt
subPath: tls.crt
- name: tls-certs
mountPath: /etc/ssl/private/smtp.key
subPath: tls.key
volumes:
- name: tls-certs
secret:
secretName: aks-ingress-tls環境變數說明
| 環境變數 | 值 | 說明 |
|---|---|---|
RELAY_NETWORKS | :10.30.0.0/16 | 允許此網段的主機透過本 SMTP 轉發郵件 |
SMARTHOST_ADDRESS | wiwynn-com.mail.protection.outlook.com | 公司 SMTP Smarthost 位址 |
SMARTHOST_PORT | 25 | Smarthost 連線埠號 |
KEY_PATH | /etc/ssl/private/smtp.key | TLS 私鑰路徑 |
CERTIFICATE_PATH | /etc/ssl/certs/smtp.crt | TLS 憑證路徑 |
TLS 憑證掛載
| 掛載路徑 | Secret 子路徑 | 用途 |
|---|---|---|
/etc/ssl/certs/smtp.crt | tls.crt | TLS 憑證 |
/etc/ssl/private/smtp.key | tls.key | TLS 私鑰 |
TLS 相關的
volumeMounts、volumes、KEY_PATH、CERTIFICATE_PATH為加上 TLS 加密的部分,若不需要加密傳輸可省略。
Service YAML(Internal Load Balancer)
yaml
apiVersion: v1
kind: Service
metadata:
name: smtp-service
namespace: ingress-basic
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
service.beta.kubernetes.io/azure-load-balancer-ipv4: 10.30.196.60
spec:
selector:
app: smtp-server
ports:
- port: 25
targetPort: 25
type: LoadBalancer相關概念
- Squid Proxy(Kubernetes 部署) — 同樣使用 Azure Internal LoadBalancer 對內暴露的基礎設施服務
- Caddy 靜態檔案伺服器 — 同為叢集內的共用基礎設施服務
- Samba + Nginx 檔案分享服務(Kubernetes 部署) — 同樣部署於
ingress-basicnamespace 的基礎設施服務 - Kubernetes RBAC 帳號管理 — 管理 SMTP 服務叢集存取權限的通用 RBAC 模式