1
Mercari JPのモノリスサービスをKubernetes
に移行した話
PHP Conference 2022
Shin Ohno(@ganchiku)
2
Engineering Manager

Mercari API Team, Mercari JP





Shin Ohno

3
Mercari-api チーム
ストリームドアラインド & イネイブリングを兼ねているようなチーム
チームとその領域
4
なぜ Kubernetes 環境に移行をしたか
トピック
なにを Kubernetes 環境に移行したか
どうやって Kubernetes 環境に移行したか
チームトポロジー的な視点
02
03
04
01
既存アプリケーションの問題にどう対処したか
05
今後、どうなっていくか
06
5
なぜ Kubernetes 環境に移行をしたか
WHY
6
なぜ Kubernetes 環境に移行をしたか
Cloud ならではの利点の享受
● Reliability を向上させる
● インフラのコスト最適化させる
開発者体験を改善し、エンジニアの満足度の向上
● Kubernetes, Terraform などの Platform 基盤の上に乗る
● 開発環境と本番環境の差を最小にする
Platform チームが提供するMercari のマイクロサービスと同じ開発体験とするた
め
7
なぜ Kubernetes 環境に移行をしたか
移行前の開発環境 移行後の開発環境
開発環境の主なオーナー CI/CDチーム Mercari API チーム
本番環境と開発環境の差異 開発環境は、VM の Docker
環境で他のサービスと相乗り
していた
本番と同じくコンテナイメージ
を使用するようになった
開発環境のセットアップ Web UI から手動で VM を起
動していた
GitHub PR が作られると、自
動的に開発クラスターに
Deploy され、起動していた
ログの確認 開発環境のコンテナ内のログ
を参照
DataDog に流れるようになっ
た
開発環境と本番環境の差を最小にする
8
サービスの概念図(簡略版)
9
実際のインフラ構成図(簡略版)移行前
10
実際のインフラ構成図(簡略版)
11
なにを Kubernetes 環境に移行したか
WHAT
12
モノリスサービスの構成
見出し
APIサーバー

Nginx+Apache

キューを処理するWorker 

Q4M with PHP

● メール送信

● SMS送信

● プッシュ通知送信

● 会計処理

など

● マイクロサービス化されてい
ないエンドポイント群 

● 購入、配送処理の一部 

● ユーザー管理の一部 

など

● 配送処理のバッチ

● リマインド通知のバッチ 

● 会計の月次処理のバッチ 

● 一部ログ掃除などのバッチ 

など





Cron Job

13
どうやって Kubernetes 環境に移行したか
HOW
14
どうやって Kubernetes 環境に移行したか
● Lift
○ 既存のシステムをそのままクラウド環境へ移行する
● Shift
○ クラウドへ移行したシステムを徐々にクラウド環境に最適化する
Lift & Shift アプローチ
15
どうやって Kubernetes 環境に移行したか
● PHPの Base Container を予め用意する
● アプリケーションを含んだContainer を Build & Release
● 1つずつ影響度の小さいものから移行していく。Kustomize 使用
影響の小さいものから少しずつ(Worker から)
キューのDB は
同じなので、取
り合いに注意
16
どうやって Kubernetes 環境に移行したか
Worker の移行後、API サーバーも準備し、少しずつ Traffic を移行していく
0%-0.01% -> 0.01%-1%-5% -> 5%-25%-42%-0% -> 0%-5% -> 5%-25%-50% -> 50%-0% -> 0%-50%-0% ->
0%-10% -> 10%-25% -> 25%-0%-50% -> 50%-100%
参考: What it’s like to work as an embedded microservices SRE
17
どうやって Kubernetes 環境に移行したか
Mercari API チームが先行事例を作り、ドキュメント作成後、各チームに委譲
● ノウハウをドキュメント化し、各ドメインオーナーに伝え、支援する
CronJob の数: 約40
CronJob に関しては、先行事例を最初に作って、各ドメインオーナーが実施
検索 取引
物流
クーポン
通知
ユーザー
価格
出品
ログイン
コメント
18
チームトポロジー的な視点
Team Topologies Perspective
19
チームトポロジー的な視点
● 初期(構想を練って、プロトタイプ化)

○ タスクフォース的に、モノリスサービスの知見を持ったメンバーがリード 

○ 先行して移行をしていたMercari USの知見を参考 

● 中期(Kubernetes 環境にリリース)

○ マイクロサービスの知見を持ったメンバーがKubernetes の設定をリード 

○ ミドルウェアの運用の知見を持ったSREにヒアリング 

● 後期(運用改善)

○ CronJobに関しては、各チームに委譲していく 

○ オブザーバビリティ改善のため、Embedded SRE と共にサービス改善を行う 

■ DataDog によるモニタリング、ログ等の組み込み 

■ 最適なCPU, Memory の設定 

フェーズによってチームメンバーが入れ替わり、チームのインタラクションモードも合
わせていった。
20
チームトポロジー的な視点
移行タスクフォース: ストリームアラインドチーム
● 移行そののものをリード
SRE: イネイブリングチーム
● 移行で困難なことやノウハウを伝授、教育
Platform: プラットフォームチーム
● マイクロサービス共通基盤などを提供
チームのタイプ
21
チームトポロジー的な視点
● タスクフォース的に、モノリスサービスの知見を
持ったメンバーがリード 

● US の移行の知見のヒアリング
ブロッカーになりそうな場所の整理
● Log の集約をどうするか
● Credentials の管理をどうするか
大まかなマイルストーンとスケジュール
● Base となるコンテナイメージ の作成
● Worker, APIServer, CronJob それぞれい
つまでの移行完了を目指すか
初期(構想を練って、プロトタイプ化)(3ヶ月)
参考: 巨大モノリスをKubernetesに移行してシングルクラスタ
運用にするためにどうしたか
22
チームトポロジー的な視点
● マイクロサービスの知見を持ったメンバーが
Kubernetes の設定をリード 

● ミドルウェアの運用の知見を持ったSREにヒア
リング
開発期(yamlがほとんど)
● Worker の Deployment 用意
● GitHub PR merge でアプリケーションイ
メージの作成
● PubSub -> Spinnaker でデプロイ
中期(Kubernetes 環境にリリース)(5ヶ月)
23
チームトポロジー的な視点
運用改善

● オブザーバビリティ改善のため、SRE と共に
サービス改善を行う 

● DataDog によるモニタリング、ログ等の組み
込み
CronJob 移行

● 移行ドキュメントやスケジュールを管理し、各
チームに委譲、レビューや相談に乗る
後期(運用改善)(5ヶ月)
運用改善
CronJob
移行
24
既存アプリケーションの問題にどう対処したか
Application Specific issues
25
既存アプリケーションの問題にどう対処したか
時間の経過と共に Worker のメモリが溜まっていく
● 24時間に一度 Rollout して、Pod を入れ替える


メモリリーク問題(Worker)
メモリが上がってくるタイミングを想定して、
CronJob のスケジューラーで RollOut
26
既存アプリケーションの問題にどう対処したか
処理中に落ちたりしてしまわないように、pcntl_signal 関数でシグナルを確認
OnPremiss環境
● 複数の Worker を Supervisord で管理
Kubernetes 環境
● 各Worker 毎に Deployment で管理
● スケールインする際に、正しくジョブの実行が終わっていることをチェック


グレースフルシャットダウン(Worker)
27
既存アプリケーションの問題にどう対処したか
GKE特有の問題、concurrencyPolicy: Replace でも並列稼働する可能性あり
● 重複実行をしても良い設計に(冪等性)
● それでも重複実行を許容できない処理においては、アプリケーションレベルで、
ロック機構を用いて対応
参考: https://engineering.mercari.com/blog/entry/k8s-cronjob-20200908/


CronJob 重複実行問題
28
既存アプリケーションの問題にどう対処したか
Kubernetes での接続先の Host の解決での DNS の問い合わせの数が増えてし
まっていた
● Trailing dotがないとき
○ ドメインの解決候補の数(5回)+ フルドメイン(1回)
○ IPv4 + IPv6 の両方で問い合わせ
■ 6回x2回の問い合わせ -> 12回
● Trailing dotがあるとき
○ Hostに trailing dot を付けて、厳密な問い合わせをするようにした
○ 1回x2回の問い合わせ -> 2回
PHP に限った話ではないが、PHP だと顕著にパフォーマンスに影響のあったDNS
解決問題
29
ホストの指定改善前と改善後
DNSサーバーの RPS
Host指定が多かったエンド
ポイントの Latency
改善前 改善後
改善前
改善後
30
今後、どうなっていくか
Next?
31
今後どうなっていくか
● Log 基盤の最適化
○ 今までログの一部に td-agent を使用していたが、Cloud Logging へ
● Traffic のルートの最適化
○ 今まで Gateway からの Traffic を GCE の Proxy を経由していたが、直接 GKE のアプリケー
ションへ
● Cloud Resource の最適化
○ CPU, Monitor などを適宜ウォッチし、改善の余地がある場所を見つけ、改善
● 柔軟なリリース
○ Canary Release を採用し、より安全なリリースへの改善
まだまだLift & Shift の Shift の最中
32
まとめ
メルカリ最古のモノリスサービスをKubernetes 環境に移行
● なぜ、なにを、どうやって
● フェーズによってMercari-api チームだけでは解決できない問題
○ SREチームとファシリテーションモード 、コラボレーションモード で関わりながら遂行
○ ドメインオーナーが持つべき CronJob の移行は、Mercari-api チームがファシリテートして移
行
他のマイクロサービスと同じ Platform の上に乗ることができた
● チームが開発し、運用し、改善をすることがしやすくなった
● CPU, Memory の最適化の改善を考えた運用ができるようになった
33
We are hiring
Robust Foundation for Speed, Mercari

Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24