JPAAWG 5th General Meeting
レガシーなEメールシステムをKubernetes化しました！

2022/11/07
IIJ: 衣笠 茂浩© Internet Initiative Japan Inc.

1

はじめに

私は長年 Eメールシステムを開発・導入・運用しています。
物理サーバ・仮想・オブジェクトストレージ・NoSQLと世代が変わる中で、今回Kubernetesを全面採用しレガシー Eメールシステムを完全リプレースしました。

本日はKubernetes導入における「考え方」・「はまりどころ」を具体的にお伝えし、導入障壁が下がれば良いと考えています
お断り： 内容は会社としての見解では無く個人の見解です2

話者の紹介• 話者: IIJ 衣笠 茂浩• メール歴20年• 移行: 2桁超
• のべ移行アカウント: 1100万超• 仕事:• メール・動画配信• アーキテクト•管理職（部長）

3

私のメール 履歴書

2011年 ～ ASP・オンプレ時代

2003年 ～ 2010年 オンプレ時代◼ 2021-年： 複数メールASP 導入◼ 2020年： 数十万規模メールASP 導入◼ 2019年： 数百万規模メールASP 導入◼ 2018年：◼ 2009年-2011年：数十万規模導入◼ 2007年-2008年：数十万規模導入◼ 2006年：数万規模導入◼ 2005年：◼ 数十万規模メールASP導入◼ 新メールASP立ち上げ◼ 2017年：数十万規模 導入◼ 2015-16年：数百万規模 導入◼ 2013-14年：◼ 数十万規模導入◼ 数万規模導入◼ 2004年：数十万規模導入◼ 2003年：数十万規模導入◼ 数百万規模導入◼ 数十万規模導入◼ 2011年：メールASP立ち上げ

ASP化 が さらに加速

4

2021年 JPAAWG 4th でこんな発表をしました

某サービスでKubernetesを全面採用しました！
安定稼働中です！
5

Kubernetesとは

6

Kubernetesとは•••デプロイやスケーリングを自動化
コンテナ化されたアプリケーションを管理
オープンソース
自分で調査可能（重要）参考: https://kubernetes.io/ja/

7

Kubernetesを使ったいい感じなメールシステム

いい感じなEメールシステム
サーバ間もWORKER

いい感じに通信

いい感じに

WORKER

Redis

セルフヒーリング
WORKER
ローリングアップデート・LDAP

Blue/Greenデプロイメント

Dovecot

Dovecot

Dovecot
いい感じに

Postfix
負荷分散できる

Postfix

Load Balancer

スケールアウト

自動でログ収集8

Kubernetes導入に必要なステップ

頑張ることいっぱいでした
1. クラスタ作りこみ
1. クラスタ作成
2. 外部連携（LB・ストレージ)
2. アプリ作りこみ
1. コンテナ作成
2. デプロイ
3. コントローラ自作

3. モニタリング・ログ
1. モニタリング
2. 監視
3. ログ収集
4. 工夫
1. 性能面
2. 可用性トピックとはまりどころを伝えます
お断り: 紹介内容はできるだけリアルな構成としていますが、アプリ周りは皆様にわかりやすいようにOSS系を中心に紹介します9Kubernetes クラスタ作りこみ(オンプレです)10オンプレミスでのKubernetesの作り方

クラスタベース(今回利用した構成の場合）
プロダクト名説明

RockyLinuxLinux OSKubeadm

Kubernetesクラスター環境を作成・管理するツール

KubeletPodやコンテナの起動

Kubectl

クラスターにアクセスするためのコマンドラインツール

etcd

クラスターの構成情報・状態を保存するKVSCalico

コンテナにネットワークとセキュリティポリシー機能を提供

F5 Container Ingress Services

F5製連携ソフト。BIG-IP連携で利用。

Astra Trident

NetApp製連携ソフト。NetApp連携(NFS/iSCSI)で利用。

基本OSS。コード調査可能
11オンプレミスでのKubernetesの作り方

基本:• Kubeadm + calicoでOK手順を見れば大体できますhttps://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

応用:• 可用性考慮で構成変化有り
https://kubernetes.io/docs/setup/#production-environment• Container Network Interface(CNI)・Container Storage
Interface (CSI) は状況に応じて選択を。
12

Kubernetesクラスタ 構成図(冗長構成)

3台で冗長化構成が基本
MASTERMASTERMASTER

WORKER

WORKER

etcd

etcd

etcd

haproxy

haproxy

WORKER

名称説明MASTER

コントロールプレーン。スケジューリング・イベント検出および応答等を行う。

WORKER

ワーカーノード。POD実行。

etcd

キーバリューストア。クラスタ情報保存に利用。多数決モデル利用。

haproxy

クラスタ外部からMASTER APIへのアクセス冗長化に利用

13

BIG-IP連携

スケールアウトでLB配下に動的組み込み。IPv6にも対応。
3台しかいない
3. node追加・poolmemberに自動登録# kubectl scale statefulset pop --replicas=42. 変更を検知

pop1

pop2
1. pod4を追加

pop3

F5
Container Ingress
Service

4台構成に！
Dual Stackにも対応！

新POD
pop4
Scale outも簡単(自動でnode/poolに追加)

14

BIG-IP連携

注意点・はまりどころ
1. BIGIP本体でREST・BGP有効化・AS3導入が必要

2. （重要）構成変更（POD増減等)反映まで60秒程度かかる• パーティションが複数存在する場合はさらに時間がかかる場合あり
3. （重要） BIGIP restjavadが安定しないことがある• BIGIP本体の最新化・Java HEAP最適化等必要
https://cdn.f5.com/product/bugtracker/ID769581.html
https://support.f5.com/csp/article/K12410040

上記を踏まないチューニングが必須
15

NetApp連携

ボリューム（NFS・iSCSI)を必要に応じて自動作成。DRにも対応。
WORKERMASTER
Dovecot

動的にVOL作成(NFS/iSCSI)

必要に応じてPODに
動的マウンドvolDRサイトへのコピー

16NetApp連携

注意点・はまりどころはあまり無い（安定してる）。
1. メールキュー等ロック・性能が必要な部分はiSCSIを利用•

オンライン領域解放(discard option)は使わないこと！(プチフリします)•

https://docs.netapp.com/ja-jp/trident-2204/pdfs/fullsite-sidebar/Astra_Trident_22_04_%E3%81%AE%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88.pdf

2. iSCSI利用時にiSCSIマウントできない(Linux Kernel 不具合)••- scsi: iscsi: iscsi_tcp: Avoid holding spinlock while calling getpeername() (Chris Leech)[2011470]
https://cbs.centos.org/koji/buildinfo?buildID=36146

回避策: Kernelを最新にあげて回避

Trident連携は安定していました17アプリの作り込み
お断り: アプリは皆様にわかりやすいようにOSS系を中心に紹介します18Kubernetesでのアプリ作り込み

主な特徴• 全部コンテナにする• ミニマムアプリにする(sample)Postfixでのコンテナプロセス例[root@postfix-6db444b6b4-ccd29 /]# ps axwwuf
USER
PID %CPU %MEM
VSZ RSS TTY
root
1098 0.1 0.0 22804 3484 pts/0
root
1111 0.0 0.0 55440 3568 pts/0
root
1 0.0 0.0 105232 1996 ?
postfix
77 0.0 0.0 121364 1836 ?
postfix
82 0.0 0.0 125524 1140 ?
postfix
1093 0.0 0.0 121244 8792 ?
[root@postfix-6db444b6b4-ccd29 /]#STAT STARTSs 10:31
R+ 10:31
Ss Oct24
SOct24
SOct24
S
10:22

TIME COMMAND
0:00 bash
0:00 ¥_ ps axwwuf
0:03 /usr/libexec/postfix/master -i
0:00 qmgr -l -t unix -u
0:00 tlsmgr -l -t unix -u
0:00 pickup -l -t unix -u• (重要)通信は名前解決のみ• IPアドレスは変わる• Kubernetesが提供しない機能は作りこむ• クラスタリング(Dovecot Director)• MariaDB（Galera Cluster）
他

proxy-01
10.244.139.24

再起動

proxy-01
10.244.139.25

POD再起動でIPは変わる！

19

コンテナ作成例(postfix)

Dockerfile(sample: postfix)
FROM rockylinux/rockylinux:8.6
RUN dnf -y install postfix
RUN echo "maillog_file = /dev/stdout" >> /etc/postfix/main.cf
CMD ["/usr/sbin/postfix","start-fg"]

ポイント• ログ: 標準出力
• 起動: フォアグラウンド• 開発・デバッグツール: ご自由に20コンテナイメージ作成

メールアプリコンテナ#作成コンテナ（これ以外も多数あり）
アプリケーション
ログ出力

1 postfix
2 Dovecot
3 Halon MTA
4 Cloudmark Authority Server
5 TwoFive Safe25
6 Vade MTA
7 Zimbra
8 Haproxy
9 Fluentd
10 Fluent-bit
11 apache
12 Appsuite
13 Keycloak
14 Nginx
15 Guvicorn
16 Openldap
17 Mailman318 Openresty

フォアグラウンド起動〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇

一つ一つは大きくないが、全体で見ると作業量が多し〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇
21

コンテナ作成TIPS• docker hub等のサンプルを改造• 下調べと十分な検証が必要• 1. ログ出力• stdout/stderr or syslog• 2. モニタリング対応(後述)• exporter必要有無• 3. 同一コンテナで複数プロセス動作要否• rsyslog・外部exporter同居時はsupervisordが必要等

モニタリング連携まで揃えると作り込みに時間がかかる

22

コンテナ起動例

sample: Dovecot Directorのコンテナ起動例# ps axwwuf
USER
PID %CPU %MEM
VSZ RSS TTY
root
3906217 0.0 0.0 23112 3880 pts/0
root
3906804 0.0 0.0 55472 3672 pts/0
root
1 0.1 0.0 109548 17216 ?
root
9 0.0 0.0 16020 852 ?
root
20 0.0 0.0 52944 1612 ?
dovenull
23 0.0 0.0 32892 7924 ?
dovenull
24 0.0 0.0 29472 3344 ?
dovecot
25 0.0 0.0 10384 764 ?
root
26 0.0 0.0 11156 1340 ?
dovenull
27 0.0 0.0 35136 8816 ?
dovenull
28 0.0 0.0 33872 7944 ?
dovenull
29 0.0 0.0 37912 10968 ?
dovenull
30 0.0 0.0 30636 3624 ?
dovenull
31 0.0 0.0 30808 4232 ?
dovenull
32 0.0 0.0 31184 5724 ?
root
33 0.0 0.0 29556 3868 ?
dovecot
34 0.0 0.0 15872 2872 ?
dovecot
36 0.0 0.0 18064 2248 ?
dovecot
250 0.0 0.0 10508 848 ?
root
10 0.1 0.0 530276 16288 ?
root
11 0.0 0.0 199228 1536 ?

dovecot・ヘルスチェック・rsyslog起動のためにsupervisord利用
STAT START TIME COMMAND
Ss 10:39 0:00 bash
R+ 10:43 0:00 ¥_ ps axwwuf
Ss Aug08 146:31 /usr/bin/python3.6 /usr/bin/supervisord -c /etc/supervisord.conf
S
Aug08 0:00 /bin/bash /boot-dovecot.sh
S
Aug08 18:15 ¥_ /usr/sbin/dovecot -F
S
Aug08 3:18¥_ dovecot/pop3-login
Dovecot フォアグラウンド起動(-F)
S
Aug08 8:20¥_ dovecot/imap-login
S
Aug08 1:18¥_ dovecot/anvil [8 connections]
ログは/dev/stdoutに出力
S
Aug08 10:43¥_ dovecot/log
S
Aug08 4:26¥_ dovecot/pop3-login
S
Aug08 3:44¥_ dovecot/pop3-login
S
Aug08 5:33¥_ dovecot/pop3-login
S
Aug08 8:48¥_ dovecot/imap-login
S
Aug08 9:23¥_ dovecot/imap-login
S
Aug08 10:20¥_ dovecot/imap-login
S
Aug08 59:32¥_ dovecot/config
S
Aug08 35:44¥_ dovecot/stats [11 connections]S
Aug08 35:50¥_ dovecot/director [121 users, 0+0 req/s, 0+0 kB/s]
SAug08 2:39¥_ dovecot/ipc [9 connections]
Sl Aug08 251:20 /usr/bin/python3.6 /usr/sbin/healthcheck.py
ヘルスチェックPGはsyslogにログを
Sl Aug08 46:34 /usr/sbin/rsyslogd -n
出力するためrsyslogを準備

rsyslogは/dev/stdoutにログを出力

23

Kubernetesへのデプロイ

ステートレス・ステートフルでデプロイプランを検討• ステートレス: Deployment• ステートレスアプリケーションの管理に利用• プロキシ・Webサーバ・アンチウイルス・アンチスパム等に利用• ステートフル: Statefulset• ステートフルなアプリケーションの管理に利用• メールボックス・MTA・LDAP等ストレージを利用する物に利用

24deployment・statefulsetを使ったデプロイ例

必要に応じてスケールアウト# kubectl scale statefulset mta --replicas=3
mta-0

mta-1

av5f4948c7cd-29pxr

av5f4948c7cd-5zvrp# kubectl scale deployment av --replicas=3

mtax-0

mta-1

mta-2

av5f4948c7cd-29pxr

av5f4948c7cd-5zvrpav5f4948c7cd-wv966

動的に増減できるのがKubernetesの醍醐味！
25

余談

金曜日 の大量着信に備えて2倍にスケールアウト！

2倍きっちり打ち込まれる・・・

教訓: 大量着信には流量制御で勝負すべし26

コンテナライフサイクル

Kubernetes化に伴い以下の強化が必須に
ソフトウェアに依っては• 起動・停止スクリプト• VMの起動・停止とは前提が異なる• gracefulな停止が必要

かなりの作り込むになるケースも• 適切なヘルスチェックが肝• POD生死判定: LivnessProbe• POD RUNNING判定: ReadinessProbe

セルフヒーリングに最も重要なポイント！
27

コンテナライフサイクル(割とはしょってます）

POD起動時のライフサイクル
Pod

Containers

Initialize

Start

Running
起動スクリプト

initContainer

任意の初期化プログラム実行

Livness/Readiness Probe

POD終了時のライフサイクル
Running

Terminating

プログラム実行

停止スクリプト(preStop)

Terminated

SIGTERM

SIGKILL
28

起動・停止スクリプト

POD初期化含めた起動スクリプトが必須• 例: メールキューディレクトリ作成
for D in /var/spool/mailq /var/spool/mailq/queue /var/spool/mailq/tmp
domkdir -p $D
chown smtpd:smtpd $D
chmod 750 $D
done• VMでは既に終わってる前提だった初期化を敢えて意識した実装が必要

独自起動スクリプトが必要なケース多し
29

起動・停止スクリプト停止スクリプト(preStop)は以下で実行される• POD Terminating時• LivnessProbe 失敗

停止スクリプト例• メールキュー強制吐き出し• ユーザコネクション切断待ち ＆ 切断
• クラスタリングからの自分自身の削除
他

クラスタリングの作り込みが複雑になるケースあり

メンテナンス・セルフヒーリングにはgraceful停止が必須
30

アプリケーションコントローラの自作

アプリケーションクラスタリングは自作
sample: Dovecot Directorの場合
元々3台存在することをDNSで把握
POP

POP

4台目が振り先として
192.168.0.1
192.168.0.2
192.168.0.3

192.168.0.1
192.168.0.2
192.168.0.3

director-0
POPPOP

自動登録されない

director-0
POPPOPPOPPOP# kubectl scale sts mailbox --replicas=4
mailbox-0192.168.0.1

mailbox-1
192.168.0.2

mailbox-2
192.168.0.3

mailbox-0192.168.0.1

mailbox-1
192.168.0.2

mailbox-2
192.168.0.3

mailbox-3192.168.0.4

Directorは起動時のみ名前解決するため起動後のノード増減を把握できない31

アプリケーションコントローラの自作

POD増減に応じて動作するコントローラが必要
1. APIに問い合わせ
mailbox追加を検出

Kubernetes
APIPOP

4台目を認識！

自作コントローラ192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4

POP

mailbox-0192.168.0.1

director-0POP

2. mailbox追加を指示

POP

mailbox-1
192.168.0.2

本日探してみたらこんな物が・・・（未検証です）
https://github.com/yartu/yartu-dovemon/

controllerPOPmailbox-2
192.168.0.3

mailbox-3192.168.0.4

32

出口コントロール

Kubernetesではノード外通信は基本ノード IPでNATされる

Fallback・外部送信が同

一Global IPで届いている

Src:192.168.137.11
Dest: 203.0.113.1

Src: Global IP1
Dest: 203.0.113.1

Src:192.168.137.11
Dest: 203.0.113.1

Src: Global IP1
Dest: 203.0.113.1

ように見える

Src:10.244.139.30
Dest: 203.0.113.1

fallback-01
10.244.139.30

Src:10.244.139.31
Dest: 203.0.113.1

mailout-01
10.244.139.31
worker-01
192.168.137.11

Fallback・外部送信PODが同一IPにNATされる

例: fallback・通常配送で同じsrc IP(192.168.137.11)にNATされるため、出口IP使い分けできないケース

Fallback・通常送信が同一グローバルIPとなり、IPの送信評価が低下するリスク
33

出口コントロール

ノード出口でNATせず、ノード外(LB・FW)でNATすることで出口振り分け実施Src:10.244.10.1
Dest: 203.0.113.1

Src: Fallback IP1
Dest: 203.0.113.1

Src:10.244.10.1
Dest: 203.0.113.1
FallbackのIPレンジ
Fallback専用IP

fallback-01(10.244.10.0/24)をpool(10.244.10.0/24)から

LBでNAT

10.244.10.1

払い出し

Src:10.244.139.31
Dest: 203.0.113.1

mailout-01

spec:
template:
metadata:
annotations:"cni.projectcalico.org/ipv4pools":"[¥“fallback-ipv4-ippool¥"]""cni.projectcalico.org/ipv6pools":"[¥" fallback-ipv6-ippool¥"]"Fallback でNATしないIPレンジを指定
Src:192.168.137.11
Dest: 203.0.113.1

Src: 通常Global IP
Dest: 203.0.113.1

10.244.139.31
worker-01
192.168.137.11

IPv4・IPv6DualStack可能ですhttps://projectcalico.docs.tigera.io/networking/workloads-outside-cluster

34

モニタリング・ログ収集

35

Kubernetesでのモニタリング

主な特徴• PULL型監視• 定期的にHTTP経由でmetricsを取得し評価• 監視対象（POD）が動的に増減• Service discover必須• ノードの監視・アプリの監視それぞれが必要• ノード監視: 標準でほぼデータ取得可能• アプリ監視: HTTP経由でOpenMetricsに対応していればOK• メールアプリは基本非対応(Dovecot・Halonぐらいか?)

36

Victoria MetricsとはPrometheus互換。安定稼働中。

••
•••
•••

Highest Ingestion Rate
Fastest Query Performance
Smallest Disk Storage Size
Lowest Memory Usage
Long-term Storage for Metrics
Highly Scalable
Cloud Readiness
Simple Set-up & Operation

https://victoriametrics.com/
https://docs.victoriametrics.com/

37

PULL型監視

VictoriaMetrics + GrafanaでPULL型監視WebUIで参照

node_exporter
Victoriaに保存

Scrape(pull)vmagent

gloval query view

Remote_write

Scrape(pull)

grafana

Application exporter
一定間隔でPULL

Victoria metrics

一定間隔でHTTPでmetricsデータ取得
VictoriaMetricsにデータ投入する38

アプリ毎対応状況

アプリ監視対応状況#アプリケーション

1 postfix
2 Dovecot
3 Halon MTA
4 Cloudmark Authority Server
5 TwoFive Safe25
6 Zimbra
7 Haproxy
8 Fluentd
9 Fluent-bit
10 apache
11 Appsuite

検証結果
監視ポイント○(外部ツール)◎(標準提供)◎(標準提供)●(自作)●(自作)◎(標準提供) * 最新◎(標準提供)◎(標準提供)◎(標準提供)○(外部ツール)◎(標準提供)Grafanaダッシュボード

○
●(自作)
●(自作)
●(自作)
●(自作)
●(自作)
○
○
○
○
○

望む監視のために自作するケースも多々あり
メールアプリのダッシュボードは基本自作
39

ダッシュボード

Grafana dashboardで可視化

40モニタリング

監視はAlertmanager + barry(IIJ 内製 インシデント管理アプリ) + 他

alertmanager2barry

アラート結果一定間隔で保存データを評価

伝達

barry

Prometheus
Teams Proxyvmalertalertmanager
Victoria metrics

Barrryとは:
https://www.iij.ad.jp/dev/report/iir/051/03.html
https://eng-blog.iij.ad.jp/archives/4488アラート振分
通知実施

41

監視ルール

監視テンプレート有り#

アプリケーション
1 Kubernetes
これで事足りる
2 ホスト
3 MySQL
4 Redis

監視テンプレート
https://awesome-prometheus-alerts.grep.to/rules.html
https://awesome-prometheus-alerts.grep.to/rules.html
https://awesome-prometheus-alerts.grep.to/rules.html
https://awesome-prometheus-alerts.grep.to/rules.html

Eメールアプリは監視テンプレート無し#

アプリケーション

1 postfix
2 Dovecot
3 Halon MTA
4 Cloudmark Authority Server
5 TwoFive Safe25
6 Zimbra

その他

ポート監視
自作SMTP・POP・IMAP・HTTPトランザクション等
キュー監視
リソース監視メールアプリ監視は基本自作
Kubernetes側でのカバー範囲多し(PODダウン・リソース監視・ヘルスチェック失敗等）
42ログ収集コンテナログ収集はlokiで集約

https://grafana.com/oss/loki/
43

ログ検索

Grafanaで串刺し検索
検索条件入力ログ量目視も可能

ログ検索がしっかりしていないとKubernetesは辛い(Loki・Splunk等必須)44

ログ保管ストレージ

LokiのログはS3互換ストレージに保管可能• IIJオブジェクトストレージサービス• minio• AWS S3
• Scality S3
他

45工夫したところ

46

DNS問い合わせの最適化• デフォルト設定では名前解決「しすぎ」です！

ndots: 1 は必須(と信じてる)

POD デフォルトの/etc/resolv.conf(ndots: 5)
search default.svc.cluster.local svc.cluster.local cluster.local test.example.com example.com
nameserver 10.96.0.10
options ndots:547

DNS問い合わせの最適化

ndotsとは$ man resolv.conf….
ndots:nSets a threshold for the number of dots which must appear in a name given to res_query(3) (see resolver(3)) before
an initial absolute query will be made. The default for n is 1, meaning that if there are any dots in a name, the name willbe tried first as an absolute name before any search list elements are appended to it. The value for this option is silently
capped to 15.

ndots:• /etc/resolv.confで定義したドメイン補完 動作有無を「ドット」の数で判断• OS標準 ndots: 1• 「ドット」が1つ含まれていれば補完しない
48

DNS問い合わせの最適化

ndots:5(Kubernetes default) でiij.ad.jpにメールを投げると・・・
1. omgi.iij.ad.jp.default.svc.cluster.local (A)2. omgi.iij.ad.jp.default.svc.cluster.local (AAAA)
3. omgi.iij.ad.jp.svc.cluster.local (A)4. omgi.iij.ad.jp.svc.cluster.local (AAAA)
5. omgi.iij.ad.jp.cluster.local (A)6. omgi.iij.ad.jp.cluster.local (AAAA)
7. omgi.iij.ad.jp.test.example.com (A)
8. omgi.iij.ad.jp.test.example.com (AAAA)
9. omgi.iij.ad.jp.example.com (A)
10. omgi.iij.ad.jp.example.com (AAAA)
11. omgi.iij.ad.jp(A)
12. omgi.iij.ad.jp(AAAA)* omgi.iij.ad.jp: iij.ad.jpのMXレコード

マジでやばいです49

DNS問い合わせの最適化

ndots:1 なら
1. omgi.iij.ad.jp(A)2. omgi.iij.ad.jp(AAAA)* omgi.iij.ad.jp: iij.ad.jpのMXレコード

すっきり（普通・・・）
50

node-local-dnsでの問い合わせ最適化

名前解決命なので、DNSキャッシュも必須
node-local-dnsという素晴らしいキャッシュソフト(daemonset)有り
WORKER
TCP

UDP

TCP

postfix

TCP

node-localdns

unboundcore-dns
TCP

内部問い合わせ

WORKER
UDP

TCP

外部問い合わせpostfix

node-localdns

同一ノード中でキャッシュ保持
UDP->TCPにアップグレードしconntrack節約

https://kubernetes.io/ja/docs/tasks/administer-cluster/nodelocaldns/

51

node-local-dnsとunboundの組み合わせ

unbound側でTCP問い合わせ上限を増やさないと名前解決が飽和します

DNSのアップストリームがunboundの場合、node-local-dnsはUDP->TCPに強制アップグレードするのではまりますhttps://dnsops.jp/event/20160624/unbound.pdf

52Kernel パラメータ• 各種最適化のためにKernelパラメータも随時調整• PODレベル• kernel.msgmax• kernel.msgmnb• net.core.somaxconn• net.ipv4.ip_local_port_range• net.ipv4.tcp_tw_reuse….
• ノードレベル• fs.inotify.max_user_instances• fs.inotify.max_user_watches…
allowed-unsafe-sysctls で定義できるパラメータの追加が必要
https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/53可用性の向上についてAnti Affinityコントロール• 同一種別のPODは別ノードで起動させる• ラックレベルで分ける
等
WORKER

WORKER

WORKER

WORKER

Dovecot
Postfix

Redis

Redis

Dovecot

Dovecot

Dovecot

Postfix

Postfix

Postfix

Redis

障害時影響大Redis

障害時影響低減54

性能について• (重要)コンテナ化しても性能は(大して)変わらない• ノードリソース使い切りは危険• リソースの取り合い• CPU・I/O・NWを激しく使うコンテナは特に注意• HEAVY PODがノードリソースを占有して全体がスローダウン• MTA・メールボックスは同居させない等

入念なスケジューリング設定が必要
55

最後に56

全体構成図作り上げるとこういうイメージになります(書ききれないので概要です)
配送系

システム基盤系

node-localdns

k8s-f5-ctrl

MTA

MSA

AV

AS

メールボックス・Webメール系

trident

trident-cs

proxy

loki

mailboxwebmail

promtail
共通系

victoria

LDAP

alertmanager

KVS

haproxy

オブジェクトストレージ

検索エンジン

fluentd

DB

ストレージ

LB

57

導入して良かったこと

1.影響無しメンテがいつでもできる• ダウン無しに作り込めばOK2.（重要）世代交代できた！
• 若手の活躍がすごかった！
3.開発速度が上がった！
• インフラとアプリの分離は偉大• 汎用性が高い点も◎
58

まとめ

1.EメールシステムをKubernetesでリプレースしました

2.導入難度は高いが、構成・運用が今風になり世代交代できました。

3.安定稼働。安心です。
59

仲間募集中IIJはメールエンジニアを絶賛募集中です• メール好きな人（運用・開発）• Kubernetesへの取り組み

IIJ 採用

検索60

ご清聴ありがとうございました。

61