Skip to content

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 通知、應用系統自動報表寄送等。

部署設定參考

以下為實際部署時使用的完整設定,供日後查詢與複製使用。

環境參數

項目
Namespaceingress-basic
容器映像registry.gitlab.com/egos-tech/smtp:latest
副本數1
Service 類型LoadBalancer(Azure Internal)
Internal LB IP10.30.196.60
Port25
Smarthostwiwynn-com.mail.protection.outlook.com:25
Relay Networks10.30.0.0/16
TLS 憑證 Secretaks-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_ADDRESSwiwynn-com.mail.protection.outlook.com公司 SMTP Smarthost 位址
SMARTHOST_PORT25Smarthost 連線埠號
KEY_PATH/etc/ssl/private/smtp.keyTLS 私鑰路徑
CERTIFICATE_PATH/etc/ssl/certs/smtp.crtTLS 憑證路徑

TLS 憑證掛載

掛載路徑Secret 子路徑用途
/etc/ssl/certs/smtp.crttls.crtTLS 憑證
/etc/ssl/private/smtp.keytls.keyTLS 私鑰

TLS 相關的 volumeMountsvolumesKEY_PATHCERTIFICATE_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

相關概念

來源