大規模WebサービスにおけるKubernetes移行:ゼロダウンタイムを実現した戦略的アプローチ
現代のインフラエンジニアにとって、レガシーなモノリス構成からコンテナオーケストレーション環境への移行は、避けては通れない技術的挑戦です。本稿では、月間数億PVを誇る大規模Webサービスにおいて、TerraformとAmazon EKS(Elastic Kubernetes Service)を駆使し、サービス停止時間を限りなくゼロに近づけながら移行を成功させた事例を詳細に解説します。
プロジェクトの背景と課題
移行対象となったシステムは、長年運用されてきたEC2インスタンス上のPHPアプリケーションでした。主な課題は以下の3点です。
1. スケーリングの遅延:突発的なトラフィック増加に対し、AMIのビルドとインスタンス起動が追いつかず、ピークタイムにレスポンス遅延が発生。
2. デプロイの属人化:複雑なシェルスクリプトによるデプロイ手順がブラックボックス化しており、CI/CDのパイプライン構築が困難。
3. コストの最適化:リザーブドインスタンスの柔軟性が低く、リソースの過剰なプロビジョニングが利益を圧迫。
これらを解決するため、我々は「インフラのコード化(IaC)」と「宣言的なコンテナ管理」を軸としたKubernetes移行プロジェクトを立ち上げました。
技術選定と設計のポイント
移行戦略として採用したのは「Blue/Greenデプロイメントを用いた段階的移行」です。一気に全トラフィックを切り替えるのではなく、Route 53の加重ルーティングを利用して、トラフィックを1%、5%、20%、100%と段階的にEKS側へ流す手法をとりました。
また、ネットワーク設計においては、CiliumをCNIとして採用しました。標準的なVPC CNIと比較して、eBPFを活用した高い可観測性と、高度なネットワークポリシー制御が、セキュリティ要件の厳しい本プロジェクトにおいて決定打となりました。
サンプルコード:TerraformによるEKSクラスター定義の抜粋
以下は、インフラの再現性を確保するために作成したTerraformコードの一部です。モジュール化を行い、環境ごとの差異を最小限に抑えています。
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "19.0.0"
cluster_name = "production-cluster"
cluster_version = "1.27"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
eks_managed_node_groups = {
general = {
min_size = 3
max_size = 10
desired_size = 3
instance_types = ["m6i.large"]
capacity_type = "SPOT" # コスト削減のためスポットインスタンスを活用
}
}
manage_aws_auth_configmap = true
}
resource "kubernetes_horizontal_pod_autoscaler" "app_hpa" {
metadata {
name = "api-hpa"
namespace = "production"
}
spec {
max_replicas = 20
min_replicas = 5
scale_target_ref {
api_version = "apps/v1"
kind = "Deployment"
name = "api-deployment"
}
target_cpu_utilization_percentage = 60
}
}
移行のプロセスとトラブルシューティング
移行プロセスにおいて最も苦労したのは「ステートフルなデータの整合性」です。セッション情報がRedisに依存していたため、移行期間中はEC2側とEKS側でRedisクラスターを共有する必要がありました。ここで発生したのが「接続数の枯渇」です。
解決策として、コネクションプールを適切に設定し、さらにRedisのクライアントライブラリを最新化することで、レイテンシを5ms以下に抑えることに成功しました。また、コンテナイメージのビルド時間を短縮するため、マルチステージビルドを導入し、最終的なイメージサイズを800MBから150MBまで削減しました。これにより、Podの起動速度が劇的に向上し、オートスケーリングの応答性が改善しました。
実務アドバイス:エンジニアが直面する壁を越えるために
このプロジェクトを通じて得られた教訓は、「技術よりも組織の合意形成が重要である」という点です。
1. 監視体制の刷新:
Kubernetesに移行すると、従来の「サーバー監視(CPU、メモリ)」だけでは不十分です。「Podの再起動回数」「イベントログ」「メトリクス」を統合的に監視するため、DatadogやPrometheus + Grafanaの導入は必須です。特に、カスタムメトリクスを用いたHPA(Horizontal Pod Autoscaler)の調整は、本番環境での試行錯誤が不可欠です。
2. チームのスキルセット:
インフラチームとアプリケーションチームの境界を曖昧にする「Platform Engineering」の考え方を取り入れました。開発者が自分でマニフェストを修正できる環境(開発用クラスター)を用意し、デプロイに対する心理的障壁を下げることに注力しました。
3. 「逃げ道」の確保:
移行の際、常に「即座にEC2へ切り戻せる構成」を維持しました。具体的には、ロードバランサーのターゲットグループを動的に切り替えられるよう、IaCパイプラインを準備していました。この安心感が、最終的な決断を加速させます。
まとめと今後の展望
本事例では、単なるコンテナ化に留まらず、インフラの運用負荷を大幅に軽減し、開発者のデプロイ体験(DevEx)を向上させることに成功しました。結果として、月間のデプロイ回数は以前の10倍に増加し、障害発生時の切り戻し時間は平均30分から3分へと短縮されました。
しかし、Kubernetesの世界に終わりはありません。次は、GitOps(ArgoCD)による完全自動化と、Service Mesh(Istio)を用いたカナリアリリースの自動化を進める予定です。技術は常に進化しますが、インフラエンジニアの本質は「ビジネスの成長を阻害しない、堅牢で柔軟な基盤を提供し続けること」にあります。
今回の移行事例が、現在進行形で同様の課題と向き合っているエンジニアの皆様にとって、何らかの指針となれば幸いです。システムは生き物であり、その成長を支えるのは常に現場のエンジニアの知見と、失敗を恐れない挑戦心です。これからも、より良いアーキテクチャを追求し、技術の最前線を駆け抜けていきましょう。

コメント