Skip to content
Kembali ke senarai artikel
infra14分

Kubernetes本番運用2026: 我々が学んだ教訓

Kubernetes Production 2026: Lessons We Learned

金 東勲 / Kim Dong-hoonSecurity Engineer
2026-03-2714分
KubernetesK8sAutoscalingObservabilityCost Optimization

Artikel ini diterbitkan dalam Bahasa Jepun. Ringkasan dalam Bahasa Melayu di bawah:

Kubernetes Production 2026: Lessons We LearnedKubernetes本番運用3年目で学んだ教訓を赤裸々に共有。オートスケーリングの罠、Observabilityの構築、コスト最適化、実際に起きたインシデントの事後分析。

3年間のKubernetes運用を振り返る

KGAがKubernetesを本番環境に導入して3年が経過した。EKS(AWS)をメインに、一部GKEも運用している。この3年で大小合わせて23件の本番インシデントを経験し、そのうち5件はSeverity 1(サービス全停止)だった。この記事では恥を忍んで失敗談を共有し、同じ轍を踏まないための教訓をまとめる。

教訓1: HPAの設定ミスは致命的

Horizontal Pod Autoscaler (HPA)の設定ミスで2回のSev-1インシデントが発生した。

  • 回目: CPU使用率80%でスケールアウトするように設定したが、CPU requestsを実際の使用量より大幅に低く設定していた。結果、実際のCPU使用率が80%に達してもHPAのメトリクスでは200%と表示され、Podが際限なく増殖。最終的にNodeのリソースを食い尽くしてクラスタ全体がダウンした。

教訓: CPU/memory requestsは実際の使用量の80%を設定し、limitsはrequestsの150%にする。この比率はKGAの3年間の運用で最も安定した値だ。

  • 回目: スケールダウンのstabilizationWindowSecondsを短くしすぎた(60秒)。トラフィックのスパイクに対してスケールアウト→スケールイン→スケールアウトが激しく繰り返され、コネクションの断絶が多発。300秒に延長して解決。

教訓2: PDBを設定しないと痛い目に見る

PodDisruptionBudget (PDB)を設定していなかったために、Nodeのローリングアップデート中に全Podが同時に退避され、サービスが5分間完全停止した。maxUnavailable: 1 または minAvailable: N-1 のPDBを全Deploymentに設定することを義務化した。

これは基本中の基本だが、KGAでは初期のスピード優先でスキップしてしまった。Infrastructure as Codeで全リソースを管理し、PDBのないDeploymentはCI/CDパイプラインでrejectする仕組みを導入した。

教訓3: Observabilityは投資ではなく保険

KGAのObservabilityスタックは、Prometheus + Grafana(メトリクス)、Loki(ログ)、Tempo(トレース)のGrafana三兄弟構成。導入コスト(人件費込み)は約500万円、月間運用コストは約30万円。高く感じるかもしれないが、Observabilityなしで発生していたインシデントの平均復旧時間は4時間。導入後は平均22分に短縮された。月1回のSev-1インシデントの機会損失を考えると、ROIは1ヶ月で回収できている。

具体的に役立ったダッシュボードを紹介する。Golden Signals(レイテンシ、トラフィック、エラー率、サチュレーション)のリアルタイム表示。Pod restart historyとOOMKilled検出。Node別のリソース使用率ヒートマップ。APIエンドポイント別のp50/p95/p99レイテンシ。

教訓4: コスト最適化は継続的な取り組み

Kubernetesのコストは放置すると際限なく膨らむ。KGAのEKSクラスタの月額費用推移。導入直後: $3,200/月。6ヶ月後: $8,500/月(リソース要求の見直しなし)。最適化後: $4,100/月。

最も効果があったのはSpot Instanceの活用だ。ステートレスなワークロード(Webサーバー、APIサーバー)をSpot Instance上で動かし、Nodeの中断に対してはPDBとgraceful shutdownで対応。これだけで月額の35%を削減した。

次に効果があったのはright-sizingだ。Kubecostを導入してPod単位のコストと実際のリソース使用量を可視化。多くのPodがrequestsの20-30%しかリソースを使っていないことが判明し、requestsを適正値に調整。これで月額の20%を削減。

教訓5: Namespaceの分離戦略

最初は全環境(dev、staging、production)を1クラスタのNamespace分離で運用していた。コスト的には効率的だが、dev環境のメモリリークがproduction Nodeのリソースを圧迫するインシデントが発生。以後、productionは独立クラスタに分離した。

ResourceQuotaとLimitRangeでNamespace単位のリソース制限は設定していたが、Node自体は共有だったため、Nodeレベルのリソース競合を防げなかった。Namespace分離は論理的な分離であり、物理的な分離ではないことを身をもって学んだ。

実際のインシデント事後分析

  • 年9月のSev-1インシデントを詳細に共有する。発生: 金曜日18:00(よりによって)。症状: 全APIがタイムアウト。原因: CronJobで実行していたバッチ処理がメモリリークし、OOMKillerが関連のないPodを道連れにした。対応: 手動でCronJobのPodを削除し、影響を受けたPodが再起動するまで23分のダウンタイム。再発防止: CronJobを専用NodePoolに隔離、メモリlimitsの厳格化、OOMKillerの挙動監視アラート追加。

このインシデントから学んだ最大の教訓は「バッチ処理とオンラインサービスは物理的に分離せよ」だ。NodePoolを分け、taint/tolerationで確実に分離する。論理的な分離だけでは不十分。

技術的な課題を一緒に解決しませんか?

KGA IT Solutionsは、AI・クラウド・DevOpsの専門チームがお客様の課題に最適なソリューションを提供します。

お問い合わせ