メインコンテンツへスキップ
  1. Posts/

コンテナにおける Go のサイレント・クライシス

·130 文字·1 分·
Go Kubernetes Runtime Performance
アミット・デイブ
著者
アミット・デイブ
ソフトウェアエンジニアで、しっかりしたシステムを作るのが得意です。難しい問題をわかりやすくすることも得意です。好きなことは、分散システムクリーンアーキテクチャ、そしてオープンソースプロジェクトです。仕事以外では、山を歩くことや日本語の勉強、そしてstderrなどから学ぶことを楽しんでいます。
目次

「動いている」が「最適ではない」という恐怖
#

多くの SRE やバックエンドエンジニアにとって、Kubernetes へのデプロイは日常的なルーチンだ。resources.limits.cpu を設定し、Pod が正常に起動してヘルスチェックが通れば、概ね「成功」と見なされる。

しかし、ここには罠がある。Go のランタイムは、ホストマシンの物理リソースを基準に設計されており、コンテナによる「擬似的な制限(CPU クォータ)」を完全には理解していない。この認識の乖離が、サイレントにパフォーマンスを蝕む「サイレント・クライシス」を引き起こす。

動画で見る: この記事の内容を YouTube で解説しています。

CPU クォータという名の錯覚
#

Kubernetes の CPU リミットは、実際には Linux カーネルの CFS (Completely Fair Scheduler) クォータによって制御されている。例えば cpu: 500m と設定した場合、それは「1 秒間のうち 0.5 秒間だけ CPU を使用して良い」という時間制限を意味する。

ここで問題となるのが Go の GOMAXPROCS だ。デフォルトでは、Go はホストマシンの論理コア数をすべてカウントし、それに基づいた並列度でスケジュールを行う。

  • ホスト: 64 コア
  • Pod リミット: 0.5 コア (500m)
  • GOMAXPROCS: 64 (デフォルト)

この状態で Go ランタイムは 64 個の OS スレッドを効率的に回そうと試みるが、カーネルによって 0.5 秒で強制的にスロットリング( throttling)される。結果として、コンテキストスイッチが激増し、テールレイテンシ(P99)が跳ね上がる。

メモリの誤解と OOMKill の正体
#

CPU だけでなく、メモリ管理にも深い溝がある。Go の GC (Garbage Collector) は、デフォルトでは利用可能なメモリ全体を基準に動作する。しかし、コンテナ環境では cgroups によるハードリミットが存在する。

多くの開発者が、「メモリ使用率を 80% 程度に抑えれば安全だ」という曖昧な経験則に頼っている。だが、Go のメモリ管理は単純な「使用量」だけでは決まらない。GC のトリガータイミングと、一時的に急増するアロケーション、そしてコンテナのメモリリミットが衝突した瞬間、カーネルは容赦なく OOMKill を執行する。

検出のギャップ:なぜ気づかないのか?
#

最悪なのは、平均的なメトリクス(Average CPU/Memory)ではこの問題が表面化しにくいことだ。

  • CPU Throttling: Prometheus の CPU 使用率グラフは「低く」見えるが、実際にはクォータに達して停止している時間がある。
  • GC ポーズ: 平均レスポンスタイムは正常だが、特定のタイミングで発生する GC ストールが、分散システムにおけるカスケード失敗のトリガーとなる。

次回、解決への道へ
#

この「サイレント・クライシス」を脱するには、Go ランタイムをコンテナの現実に適応させる必要がある。

次回は、この問題の核心である GOMAXPROCS を解剖する。特に Go 1.25 で導入された新しい丸めロジックが、どのようにマルチコアホストにおける GC ストールを防ぐのか。そして、なぜ単なる「整数への切り捨て」では不十分なのかを深掘りする。


「コンテナの中の Go」シリーズ: イントロ — サイレント・クライシス · 1. GOMAXPROCS の謎を解く · 2. 圧力下でのガベージコレクション · 3. GC ポーズとレイテンシ · 4. コンテナ・デバッグの実践ワークフロー

関連記事

AIエージェントのタスク管理、GitHub Issuesでやってみた
·678 文字·4 分
Ai Go Automation Github Devops
そのプライマリキーがボトルネックだ(スケーリングじゃ直らない)
·701 文字·4 分
Postgresql Performance B-Tree Uuid Database-Design
天井は同じだ。床が上がっただけ。
·87 文字·1 分
Devlog Ai Software-Engineering Economy Future-of-Work
Goでモジュラーモノリスを設計する:構成、境界、実践パターン
·529 文字·3 分
Go Architecture Golang Modular-Monolith Architecture
Goプロジェクトの構成方法(実用的な慣習、ルールじゃない)
·443 文字·3 分
Go Architecture Golang Project-Structure Monolith Best-Practices