置 etcd 集群升級(jí)實(shí)戰(zhàn):從 2.3 到 3.0 的零停機(jī)滾動(dòng)升級(jí)指南)
云原生后端微服務(wù)DevOpsAI 應(yīng)用【免費(fèi)下載鏈接】rainbond無需學(xué)習(xí) Kubernetes 的容器平臺(tái)在 Kubernetes 上構(gòu)建、部署、組裝和管理應(yīng)用無需 K8s 專業(yè)知識(shí)全流程圖形化管理項(xiàng)目地址https://gitcode.com/goodrain/rainbond點(diǎn)擊查看免費(fèi)下載etcd 是 Rainbond 平臺(tái)底層依賴的關(guān)鍵分布式鍵值存儲(chǔ)組件本指南以倉庫內(nèi)置的 etcd 2.3 升級(jí)到 3.0 官方文檔third_party/coreos-etcd/Documentation/upgrades/upgrade_3_0.md為核心系統(tǒng)講解升級(jí)前置檢查、備份策略、混合版本行為、滾動(dòng)升級(jí)五步操作法以及回退限制并結(jié)合倉庫源碼剖析版本協(xié)商與集群版本判定的底層原理幫助讀者在 Rainbond 環(huán)境中安全、可回退地完成 etcd 主版本升級(jí)。一、升級(jí)總覽一次零停機(jī)滾動(dòng)升級(jí)在一般情況下etcd 從 2.3 升級(jí)到 3.0 可以做到零停機(jī)滾動(dòng)升級(jí)其核心思想非常簡(jiǎn)單逐個(gè)停止 etcd v2.3 進(jìn)程并替換為 etcd v3.0 進(jìn)程當(dāng)集群中所有成員都運(yùn)行 v3.0 之后v3.0 新增特性才對(duì)整個(gè)集群開放。這種逐個(gè)替換的方式之所以可行是因?yàn)?etcd 集群在設(shè)計(jì)上允許成員以混合版本運(yùn)行一段時(shí)間詳見下文混合版本一節(jié)。在動(dòng)手執(zhí)行升級(jí)之前務(wù)必通讀本指南的檢查清單并逐項(xiàng)準(zhǔn)備尤其是健康檢查、數(shù)據(jù)備份與回退路徑不要跳過。從倉庫結(jié)構(gòu)看third_party/coreos-etcd 目錄完整內(nèi)置了 etcd 源碼與官方 Documentation本文所講的升級(jí)流程即對(duì)應(yīng)其中Documentation/upgrades/系列升級(jí)指南的第一篇Rainbond 自身的代碼則全部基于etcd v3 clientclientv3與 etcd v3 數(shù)據(jù)模型進(jìn)行開發(fā)見 util/etcd/client.go 中NewClient的注釋new etcd client v3 for all rainbond module, attention: do not support v2因此在 Rainbond 語境下完成 2.3 → 3.0 的遷移意味著平臺(tái)各模塊能夠真正接入 v3 數(shù)據(jù)面與 v3 API。二、升級(jí)檢查清單Upgrade checklists2.1 版本前提Upgrade requirements升級(jí)到 3.0 的前提是當(dāng)前正在運(yùn)行的集群版本必須是 2.3 或更高。如果集群版本低于 2.3請(qǐng)先升級(jí)到 etcd 2.3 版本再執(zhí)行本指南的 3.0 升級(jí)流程此外為了確保滾動(dòng)升級(jí)平滑進(jìn)行運(yùn)行中的集群必須是健康的healthy。在動(dòng)手之前務(wù)必使用etcdctl cluster-health命令確認(rèn)集群健康狀態(tài)。2.2 升級(jí)前準(zhǔn)備Preparation先在預(yù)發(fā)/測(cè)試環(huán)境驗(yàn)證升級(jí) etcd 之前務(wù)必先在預(yù)發(fā)環(huán)境測(cè)試所有依賴 etcd 的服務(wù)確認(rèn)無誤后再部署到生產(chǎn)環(huán)境備份數(shù)據(jù)目錄升級(jí)開始前按照官方 v2 管理指南中 Backing up the datastore 一節(jié)的方法備份 etcd 數(shù)據(jù)目錄倉庫中對(duì)應(yīng)文檔位于 third_party/coreos-etcd/Documentation/v2/admin_guide.md目錄內(nèi)亦提供基于 systemd 的備份腳本 third_party/coreos-etcd/contrib/systemd/etcd2-backup-coreos。如果升級(jí)過程中出現(xiàn)問題可以借助這份備份回退downgrade到原有 etcd 版本另外升級(jí)過程中還應(yīng)當(dāng)為所有 etcd 成員都保存一份數(shù)據(jù)目錄備份這樣即使在集群整體升級(jí)完成之后也保留了將集群回退到 v2.3 狀態(tài)的可能性詳見下文回退一節(jié)。2.3 混合版本行為Mixed versions升級(jí)過程中etcd 集群支持成員以混合版本運(yùn)行并統(tǒng)一按照最低公共版本the lowest common version的協(xié)議工作只有所有成員都升級(jí)到 v3.0 之后集群才被認(rèn)定為完成升級(jí)在內(nèi)部etcd 各成員之間會(huì)相互協(xié)商以確定整個(gè)集群的版本cluster version該版本決定了對(duì)外上報(bào)的版本號(hào)以及可用的功能特性capabilities。倉庫源碼印證了這一機(jī)制third_party/coreos-etcd/etcdserver/cluster_util.go 中的decideClusterVersion函數(shù)會(huì)遍歷所有成員上報(bào)的Server版本取最小版本作為集群版本同時(shí)isCompatibleWithCluster/isCompatibleWithVersthird_party/coreos-etcd/etcdserver/cluster_util.go會(huì)校驗(yàn)各成員的集群版本是否落在[MinClusterVersion, Version]范圍內(nèi)超出范圍的成員會(huì)被判定為不兼容。當(dāng)集群版本最終變化時(shí)third_party/coreos-etcd/etcdserver/membership/cluster.go 會(huì)記錄 updated the cluster version from ... to ... 并將新版本持久化到 store——這正是升級(jí)日志中那條關(guān)鍵消息的來源。2.4 升級(jí)限制Limitations升級(jí)過程有兩個(gè)重要的時(shí)間預(yù)期請(qǐng)據(jù)此安排節(jié)奏數(shù)據(jù)量大于 50MB 時(shí)新升級(jí)的成員追上集群進(jìn)度可能需要最多 2 分鐘??梢圆榭醋罱淮慰煺盏拇笮砉浪憧倲?shù)據(jù)量。換句話說最穩(wěn)妥的做法是每升級(jí)完一個(gè)成員后等待 2 分鐘再升級(jí)下一個(gè)數(shù)據(jù)總量達(dá)到 100MB 或更大時(shí)這次一次性追趕過程耗時(shí)會(huì)更長(zhǎng)。管理超大規(guī)模 etcd 集群的運(yùn)維人員可以在升級(jí)前聯(lián)系 etcd 團(tuán)隊(duì)咨詢操作建議。2.5 回退Downgrade關(guān)于回退需要明確兩條規(guī)則一旦所有成員都升級(jí)到 v3.0集群整體版本即升級(jí)為 v3.0此時(shí)無法再回退從已完成升級(jí)的終態(tài)回退是不可能的只要還有任何一個(gè)成員仍停留在 v2.3整個(gè)集群及其操作就仍處于 v2.3 語義之下此時(shí)可以從這種混合集群狀態(tài)恢復(fù)為全部成員運(yùn)行 v2.3 二進(jìn)制。因此務(wù)必在升級(jí)前為所有 etcd 成員備份數(shù)據(jù)目錄為集群在完全升級(jí)后仍保留可回退能力。三、升級(jí)操作五步法Upgrade procedure下面以運(yùn)行在本機(jī)的三節(jié)點(diǎn) v2.3 etcd 集群為例給出完整的升級(jí)步驟。三個(gè)成員的客戶端端口分別為12379、22379、32379對(duì)應(yīng) peer 端口12380、22380、32380。第 1 步檢查升級(jí)前提確認(rèn)集群健康且運(yùn)行在 v2.3.x$ etcdctl cluster-health member 6e3bd23ae5f1eae0 is healthy: got healthy result from http://localhost:22379 member 924e2e83e93f2560 is healthy: got healthy result from http://localhost:32379 member 8211f1d0f64f3269 is healthy: got healthy result from http://localhost:12379 cluster is healthy $ curl http://localhost:2379/version {etcdserver:2.3.x,etcdcluster:2.3.8}etcdctl cluster-health輸出中每個(gè)成員都返回 healthy、最后一行輸出cluster is healthy說明集群健康/version接口返回etcdserver與etcdcluster兩個(gè)字段前者是服務(wù)版本后者是集群版本2.3.x / 2.3.8滿足升級(jí)前提。第 2 步停止現(xiàn)有 etcd 進(jìn)程逐個(gè)停止 v2.3 etcd 進(jìn)程。停止某個(gè)成員時(shí)其他成員會(huì)輸出預(yù)期中的錯(cuò)誤日志——這是因?yàn)榧撼蓡T連接被暫時(shí)斷開了屬于正常現(xiàn)象2016-06-27 15:21:48.624124 E | rafthttp: failed to dial 8211f1d0f64f3269 on stream Message (dial tcp 127.0.0.1:12380: getsockopt: connection refused) 2016-06-27 15:21:48.624175 I | rafthttp: the connection with 8211f1d0f64f3269 became inactive此時(shí)是一個(gè)理想的備份時(shí)機(jī)建議立即備份 etcd 數(shù)據(jù)目錄為可能出現(xiàn)的任何問題保留回退路徑$ etcdctl backup \ --data-dir /var/lib/etcd \ --backup-dir /tmp/etcd_backup第 3 步放入 v3.0 二進(jìn)制并啟動(dòng)新進(jìn)程將二進(jìn)制替換為 etcd v3.0 并啟動(dòng)。新的 v3.0 成員會(huì)向集群發(fā)布自身信息09:58:25.938673 I | etcdserver: published {Name:infra1 ClientURLs:[http://localhost:12379]} to cluster 524400597fb1d5f6隨后驗(yàn)證該成員乃至整個(gè)集群在新二進(jìn)制下恢復(fù)健康$ etcdctl cluster-health member 6e3bd23ae5f1eae0 is healthy: got healthy result from http://localhost:22379 member 924e2e83e93f2560 is healthy: got healthy result from http://localhost:32379 member 8211f1d0f64f3269 is healthy: got healthy result from http://localhost:12379 cluster is healthy在整個(gè)集群全部升級(jí)完成之前已升級(jí)的成員會(huì)持續(xù)輸出如下告警日志這是混合版本階段的預(yù)期現(xiàn)象待所有成員都升級(jí)到 v3.0 后即會(huì)消失2016-06-27 15:22:05.679644 W | etcdserver: the local etcd version 2.3.7 is not up-to-date 2016-06-27 15:22:05.679660 W | etcdserver: member 8211f1d0f64f3269 has a higher version 3.0.0這兩條告警的源碼出處正是前面提到的decideClusterVersion當(dāng)發(fā)現(xiàn)本機(jī)版本低于某個(gè)成員時(shí)會(huì)依次打出 the local etcd version ... is not up-to-date 與 member ... has a higher version ...見 third_party/coreos-etcd/etcdserver/cluster_util.go。第 4 步對(duì)其余成員重復(fù)第 2、3 步對(duì)所有剩余成員依次執(zhí)行停止 → 備份 → 啟動(dòng) v3.0并且如前文所述在數(shù)據(jù)量較大時(shí)每升級(jí)一個(gè)成員后等待約 2 分鐘給新成員留出追趕進(jìn)度的時(shí)間。第 5 步完成當(dāng)所有成員都升級(jí)完成后集群會(huì)報(bào)告升級(jí)到 3.0 成功2016-06-27 15:22:19.873751 N | membership: updated the cluster version from 2.3 to 3.0 2016-06-27 15:22:19.914574 I | api: enabled capabilities for version 3.0.0第一條日志即由 third_party/coreos-etcd/etcdserver/membership/cluster.go 中的集群版本更新邏輯輸出第二條則來自 third_party/coreos-etcd/etcdserver/api/capability.go 的UpdateCapability——集群版本提升后對(duì)應(yīng)版本的新增能力capabilities才會(huì)被啟用。使用 v3 API 再次確認(rèn)所有端點(diǎn)健康$ ETCDCTL_API3 etcdctl endpoint health 127.0.0.1:12379 is healthy: successfully committed proposal: took 18.440155ms 127.0.0.1:32379 is healthy: successfully committed proposal: took 13.651368ms 127.0.0.1:22379 is healthy: successfully committed proposal: took 18.513301ms注意這里已切換為ETCDCTL_API3環(huán)境變量與endpoint health子命令這是 v3 API 對(duì)應(yīng)的健康檢查方式。四、進(jìn)一步注意事項(xiàng)Further considerations升級(jí)到 v3 之后etcdctl 的環(huán)境變量體系發(fā)生了變化如果ETCDCTL_API2 etcdctl cluster-health工作正常但ETCDCTL_API3 etcdctl endpoint health報(bào)錯(cuò)Error: grpc: timed out when dialing請(qǐng)務(wù)必使用 etcdctl 文檔中定義的新變量名v3 采用 gRPC 通信需要正確的端點(diǎn)與連接參數(shù)v3 相關(guān)的運(yùn)維命令與 v2 差異明顯例如 v3 中查詢端點(diǎn)狀態(tài)使用ETCDCTL_API3 etcdctl --endpoints127.0.0.1:2379 endpoint status參見 third_party/coreos-etcd/Documentation/op-guide/versioning.md而 v3 的快照備份使用etcdctl snapshot save backup.db參見 third_party/coreos-etcd/Documentation/op-guide/maintenance.md。五、已知問題Known Issues官方文檔明確記錄的 v2.3 → v3.0 升級(jí)相關(guān)已知問題如下升級(jí)前請(qǐng)對(duì)照排查Go 版本與 etcd 版本兼容性使用 Go 高于 v1.7 構(gòu)建的 etcd v3.1 以下版本無法正常工作對(duì)應(yīng)官方 Issue 6951gRPC/HTTP2 傳輸錯(cuò)誤如果 etcd 服務(wù)端日志出現(xiàn)transport: http2Client.notifyError got notified that the client transport was broken unexpected EOF.請(qǐng)確認(rèn) etcd 使用的是官方預(yù)編譯發(fā)布版或者滿足(etcd v3.1 且 go v1.7)或(etcd v3.1 且 go v1.6.x)的構(gòu)建組合升級(jí)期間禁止變更成員向 v2.3 集群添加 v3 節(jié)點(diǎn)是不被支持的可能觸發(fā) panic對(duì)應(yīng)官方 Issue 7429。混合版本只允許在 v3 遷移過程中存在請(qǐng)務(wù)必在所有成員升級(jí)完成后再進(jìn)行任何成員變更增刪成員等。六、Rainbond 環(huán)境中的 etcd v3 落地參考完成 2.3 → 3.0 升級(jí)的最終目的是讓上層服務(wù)真正使用 v3 數(shù)據(jù)面。倉庫源碼顯示 Rainbond 各模塊對(duì) etcd 的接入已經(jīng)全面基于 v3統(tǒng)一客戶端util/etcd/client.go 定義ClientArgs含Endpoints、DialTimeout、AutoSyncInterval及CaFile/CertFile/KeyFile三個(gè) TLS 參數(shù)并通過NewClient創(chuàng)建clientv3.Client默認(rèn)DialTimeout為 5 秒、AutoSyncInterval為 10 秒TLS 三項(xiàng)證書同時(shí)配置時(shí)才會(huì)啟用加密連接分布式鎖/選主util/etcd/etcdlock/master.go 基于clientv3/concurrency的Election與Session實(shí)現(xiàn)主節(jié)點(diǎn)選舉CreateMasterLock支持自定義選舉名稱、競(jìng)選者標(biāo)識(shí)與 lease TTL第三方服務(wù)發(fā)現(xiàn)worker/appm/thirdparty/discovery/etcd.go 展示了 Rainbond 作為 etcd v3客戶端消費(fèi)數(shù)據(jù)的真實(shí)場(chǎng)景——通過cli.Get(ctx, key, c.WithPrefix())拉取端點(diǎn)列表并使用cli.Watch監(jiān)聽鍵變更實(shí)現(xiàn)第三方服務(wù)的動(dòng)態(tài)發(fā)現(xiàn)與在線狀態(tài)同步。這些實(shí)現(xiàn)全部依賴 etcd v3 API 與 v3 存儲(chǔ)模型因此對(duì)運(yùn)行 etcd 的版本有硬性要求——這也是本文檔所指導(dǎo)的 2.3 → 3.0 升級(jí)在 Rainbond 技術(shù)棧中具有實(shí)際意義的原因。若 Rainbond 環(huán)境內(nèi)的 etcd 仍運(yùn)行在 2.x 版本請(qǐng)按照上述五步法完成升級(jí)使平臺(tái)各模塊能夠穩(wěn)定接入 v3 數(shù)據(jù)面。七、總結(jié)etcd 2.3 → 3.0 的升級(jí)是一條逐節(jié)點(diǎn)滾動(dòng)替換的路徑升級(jí)前確認(rèn)版本與健康狀態(tài)、為每個(gè)成員備份數(shù)據(jù)目錄升級(jí)中容忍混合版本與階段性的告警日志利用最低公共版本協(xié)商機(jī)制保證集群協(xié)議一致升級(jí)完成后以ETCDCTL_API3的 v3 命令驗(yàn)證端點(diǎn)健康。牢記兩條紅線——完全升級(jí)后不可回退、升級(jí)期間不得變更成員——即可在 Rainbond 環(huán)境中以最小風(fēng)險(xiǎn)完成這次關(guān)鍵的存儲(chǔ)層主版本遷移。贊分享云原生后端微服務(wù)DevOpsAI 應(yīng)用【免費(fèi)下載鏈接】rainbond無需學(xué)習(xí) Kubernetes 的容器平臺(tái)在 Kubernetes 上構(gòu)建、部署、組裝和管理應(yīng)用無需 K8s 專業(yè)知識(shí)全流程圖形化管理項(xiàng)目地址https://gitcode.com/goodrain/rainbond點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Rainbond 內(nèi)置 etcd 集群從 3.0 滾動(dòng)升級(jí)到 3.1 全流程指南Rainbond 內(nèi)置 etcd 集群從 3.0 滾動(dòng)升級(jí)到 3.1 全流程指南 導(dǎo)讀本指南圍繞 etcd 官方升級(jí)文檔 upgrade_3_1.md ht云原生后端微服務(wù)DevOpsAI 應(yīng)用Rainbond 內(nèi)嵌 etcd 升級(jí)指南從 v2.3 到 v3.x 的零停機(jī)滾動(dòng)升級(jí)與 API 遷移Rainbond 內(nèi)嵌 etcd 升級(jí)指南從 v2.3 到 v3.x 的零停機(jī)滾動(dòng)升級(jí)與 API 遷移 本篇技術(shù)指南以 Rainbond 倉庫內(nèi)嵌的 etcd云原生后端微服務(wù)DevOpsAI 應(yīng)用Rainbond 內(nèi)置 etcd 升級(jí)指南從 3.4 到 3.5 的滾動(dòng)升級(jí)完整手冊(cè)Rainbond 內(nèi)置 etcd 升級(jí)指南從 3.4 到 3.5 的滾動(dòng)升級(jí)完整手冊(cè) 導(dǎo)讀 etcd 是 Rainbond 控制面API 服務(wù)、構(gòu)建任務(wù)、事云原生后端微服務(wù)DevOpsAI 應(yīng)用上一篇archinstall Python 插件機(jī)制解析加載方式、on_* 鉤子與自研插件實(shí)踐下一篇Windows 11終極優(yōu)化指南免費(fèi)開源工具Win11Debloat讓你的系統(tǒng)性能提升51%創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考