Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Podは生きているのにGoだけが落ちる:GOGCとGOMEMLIMITで追うInvisible...
Search
Watanabe Takeshi(Buzz)
September 10, 2026
Technology
5
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Podは生きているのにGoだけが落ちる:GOGCとGOMEMLIMITで追うInvisible OOM Killの謎
2026/09/11(金)の登壇資料です。
https://gocon.jp/2026/
https://gocon.jp/2026/timetable/sponsorSlot2/
Watanabe Takeshi(Buzz)
September 10, 2026
More Decks by Watanabe Takeshi(Buzz)
See All by Watanabe Takeshi(Buzz)
プロダクト思考 × 基盤思考を AIで実現する Compound Engineering
tkc66buzz
1
280
二重開発負債をOne Application化で解くペアーズのグローバルRe:Architect戦略
tkc66buzz
1
120
Platform Engineeringことはじめ~コミュニティと一緒に新たな旅に出よう!
tkc66buzz
0
150
Other Decks in Technology
See All in Technology
その指示、Bobにしっかり伝わってる?初心者でも即実践できる プロンプト/コンテキスト設計のコツ
muehara
1
210
現場に行くだけでは足りない——プロダクトエンジニアが業務の流れを捉える観点と、その鍛え方
takumiengineering
0
310
AIとペアプロを始める。人とのペアプロをやめる。ペアプロの良さを改めて知る。もっと好きになった。 / Rediscovering Pair Programming
honyanya
1
280
Kiro Crewしか勝たん!?
miu_crescent
PRO
0
180
Sigmaユーザーのための有用リソース一挙公開 & Sigmaで使えるMCP #sigma_ucj /useful-resources-for-sigma-computing-users-and-mcps-with-sigma
shinyaa31
0
150
Bet AI Day 2026丨Agentは、「金融」という巨大産業の何を変えられるのか
layerx
PRO
0
1.1k
データエンジニアの困りごとをDevinと一緒に解消する
10xinc
2
850
Tab5をRubyで動くパソコンにする
kishima
1
250
Azure App Service / Container Apps の組み込み認証
kuniteru
0
210
20260903 Tokyo Jazug Night #62 | Azure エンジニアよ、 その環境は本当にセキュアか?
olivia_0707
1
630
Benchmarking Vector Databases: pgvector vs. LanceDB
tsho
0
150
Where Is JetBrains AI Heading- — Central CLI, Air Alpha, and the Agentic Development Stack
x5gtrn
PRO
0
140
Featured
See All Featured
The World Runs on Bad Software
bkeepers
PRO
72
12k
The Language of Interfaces
destraynor
162
27k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Accessibility Awareness
sabderemane
1
200
Designing for Timeless Needs
cassininazir
1
470
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
320
Ethics towards AI in product and experience design
skipperchong
2
360
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
530
How to build a perfect <img>
jonoalderson
1
6k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
510
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.5k
Paper Plane (Part 1)
katiecoart
PRO
1
11k
Transcript
Podは⽣きているのにGoだけが落ちる GOGCとGOMEMLIMITで追うInvisible OOM Kill の謎 2026年09⽉11⽇ Go Conference 2026 1
About Me Buzz | Takeshi Watanabe @buzz_tkc Company 株式会社エウレカ Role
Senior Backend Engineer Hobbies トライアスロン, スノボ, サッカー 2
3
2025年4月頃 4
数日に一回の周期で 5xxエラーが不定期に大量発生し始める 5
✕ Killed Go App 5xxエラー発生後に Goのプロセスが落ちる 6
Panic logがでていない OOM Killedもでていない Podも⽣きている Goのプロセスだけ 突然落ちたように⾒える 7
そんな謎が多い障害を 一つ一つ解き明かしていくお話です 8
Agenda 1 前提:ペアーズのArchitectureと発⽣していた問題 2 第⼀の謎:Invisible OOM 3 第⼆の謎:なぜGoがOOMでKillされたのか 4 第三の謎:なぜGCが⾛らなかったのか
5 問題を解いていく 6 まとめ 9
前提:ペアーズの Architectureと 発生していた問題 10
ペアーズの Architecture(簡略版) • GoのアプリケーションがKubernetes(Amazon EKS)上で動いている • 当時は歴史的経緯もあり、NginxとGoが同じコンテナ内で動いていた Go App Nginx
クライアント (iOS / Android / Web) EKS 11
不定期に起きていた問題 • 5xxエラーが急激に増え、Goのプロセスが落ちる • 同じコンテナのNginxは生きている • エラー発生後、何事もなかったようにすぐに復活する Container Nginx Go
App 12
第⼀の謎 Invisible OOM 13
まずは何が起きたかを確認していく Application panic log なし Container Nginxは稼働、Goだけが不在 Kubernetes/Pod OOMKilled ‧Terminatedなし
Host / Kernel TaskOOM / oom-kill / exit code 137 → ここで初めて OOM だったと判明 14
問題があったコンテナを分析する コンテナは技術的には複数プロセスを動かせるが、1コンテナ1プロセス が推奨。当時は歴史的経緯でNginx + Go の複数プロセス構成だった。 コンテナ ✓ Alive PID1
= init (起動シェル / entrypoint) コンテナの「親」プロセス ✓ Alive ✕ Killed Nginx Go App ⼦プロセス 前段のリバースプロキシ ⼦プロセス‧PID≠1 アプリ本体 15
鍵はkillされたプロセスがPID1かどうか Linux OOM Killer はcontainer memory limitを超えた場合、 コンテナ内のメモリを⼀番使⽤しているプロセスを選んで kill する。
PID1(init)をkill → Container ⾃体が終了 → Status = OOMKilled (=普通はこう⾒える) (今回)⾮PID1 のGoプロセスをkill → PID1 と Nginx は⽣存 → Container は落ちない → OOMKilledもTerminatedも出ない NginxとGoが1つのコンテナに同居しているせいで、OOMの発⽣がログか ら⾒えづらい(Invisible)状態になっていた。 16
補⾜:Kubernetesのバージョンで挙動が変わる 必ずGoだけが kill されると⼀般化はできず、Kubernetes / cgroup の バージョンで挙動が変わる。 バージョン 挙動
Kubernetes 1.27 以前 ⼀番メモリを使⽤しているプロセスのみ killされる。 (=Goだけ落ちる、今回のケース) Kubernetes 1.28 以降 (cgroup v2 +memory.oom.group) 同じcgroup内の任意のプロセスがまとめて killされうる。 17
実際に起きていた挙動の流れ ③liveness probeが失敗(Goの応答なし) ① 何かしらの原因で Container OOM Killが⾛り、 Go だけが
kill される。 kubelet Kernel Go App Nginx ⑤コンテナ再起動で復活 ④Nginxがupstream(Go)不在 で502/503を返し続ける ②PID1とNgixが残るためContainer は即時終了しない Client 18
その結果一時的な 5xxエラーが大量発生しては、 コンテナ再起動で復活を繰り返す 19
Invisible OOMの調査結果 謎 調査結果 • Pod/Containerのstatusに OOMが出ない。 • メトリクス上だと⼀瞬5xxエ ラーが発⽣しては、すぐに回
復する挙動が繰り返される。 • Go(⾮PID1)がKernelにOOM Kill されていた。 • PID1とNginxが⽣存しているため Containerは落ちず、OOMが Pod/ContainerのStatusに出ず観 測しづらい状態となっていた。 20
第⼆の謎 なぜGoがOOMでKillされたのか 21
⾒えないスパイクがあったと推測 • 観測グラフ上では container memory limitの超過は確認できなかった • KernelのOOM Logから、メモリの超過が発⽣したのは確実 ◦
短期間のメモリスパイクが発⽣したと推測 コンテナメモリの推移 メモリ 使用量 container memory limit 到達で即 OOM Kill 実際には⾒えていなかった推移 時間 22
スパイクの発⽣源は単⼀ではなかった 数⽇に1回コンテナが落ち、かつ規則性がないことから、単⼀の原因では なさそうだった。 • 重い処理で⼀時的にメモリに負荷がかかる • リクエストが急増する 上記が不定期に重なった際に、トラフィック起因の散発的なスパイクが発 ⽣し、それが原因でOOMが発⽣したと推測。 23
スパイクを防げなかった原因として GOMEMLIMITが未設定だった GOMEMLIMITとは、Go runtime に与える緩い上限。近づくとGCを積極的 に実⾏し、container memory limitの前でメモリを解放させられる。 container memory
limit 到達で即 OOM Kill GOMEMLIMIT (GC line) メモリ 使用量 GOMEMLIMITに近づくとGCを 積極的に実⾏し、OOMを防ぐ 時間 24
なぜOOMが発⽣したかの調査結果 謎 調査結果 • メトリクス上だとcontainer memory limitの超過は観測 できなかった。 • GoのGCが⾛らなかった。
• KernelのOOM Logと突き合わせ て、短期的かつ散発的なスパイ クが発⽣したと予想。 • GOMEMLIMIT未設定が原因で memory limitの前にGCを発⽕さ せられなかった。 25
第三の謎 なぜGCが⾛らなかったのか 26
実はGOGC=500を設定していたが機能していなかった GOGCとは以下の計算式で算出される、次回のGC実⾏を決める指標。 次回GCの⽬標 = live heap ×(1 + GOGC/100) GOGC=500
live heap × 6 GCが稀に発⽕ (CPU負荷↓) メモリ 使用量 GOGC=100 live heap × 2 GCが頻繁に発⽕ (CPU負荷↑) live heap (前回GC後に⽣きていたheap) 時間 27
GCが⾛るより先にcontainer memory limit へ到達した可能性 CPU負荷を抑える狙いでGOGCを⼤きめにしていたが、そのせいで図のように、 GCの⽬標より先にコンテナの上限に達していた可能性がありそうだった。 GOGC=500で、次回にGCが⾛るライン(live heap × 6)
メモリ 使用量 container memory limit ②GCが⾛るのはもっと上 ① OOM Kill 時間 28
なぜGCが⾛らなかったのかの調査結果 謎 調査結果 GOGCを設定しているのにもかか わらず、なぜOOM前にGCが⾛ら なかったのか。 1. live heapが増える 2.
GOGC=500の相対条件 > container memory limit 3. GCより先にcontainer memory limitへ到達 4. Kernel OOM Kill 29
問題を解いていく 30
今まで起きていた問題を整理 問題 起きていた事象 NginxとGoが 同⼀コンテナに同梱 • • 解消法 コンテナメモリのメトリクス NginxとGoを別コンテナ
に分離する。 が見にくい。 PID1がベースアプリにな らない。 Goがcontainer memory limitを 知らない Goはcontainer memory limitを知らずにheapを伸ば し続ける。 GOMEMLIMITを設定す る。 GCが相対値で決まる スパイク時にGCのラインが GOGC=offを設定する。 container memory limitを超え る。 31
今まで起きていた問題を整理 問題 起きていた事象 NginxとGoが 同⼀コンテナに同梱 • • 解消法 コンテナメモリのメトリクス NginxとGoを別コンテナ
に分離する。 が見にくい。 PID1がベースアプリにな らない。 Goがcontainer memory limitを 知らない Goはcontainer memory limitを知らずにheapを伸ば し続ける。 GOMEMLIMITを設定す る。 GCが相対値で決まる スパイク時にGCのラインが GOGC=offを設定する。 container memory limitを超え る。 32
NginxとGoを別コンテナに分離する 1コンテナ1プロセス(PID1に割り当て)に分離。メモリやCPUといったメトリ クスを個別にトラッキングできるようにした。 副次的に今まで動いていなかったGraceful Shutdownも動くようになった。 Nginx Go App EKS Nginx
Go App EKS 33
今まで起きていた問題を整理 問題 起きていた事象 NginxとGoが 同⼀コンテナに同梱 • • 解消法 コンテナメモリのメトリクス NginxとGoを別コンテナ
に分離する。 が見にくい。 PID1がベースアプリにな らない。 Goがcontainer memory limitを 知らない Goはcontainer memory limitを知らずにheapを伸ば し続ける。 GOMEMLIMITを設定す る。 GCが相対値で決まる スパイク時にGCのラインが GOGC=offを設定する。 container memory limitを超え る。 34
GCのタイミングをGOMEMLIMITに⼀本化する 従来:GOGC=500 だけ 今回:GOGC=off + GOMEMLIMIT 次回GCの⽬標 = live heap
×(1 + GOGC/100) • • live heapに応じてGCのラインが 相対的に動く スパイク時にGCラインが container memory limitを超え うる。(GCより先にOOM Killが 発⽣) • 相対的なGCラインは使⽤しない • GOMEMLIMITに近づいたら、Go runtimeにGCを積極的に実⾏さ せる 35
Kubernetesのコンテナ上限から逆算してGCを制御 Kubernetesのcontainer memory limitの⼿前にGCラインを設定し、スパ イクが発⽣してもOOM前にGCを⾛らせる戦略。 GOMEMLIMIT(GC line) = container memory
limit × 0.8 memory limit メモリ 使用量 GCが積極的に発動するエリア memory limit到達までの余白を作成 ※container momory.requests を applicationのmemory limitとしている GOMEMLIMIT(GC line) memory limit × 0.8 時間 36
上記の改善を⾏った結果 OOMが起きることもなくなり、メモリ使⽤量も安定し、リソースが有効 に活⽤される平⾏線のグラフを実現できた。 37
まとめ 38
まとめ 謎 原因 改善 第⼀の謎 Invisible OOM NginxとGoが同一コンテナに同梱。Go がOOM KillされてもContainerは生存
し、StatusにOOMが出ない。 NginxとGoを別コンテナに分離。 メトリクスを個別に監視。 第⼆の謎 なぜOOM? GOMEMLIMITが未設定。 Goがcontainer memory limitを認識 せず、memory limit前にGCを実⾏で きない。 GOMEMLIMITを設定。 container memory limitの⼿前 でGCを⾛らせる。 第三の謎 なぜGCが⾛ら ない? GOGC=500はlive heap基準の相対判 GOGC=off + GOMEMLIMITに 定。GCラインがcontainer memory limit 一本化。相対値ではなく上限基 を超え、GCより先にOOMが発生。 準でGCさせる。 39
We’re hiring! Career Site 40