發表文章

Docker Container 錯誤排查指南

English Abstract: When a container exits with code 137 or 143, it's tempting to assume OOM or a clean shutdown — but both assumptions are often wrong. This post walks through reading docker inspect 's ExitCode and OOMKilled fields correctly, decoding the 128+signal exit code convention, cross-checking kernel-level OOM killer logs with dmesg / journalctl , setting sane memory limits, and the classic shell-form vs exec-form CMD pitfall that silently breaks SIGTERM handling. 當 production 裡的某個 container 無預警停掉, docker ps 已經看不到它, docker ps -a 卻顯示 Exited (137),第一個念頭通常是「是不是被 OOM killer 幹掉了」。但 137 不一定代表記憶體不足,143 也不一定代表你自己下了 docker stop 。這篇文章從 docker inspect 的欄位意義開始,拆解 Exit Code 與訊號的對應關係、怎麼用 dmesg / journalctl 找出真正的 OOM killer 記錄,到設定 memory limit 與讓應用程式正確處理 SIGTERM,建立一套完整的排查流程。 (一)用 docker inspect 看懂 ExitCode 與 OOMKilled container 停掉的瞬間, docker ps -a 只能看到一個簡化過的狀態字串,真正有用的欄位要從 docker inspect 的 State 區塊才看得到。先執行: docker inspect <container_id> --format '{{json...

Google Skills 介紹

圖片
過往使用 Google Cloud 遇到問題時的流程是:先搜尋 Google Cloud Documentation,讀完文件、理解產品行為與限制,再自己轉換成 gcloud、kubectl 或 Terraform 指令,最後執行與驗證。這套模式存在了很多年。但隨著 Codex、Claude Code、Gemini CLI 等 Coding Agent 真正進入工程師的 Terminal,一個新的問題逐漸浮現: 如果實際操作 Cloud Infrastructure 的不只工程師,也包含 AI Agent,那麼官方文件是不是也需要一種「給 Agent 使用的版本」? (本文含聯盟連結。As an Amazon Associate I earn from qualifying purchases.) Google 在 Cloud Next 2026 推出的官方 Agent Skills repository: Google Skills ( github.com/google/skills ),正是在回答這個問題。Google 把 Skill 定義為一種為 Agent 提供額外能力與專業知識的開放格式,也把它描述成針對特定技術或任務設計的 agent-first documentation 。 換句話說, 它不是把 Google Cloud Documentation 再複製一次,而是把產品知識重新整理成 AI Agent 可以理解、判斷,並在適當時機使用的操作知識。 (一)從 13 個 Skills 開始 Google Skills 在 2026 年 4 月 Cloud Next 發表時,規模並不大。第一批只有 13 個 Skills: 產品類:AlloyDB、BigQuery、Cloud Run、Cloud SQL、Firebase、Gemini API、Google Kubernetes Engine(GKE) Well-Architected 類:Security、Reliability、Cost Optimization Recipe 類:Google Cloud Onboarding、Authentication、Network Observability Google 當時就表示這個 repository 會持...

灰度發布 (Progressive Delivery / Gradual Rollout) 是什麼?從 Canary、Blue-Green Deployment 到 Feature Flag

圖片
當新的版本服務要上 production 生產環境時,最直覺的做法就是把所有流量一次全部切過去上線,這是時常看到的,這種做法如果順利的話那就皆大歡喜(實際上不太可能),但只要新版本藏了一個沒測到的 critical bug,等於讓 100% 的使用者同時出問題。這種「一次全量發布」在生產環境裡最省事、卻也最危險,在短期快速迭代開發下很難有 100% 沒有任何缺陷的軟體應用服務,但現在還是時常看到不少企業在做這樣的事情。實際上為了控制這個風險,software engineering 圈子早已發展出「灰度發布」這個概念,底下可細分出 Canary Rollout、藍綠部署(Blue-Green Deployment)、A/B Testing、Feature Flag 幾種做法,但這幾個詞常常被混著用、甚至誤用。這系列文章會先在第一篇把名詞和框架釐清,後面幾篇再針對 AWS EKS + Kubernetes 的具體實作、以及 Web 通訊 App(含 WebSocket 長連線、Android/iOS 行動端)的灰度發布細節展開。在往下讀名詞定義之前,先介紹這系列文章會用的範例情境,方便對照後面出現的程式碼與設定。 本系列的範例情境 這系列文章會用一套虛構的雲端 Web 通訊 App (姑且稱它 ChatApp) 當作貫穿全系列的範例,情境設定盡量貼近實際專案常見的架構,方便對照後面出現的程式碼與設定檔。 ChatApp 提供三種客戶端,使用者可以自由選擇任一種登入使用: iOS App (原生 Swift) Android App (原生 Kotlin) 網頁版 (瀏覽器直接使用的 Web App) 三種客戶端底層都呼叫同一組後端 API,後端部署在 AWS EKS(Kubernetes)上,由幾個主要模組組成: Gateway / Ingress 層 :對外的統一入口,也是本文提到的 Canary 流量分流實際作用的地方 訊息服務(Message Service) :處理聊天訊息的收發,跟客戶端之間走 WebSocket 長連線 認證服務(Auth Service) :處理登入、身分驗證 資料庫(Database) :儲存使用者資料與歷史訊息記錄 後面所有的範例(包含 chatapp-v1 / chatapp-v2 、 ...

新創資安事件觀察:當環境變數變成整個平台的信任根

無意中看到整合 AI Agent 的 PaaS 平台爆發資安事件:攻擊者從一把雲端管理憑證出發,一路打穿到主資料庫,把所有租戶存在環境變數裡的第三方金鑰整批查出來、匯出去。問題的根源不是「被駭」這件事本身,而是架構設計把太多信任集中在同一個地方,環境變數欄位是整個平台唯一的機密儲存層,一次控制平面層級的入侵,就足以讓所有租戶的金鑰在同一時間曝險。由此有一些想法,寫了這篇技術文章探討金鑰該如何儲存。 (一) 從攻擊鏈看金鑰為什麼能走這麼遠 該平台官方在事故發生後陸續更新的攻擊鏈,是這起事件最值得拆解的部分:攻擊者取得一把 AWS 管理層級的憑證,先進入東京的一個共用叢集,再從叢集摸到控制平面的 VPN,最後連上主資料庫,把使用者存在環境變數裡的金鑰查出來、匯出去。時間軸上,平台在 8 月 28 日凌晨建立事故頁,一開始只說是「內部服務憑證」被用來查詢環境變數紀錄;直到隔天晚間,才更新出「AWS 管理憑證 → 共用叢集 → 控制平面 VPN → 主資料庫」這條完整路徑。 如果那把 AWS 憑證的有效權限,本身就同時涵蓋叢集存取、VPN 素材、資料庫連線——那麼圖面上的四個箭頭,實際上可能從頭到尾只被同一個身分牽著走,中間沒有一關是「前一個身分拿不到、簽不出、也改不掉」的獨立授權。 要驗證一組雲端身分的真實影響範圍,不能只看掛了哪些 policy 名稱,而要直接查它的 effective permissions: aws accessanalyzer list-findings \ --analyzer-arn <analyzer-arn> \ --filter '{"resource":{"contains":["<role-or-user-arn>"]}}' 這個指令會列出該身分實際可觸及的資源, 找出哪些資源被過度開放給外部身分, 而不是政策文件上「看起來」授權了什麼——這正是重建這類事故攻擊面時,第一件該做的事。 (二) 問題不在用環境變數,而在把它當成信任根 環境變數本身不是問題。幾乎所有 PaaS——Heroku、Render、Vercel 等——都用環境變數當作應用程式讀取設定的方式,這是產業慣例,沒有問題。真正的問...

熱門文章

Docker 環境下的 Proxy 配置