開発ノート:モノリシックPHPアプリからマイクロサービスへ―Docker×Kubernetes移行のリアル

はじめに
私が技術リーダーを務めたプロジェクトでは、長年運用してきたモノリシックPHP/Laravelシステムを、DockerとKubernetesを活用したマイクロサービスアーキテクチャへ全面移行しました。
従来のシステムは、市場拡大に伴うトラフィック増加や新機能追加のたびに、リリースリスクが高まり、開発会社への発注費用も年々膨れ上がっていました。
要件定義の段階で「スケーラビリティ」「デプロイの高速化」「コスト最適化」がキーワードとなり、経営層には移行にかかる予算(費用)感とROIを説得する必要がありました。
本記事では、移行決定の背景から開発会社選び、予算策定、移行中に直面したトラブルとその解決、そして成功のポイントまで、開発ノートとしてリアルな教訓を共有します。
同じ「システム刷新」「クラウドネイティブ化」を検討中の技術リーダーやPMの方々の参考になれば幸いです。
プロジェクト背景と課題認識
当初のモノリシックPHPシステムは、ECサイトとして10年以上稼働し、売上規模は年間数十億円に達していました。
しかし、次の課題が顕在化していました。
-
スケール限界:ピークトラフィック時にECカート処理がボトルネック化し、サーバー台数を増やしても対応しきれず遅延が発生
-
リリースリスク:1つのコードベースを全機能で共有しているため、わずかな変更でも全体テストに時間がかかり、発注費用と開発会社のコストが増大
-
機能追加の遅延:新規機能開発を要件定義からリリースまで3カ月以上要し、市場機会を逃すことが増加
-
コスト増:インフラコストと開発会社報酬の両面で、毎年20%超の費用増加が続いていました
経営層への説明資料では、「1機能あたりのリリース工数」「障害発生時の復旧工数」「年間インフラ費用」のデータを示し、マイクロサービス化によるコスト抑制効果を試算。
移行初期のPoCとして約100万円の予算でDocker化を小規模に実施し、「コンテナ起動時間5秒」「負荷テストでスループット20%向上」を証明しました。
このPoC結果を根拠に、約1000万円の移行予算(費用相場)を経営層に承認してもらい、開発会社への正式発注フェーズに進みました。
モノリシックPHPシステムの限界
従来システムは、MVCフレームワークの上に複数の内部ライブラリ、バッチ処理、管理画面が混在しており、
コードベースは50万行を超えていました。ビルド・テスト・デプロイは全て手動で行い、
あるリリースでは「DBマイグレーション後の不整合」に気づかず、ECサイトが半日ダウンし、追加の保守費用と開発会社への緊急発注で200万円超が発生しました。
こうした運用コスト増が「予算圧迫」の最大要因となり、早めのアーキテクチャ刷新が必須に。
移行要件の洗い出しでは、既存のバッチ処理をどのサービスに分離するか、キャッシュ層はRedisかMemcachedか、ログ集約はElasticsearchを使うかを詳細に検討。
この要件定義段階での曖昧さが、追加費用の最大リスクとなるため、開発会社選びの際には必ず「要件定義~設計フェーズでの工数内訳」を明確に提示してもらうことが重要です。
マイクロサービスアーキテクチャ検討
移行プロジェクトの設計フェーズでは、以下のサービス単位で分割案を作成しました。
-
ユーザー管理サービス:認証・権限・会員情報
-
商品カタログサービス:SPU、カテゴリ、検索連携
-
カート&決済サービス:カート状態管理、決済ゲートウェイ連携
-
注文履歴サービス:注文処理、配送状況確認
-
バッチ処理サービス:在庫連携、メール通知
各サービスはDockerコンテナ化し、GitLab CI/CDでイメージを自動ビルド。Kubernetes上のNamespace単位で分離デプロイします。
このアーキテクチャ設計により、開発会社へ発注する場合も「1サービスあたりの開発工数×単価」で見積もりを取りやすくなり、予算管理が容易に。
たとえば、1サービスの初期実装が80工数(相場:120万~160万円)と試算される場合、5サービスで600万~800万円程度の費用感が得られます。
RFPの作成時にはこの分割案を明示し、相見積もりで相場と予算をすり合わせることが成功のポイントでした。
コンテナ化とKubernetes導入
Docker化では、既存PHPアプリを公式PHPイメージをベースに、
必要な拡張モジュールやComposerインストール処理をDockerfileに記述。
最初のPoCでは「ベースイメージ選び」「マルチステージビルド」「キャッシュ活用」によって、ビルド時間を50%短縮しました。
KubernetesクラスタはAWS EKSを採用し、ノードグループを分散配置。
Helmチャートを用いて各サービスのDeployment、Service、Ingressリソースを定義し、
CanaryリリースとBlue/Greenリリースを容易に実行可能にしました。
発注時の工数見積もりとしては、
-
Dockerfile作成:10工数
-
Helmチャート実装:20工数
-
CI/CDパイプライン構築:15工数
-
Canary/BlueGreen設計:10工数
計55工数(相場:80万~100万円)を想定。
これらをRFPに入れることで、後から追加されがちなインフラ面の費用を事前に予算化でき、無駄な追加発注を防げました。
マイクロサービス実装フェーズの進め方
コンテナ化とKubernetesクラスタの準備が整った後、本格的なマイクロサービス実装に入りました。各サービスは独立リポジトリで管理し、GitLab CI/CDパイプラインでビルド・テスト・デプロイを自動化します。
具体的には以下の流れで進めました。
-
APIモック作成:バックエンドチームが各サービスのAPIをOpenAPI仕様で定義し、モックサーバーを自動生成。フロントエンドや他サービスの開発と並行可能に。
-
ユニットテスト整備:PHPUnitでサービス固有のビジネスロジックをカバー。カートサービスでは70%以上のカバレッジを目標に設定し、テスト不備による発注後の手戻りを防止。
-
統合テスト:Postman/NewmanやKarateを活用し、サービス間のリクエスト・レスポンスシーケンスを自動テストに組み込む。
-
Contract Test:Pactを導入し、API消費側と提供側の契約テストを実行。API変更時のスコープ外影響を早期に検知。
-
ステータスモニタリング:Kubernetes上にPrometheus+Grafanaを構築し、各PodのCPU/メモリ使用率、リクエストレイテンシー、エラーレートを可視化。
このようなテストとモニタリングの充実により、リリースサイクルを2週間単位で回しつつ品質を担保できました。CI/CDパイプラインの構築は約25工数、相場40万~50万円で発注しました。
テストとCI/CDパイプラインの改善ポイント
初期のCI/CDパイプラインではジョブが連続実行されるたびに全テストを回すため、ビルド時間が30分を超えていました。
これを改善するため、以下の対策を講じました。
-
並列実行:ユニットテストと統合テストを同時に実行することで、総テスト時間を50%削減。
-
キャッシュ活用:ComposerのキャッシュやDockerレイヤーキャッシュを有効化し、依存関係の再取得時間を短縮。
-
部分的テスト:変更のあったサービスのみテストを実行するGit diff連携スクリプトを導入。
-
ステータスバッジ:READMEにビルド・テストのステータスバッジを表示し、開発会社との透明性を高める。
これにより、ビルド・テストの平均時間を15分まで短縮し、デプロイまでのリードタイムを2時間→1時間に改善しました。
テスト環境構築と改善工数は20工数程度、相場30万~40万円で対応しています。
モニタリング・オートスケーリングとコスト最適化
マイクロサービス化後、インフラコストは従来の専用サーバー10台分から、Kubernetesノード3台+スポットインスタンスで運用可能になり、月額約30万円→20万円に削減できました。
オートスケーリングを設定し、以下を実施しています。
-
Horizontal Pod Autoscaler (HPA):CPU使用率が60%を超えたらPodを自動増加、負荷平準化。
-
Cluster Autoscaler:K8sリソース不足時にEKSノードを自動追加/削除し、必要なリソースだけ課金。
-
Vertical Pod Autoscaler (VPA):メモリリークやバースト負荷を検知し、自動的にPodリソースを調整。
監視ではアプリケーションログをFluentd→Elasticsearchに集約し、Kibanaで検索・可視化。
アラートはSlack連携を行い、障害対応の平均MTTR(復旧時間)を1時間→20分に短縮しました。
この運用最適化により、追加インフラ費用を月5万円以下に抑えつつ、品質を担保しています。
トラブルと解決事例
移行中、あるマイクロサービスで「メモリリーク→OOMKill」が頻発し、Podが再起動する問題が発生しました。この原因は、長時間実行のバッチタスク内でPDO接続を閉じ忘れたためでした。
対策として、以下を実施しました。
-
コード修正:バッチ処理外部でのDB接続は都度クローズするよう修正。
-
サイドカーコンテナ:Envoyサイドカーを導入し、DBコネクションの最大数を強制制御。
-
リソースリミット:Podごとにrequests/limitsを明示し、OOMKill前にHorizontal Pod Autoscalerでスケールアウト。
この対応には約15工数、相場約25万円を要しましたが、発注時に「運用トラブル対応用予備工数」を20工数分設定していたため、予算内に収められました。
プロジェクト成果とROI評価
移行完了後の主な成果は以下です。
-
ダウンタイム:年10時間→年1時間未満(90%削減)
-
リリースサイクル:3カ月→2週間(6倍高速化)
-
インフラ費用:月30万円→20万円(33%削減)
-
開発会社費用:年間発注費用10%減(長期的コスト削減)
-
ユーザー満足度:90点→98点(アンケート調査より)
これらを金額に換算すると、年間ベースで約500万円のコスト削減効果が見込まれ、移行コスト(1000万円)を2年で回収可能と試算しています。
開発ノートまとめと次への課題
本開発ノートでは、モノリシックPHPアプリからDocker×Kubernetesによるマイクロサービス移行のリアルなプロセスと教訓を共有しました。
ポイントは「要件定義段階でサービス分割を明示」「CI/CDとテストを自動化」「運用トラブル対応用の予備工数を確保」「オートスケーリングでコスト最適化」です。
次のフェーズでは、**サービスメッシュ(Istio/Linkerd)**の導入や、GitOpsによるさらに厳格なIaC運用を検討中です。
同じくマイクロサービス化やクラウドネイティブ化を検討する技術リーダーの皆様は、ぜひ本記事のノウハウを発注先とのコミュニケーションや予算策定にお役立てください。