Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Podは生きているのにGoだけが落ちる:GOGCとGOMEMLIMITで追うInvisible...
Search
Watanabe Takeshi(Buzz)
September 10, 2026
Technology
1.1k
1
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
370
二重開発負債をOne Application化で解くペアーズのグローバルRe:Architect戦略
tkc66buzz
1
130
Platform Engineeringことはじめ~コミュニティと一緒に新たな旅に出よう!
tkc66buzz
0
160
Other Decks in Technology
See All in Technology
特殊変数大全
dak2
0
170
Mastering Agentic Development: Harness Engineering for Effective Coding Agents
konippi
3
630
Account Factory for Terraformによる 標準化されたアカウント発行の自動化
pensuke628
0
120
3人で1000GPU超を統合運用する?マルチクラウド&オンプレを跨ぐ、構築と運用のリアル!
kazukun0716
2
730
認知負荷を吸収し、プロダクトをまたぐPR Preview基盤の設計事例
taiki45
2
530
KanaAI
shreyas1009
0
110
【Findyテック文化祭ワークショップ】新卒エンジニア&採用担当と作る、 なりたい姿と今やるべき一歩
dip_tech
PRO
0
150
「ピッケル本」日本語版は4.0(第6版)が出版されるべき / pickaxe4-nagoyark05
kakutani
2
310
10年欲しかった音楽管理アプリを、AIと一緒に作りはじめた
judau
1
180
【データ横丁主催】AI Agentがコンテキストを使って仕事をした後、何が残るのか― 組織の経験を次の判断に引き継ぐ「Agent Memory」
shisyu_gaku
2
210
【ゲームメーカーズスクランブル2026】『Shadowverse: Worlds Beyond』UIとアニメーションで実現する最高のユーザー体験を叶えるプロトタイピング
cygames
PRO
1
700
いちAWSエンジニアのAI活用を振り返る #devio2026 / devio osaka 2026 kawahara
masahirokawahara
1
260
Featured
See All Featured
Designing for Timeless Needs
cassininazir
1
510
Optimising Largest Contentful Paint
csswizardry
37
4k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
The Limits of Empathy - UXLibs8
cassininazir
1
690
Faster Mobile Websites
deanohume
310
32k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
2
930
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
3
4.3k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6.2k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
440
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
510
Fireside Chat
paigeccino
43
4k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
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