etcd v3.7.0 發布:串流讀取 RangeStream 解決大範圍查詢的記憶體尖峰
etcd-io/etcd GitHub Release · 2026-07-08
背景
etcd 專案的 SIG etcd 團隊於 2026 年 7 月 8 日發布 etcd v3.7.0,並由 Kubernetes 官方部落格同步公告。這個版本最受矚目的改動是新增 RangeStream 串流查詢機制,同時完成延宕已久的舊版 v2store 移除與 protobuf 函式庫替換。etcd 是 Kubernetes 控制平面儲存所有叢集狀態的後端,任何讀取路徑的行為變化都會直接影響 API Server 的延遲與記憶體使用量。
核心改動:RangeStream
現有的 Range RPC 是一次性回傳整包結果,這代表 KV 陣列、序列化後的 protobuf、gRPC buffer 必須同時留在記憶體中,範圍越大、鍵值越多,尖峰記憶體就越高。分頁查詢也有隱藏成本:每一頁都得重新走一次 B-tree 索引來計算總筆數,等於把單頁成本放大成 O(全部鍵值數)。RangeStream 沿用既有的 RangeRequest 訊息格式,改用 gRPC server-streaming 把結果切成多個 chunk 陸續送出,並採用自適應 chunk 大小,同時整個串流過程都固定在單一 MVCC revision 上以維持一致性,細節可參考 RangeStream 的 Kubernetes KEP。
service KV {
rpc RangeStream(RangeRequest)
returns (stream RangeStreamResponse) {}
}
message RangeStreamResponse {
RangeResponse range_response = 1;
}中間的 chunk 只帶鍵值對,最後一個 chunk 才附上叢集標頭(ClusterId、MemberId、RaftTerm、Revision)與筆數,而筆數是串流過程中邊走邊算出來的,不必事先掃過整棵索引樹。伺服器端則是每個 chunk 各自開一個短命的 bbolt 唯讀交易;如果串流途中剛好發生 compaction,伺服器會回傳 ErrCompacted,交給客戶端重試。這個 RPC 已規劃在 Kubernetes v1.37 透過 EtcdRangeStream feature gate(Beta)啟用,watch cache 初始化會優先走 RangeStream,遇到 etcd 3.6 以前版本回傳 Unimplemented 時則自動退回舊的 Range,不需要手動介入。
其他效能改動
除了 RangeStream,這個版本還打包了多項效能修正。keys_only 查詢現在只讀記憶體索引,不再去 bbolt 撈序列化後的 value,除非查詢要求依 value 排序(PR #21791)。租約(lease)路徑也做了兩項調整:LeaseRevoke 請求在系統過載時會被優先處理,確保租約能準時到期(PR #20492);新增的 FastLeaseKeepAlive 則讓續約可以跳過等待 applied index,加快回應(PR #20589)。另外,watch 使用的 interval 搜尋改成依右端點切分同左端點的區間,讓大量併發 watch 時的 find() 效能提升(PR #19768)。
- 移除舊版 v2store:v2discovery(
#20109)、client/v2(#20117)、v2 request 與apply_v2.go(#21263)全數移除,etcd 現在完全從 v3store 啟動 - protobuf 從
gogo/protobuf遷移到官方google.golang.org/protobuf(PR#14533) - 相依套件升級:
bbolt v1.5.1、raft v3.7.0
影響範圍
v2store 的全面移除是不可逆的破壞性變更,仍在用舊版 v2 API 或 client 的部署必須先遷移。RangeStream 目前是新增能力而非取代既有 Range RPC,Kubernetes 端要等 v1.37 的 EtcdRangeStream feature gate 開放後才會真正吃到記憶體與延遲的改善;對自行呼叫 etcd gRPC API 或使用 etcdctl 做大範圍掃描的應用來說,現在就可以直接改用 RangeStream。
原始來源:etcd v3.7.0 Release Notes、CHANGELOG-3.7.md、RangeStream KEP
用 NGINX 與 OpenTelemetry 幫 AI Agent 畫一條網路邊界
CNCF Blog · 2026-07-08
背景
CNCF 部落格於 2026 年 7 月 8 日刊出一篇文章,處理的是一個很具體的疑慮:把自主行動的 AI agent 放進網路裡,卻不知道它實際上會打去哪裡、做什麼。文章作者引用一位與會者的話,直言「不會把 agent 放進自己的網路,因為根本不知道那東西實際上在做什麼」。這篇文章提出的做法不是去理解或限制 agent 的「意圖」,而是把網路存取本身變成可觀測、可強制的邊界,是防禦深度(defense-in-depth)裡偏基礎建設面的一層。
架構設計
NGINX 在這個架構裡身兼兩個角色:對內是終止 TLS 的反向代理,對外則是唯一被允許的正向代理出口。搭配 iptables 規則封鎖所有非經 NGINX 的 egress 流量,邊界的強制力就變成架構層級的性質,而不是依賴應用程式自己乖乖遵守的政策。示範設定是用 ConfigMap 只放行 nginx.org 與 duckduckgo.com,其餘網域一律擋下。可觀測性的部分則交給 NGINX 原生的 ngx_otel_module,它會替每一筆請求送出 OpenTelemetry span,讓使用者互動與 agent 對外呼叫可以在既有的追蹤工具鏈裡被關聯起來,細節可參考官方模組文件。模組主要靠 otel_trace(開關與取樣條件)與 otel_trace_context(propagate 或 inject,控制要不要延續上游的 trace context)兩個指令設定,也可以搭配 split_clients 做比例取樣。
驗證環境
文章描述的概念驗證是在單節點 Kubernetes 叢集上跑四個 workload:NGINX、負責跑模型的 Ollama、AI agent 框架 OpenClaw,以及收集追蹤資料的 OpenTelemetry Collector。這套組合是在消費級 NVIDIA GPU 上做的示範,但作者強調同樣的邊界模式可以從邊緣裝置一路套用到企業級系統,相關的 NGINX 專案原始碼可參考 nginx/nginx。
影響範圍
作者也坦承這個方案的侷限:代理層本身變成一個新的營運元件,需要被額外保護與監控,而且這只是防禦深度裡的一層,並不能取代身分驗證、政策管理、runtime 安全與應用層防護。換句話說,NGINX 加 OTel 的組合解決的是「這個 agent 到底連去了哪裡、我看不看得到」,而不是「這個 agent 的行為是否符合預期」這個更難的問題。
GitHub 用 Agentic Workflows 自動產生跨 repo 文件,合併時間中位數壓到 44.8 小時
GitHub Blog · 2026-07-08
背景
GitHub 工程部落格於 2026 年 7 月 8 日刊出一篇文章,說明內部 Aspire 團隊如何用 GitHub Agentic Workflows(gh-aw)把「產品程式碼合併」跟「文件更新」這兩件事接起來。過去文件更新得靠工程師合併後另外想起來要寫文件,現在改成產品 PR 一合併就自動生成文件 PR,草稿狀態、指定原 PR 的審核者覆核,整個機制跑在 microsoft/aspire 與 microsoft/aspire.dev 兩個 repo 之間。
運作機制
核心是一支叫 pr-docs-check.md 的 workflow,只在 pull_request: closed 事件、且 merged == true、目標分支是 main 或 release/* 時才觸發。要寫進哪個文件分支,靠一段固定的 bash 腳本依優先序判斷:先看 PR 的 milestone 標題對應表(例如 13.4 對應到 aspire.dev 的 release/13.4)、再看關聯 issue 的 milestone、接著看 PR 的 base ref 是否符合 release 命名規則,最後才退回 main。這一段刻意寫死,不讓 agent 自己決定要寫去哪個分支。
Workflow 本身用 Markdown 加 YAML frontmatter 撰寫,再由 gh aw CLI 編譯成實際執行的 .lock.yml GitHub Actions 檔案。權限跟工具存取都在 frontmatter 裡宣告:
tools:
github:
toolsets: [repos, issues, pull_requests]
min-integrity: approved
allowed-repos:
- microsoft/*
github-app:
app-id: ${{ secrets.ASPIRE_BOT_APP_ID }}
private-key: ${{ secrets.ASPIRE_BOT_PRIVATE_KEY }}
owner: "microsoft"
repositories: ["aspire.dev", "aspire"]Agent 不會拿到 repo 的直接寫入權限,所有輸出都得走 safe-outputs 這一層契約:讀完合併後的 diff 與關聯 issue、判斷是否需要更新文件、依既有的 doc-writer 風格與 MDX/Starlight 規範在 aspire.dev 的工作區裡草擬內容,最後只送出一段 JSON 描述「想開一個什麼樣的 PR」,交給另一個權限更窄的 job 去實際建立:
safe-outputs:
create-pull-request:
title-prefix: "[docs] "
labels: [docs-from-code]
draft: true
base-branch: main
allowed-base-branches: [main, release/*]
target-repo: "microsoft/aspire.dev"
protected-files: blocked
fallback-as-issue: true幾個關鍵限制:文件 PR一律是 draft,agent 不會自動合併;AGENTS.md、套件清單、安全性設定等檔案被列為 protected-files,agent 動不了;審核者則直接指定為原本核准產品 PR 的人,形成同一批人「先核准功能、再核准文件」的問責鏈,另外還有個 job 會在原 PR 上留言附上文件 PR 連結,幾分鐘內就能通知到工程師。
成效與限制
文章附上 2026 年 5 月 3 日到 6 月 2 日一個月的數據:
| 指標 | 數值 |
|---|---|
| 產品 PR 合併數 | 396 |
| Workflow 執行次數 | 396 |
| 產生的文件 PR 數 | 82 |
| 文件 PR 合併率 | 100% |
| 合併時間中位數 | 44.8 小時 |
| 24 小時 / 7 天內合併比例 | 38% / 96% |
文章認為效果最好的設計是milestone 對應表,因為工程師本來在產品開發時就會指定 milestone,等於不用額外流程就能自動算出目標分支;草稿制則是把過去文件寫手得回頭猜工程師到底改了什麼的成本,轉成工程師在自己核准功能的同一個介面裡順手看一眼、補充說明。每支 workflow 也各自拿到範圍限定在這兩個 repo 的 GitHub App token,這是安全審查能過關的關鍵。