etcd 笔记(04)— etcd 网关与 gRPC 网关
1. etcd 網(wǎng)關(guān)
etcd 網(wǎng)關(guān)是一個簡單的 TCP 代理,可將網(wǎng)絡(luò)數(shù)據(jù)轉(zhuǎn)發(fā)到 etcd 集群。網(wǎng)關(guān)是無狀態(tài)且透明的,它既不會檢查客戶端請求,也不會干擾集群響應,支持多個 etcd 服務(wù)器實例,并采用簡單的循環(huán)策略。
etcd 網(wǎng)關(guān)將請求路由到可用端點,并向客戶端隱藏故障,使得客戶端感知不到服務(wù)端的故障。
1.1 適用場景
我們使用客戶端連接到 etcd 服務(wù)器時,每個訪問 etcd 的應用程序必須知道所要訪問的 etcd 集群實例的地址,即用來提供客戶端服務(wù)的地址:ETCD_LISTEN_CLIENT_URLS。
如果同一服務(wù)器上的多個應用程序訪問相同的 etcd 集群,每個應用程序仍需要知道 etcd 集群的廣播的客戶端端點地址。如果將 etcd 集群重新配置,擁有不同的端點,那么每個應用程序還需要更新其端點列表。在大規(guī)模集群環(huán)境下,重新配置的操作既造成了重復又容易出錯。
以上問題,都可以通過 etcd 網(wǎng)關(guān)來解決:
- 使用
etcd網(wǎng)關(guān)作為穩(wěn)定的本地端點,對于客戶端應用程序來說,不會感知到集群實例的變化。 - 典型的
etcd網(wǎng)關(guān)配置是使每臺運行網(wǎng)關(guān)的計算機在本地地址上偵聽,并且每個etcd應用程序都連接對應的本地網(wǎng)關(guān),發(fā)生etcd集群實例的變更時,只需要網(wǎng)關(guān)更新其端點,而不需要更新每個客戶端應用程序的代碼實現(xiàn)。
1.2 不適用場景
- 性能提升
etcd 網(wǎng)關(guān)不是為提高 etcd 集群性能設(shè)計的。它不提供緩存、watch 流合并或批量處理等功能。
- 在集群上運行管理系統(tǒng)
類似 Kubernetes 的高級集群管理系統(tǒng)本身支持服務(wù)發(fā)現(xiàn)。應用程序可以使用系統(tǒng)默認的 DNS 名稱或虛擬 IP 地址訪問 etcd 集群。例如,負責為 Service 提供 Cluster 內(nèi)部的服務(wù)發(fā)現(xiàn)和負載均衡的 Kube-proxy 其實等效于 etcd 網(wǎng)關(guān)的職能。
總而言之,為了自動傳播集群端點更改,etcd 網(wǎng)關(guān)在每臺機器上都運行,為多個應用提供訪問相同的 etcd 集群服務(wù)。
2. gRPC 網(wǎng)關(guān)
gRPC-Gateway 為非 gRPC 的客戶端提供 HTTP 接口。
etcd v3 使用 gRPC 作為消息傳輸協(xié)議。
etcd 項目中包括了基于 gRPC 的 Go client 和命令行工具 etcdctl,客戶端通過 gRPC 框架與 etcd 集群通訊。對于不支持 gRPC 的客戶端語言,etcd 提供 JSON 的 gRPC-Gateway,通過 gRPC-Gateway 提供 RESTful 代理,轉(zhuǎn)換 HTTP/JSON 請求為 gRPC 的 Protocol Buffer 格式的消息。
這里你需要注意的是,在 HTTP 請求體中的 JSON 對象,其包含的 key 和 value 字段都被定義成了 byte 數(shù)組,因此必須在 JSON 對象中,使用 base64 編碼對內(nèi)容進行處理。
2.1 etcd 版本與 gRPC-Gateway 接口對應的關(guān)系
gRPC-Gateway 提供的接口路徑自 etcd v3.3 已經(jīng)變更:
-
etcd v3.2及之前的版本只能使用[CLIENT-URL]/v3alpha/*接口; -
etcd v3.3使用CLIENT-URL/v3alpha/*; -
etcd v3.4使用CLIENT-URL/v3beta/,且廢棄了[CLIENT-URL]/v3alpha/; -
etcd v3.5只使用CLIENT-URL/v3beta/;
通過上面的接口與 etcd 版本的對應關(guān)系,你可以看到,即使是 v3 版本下的 API,gRPC-Gateway 提供的接口路徑在內(nèi)部細分的版本下也有不同,所以需要注意當前正在使用的 etcd 版本。
2.2 鍵值對讀寫操作
如果沒有使用 base64 對鍵值對進行編碼,那么會報以下錯誤:
wohu@ubuntu:~$ curl -L http://localhost:2379/v3/kv/put -X POST -d '{"key": "/demo", "value": "AAA"}'
{"error":"illegal base64 data at input byte 4","message":"illegal base64 data at input byte 4","code":3}
對其進行 base64 編碼
demo字符串的base64編碼結(jié)果為ZGVtbw==AAA字符串的base64編碼結(jié)果為QUFB
wohu@ubuntu:~$ curl -L http://localhost:2379/v3/kv/put -X POST -d '{"key": "ZGVtbw==", "value": "QUFB"}'
{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"26","raft_term":"3"}}
接著,我們通過 /v3/kv/range 接口,來讀取剛剛寫入的鍵值對:
wohu@ubuntu:~$ curl -L http://localhost:2379/v3/kv/range -X POST -d '{"key": "ZGVtbw=="}'
{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"26","raft_term":"3"},"kvs":[{"key":"ZGVtbw==","create_revision":"26","mod_revision":"26","version":"1","value":"QUFB"}],"count":"1"}
當我們想要獲取前綴為指定值的鍵值對時,可以使用如下請求:
wohu@ubuntu:~$ curl -L http://localhost:2379/v3/kv/range -X POST -d '{"key": "ZGVtbw==", "range_end": "Zm9w"}'
{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"26","raft_term":"3"},"kvs":[{"key":"ZGVtbw==","create_revision":"26","mod_revision":"26","version":"1","value":"QUFB"}],"count":"1"}
因為只有一個值,所以返回正確。
2.3 watch 鍵值
etcd 中提供了 /v3/watch 接口來監(jiān)測 keys,我們來 watch 剛剛寫入的 ZGVtbw==,請求如下所示:
curl -N http://localhost:2379/v3/watch -X POST -d '{"create_request": {"key":"ZGVtbw=="}}'
然后另開一個窗口,執(zhí)行以下命令
etcdctl put demo 123
查看 watch 結(jié)果輸出:
wohu@ubuntu:~$ curl -N http://localhost:2379/v3/watch -X POST -d '{"create_request": {"key":"ZGVtbw=="} }'
{"result":{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"26","raft_term":"3"},"created":true}}
{"result":{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"27","raft_term":"3"},"events":[{"kv":{"key":"ZGVtbw==","create_revision":"26","mod_revision":"27","version":"2","value":"MTIz"}}]}}
當寫入鍵值后,觸發(fā)了監(jiān)測事件的發(fā)生,控制臺輸出了時間的細節(jié)。HTTP 請求客戶端與 etcd 服務(wù)端建立長連接,當監(jiān)聽的鍵值對發(fā)生變更時,便會將事件通知給客戶端。
2.4 HTTP 請求的安全認證
HTTP 的方式訪問 etcd 服務(wù)端,需要考慮安全的問題,gRPC-Gateway 中提供的 API 接口支持開啟安全認證。通過 /v3/auth 接口設(shè)置認證,需要實現(xiàn)以下 4 個步驟:
- 創(chuàng)建用戶
wohu@ubuntu:~$ curl -L http://localhost:2379/v3/auth/user/add -X POST -d '{"name": "root", "password": "123456"}'
{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"27","raft_term":"3"}}
- 創(chuàng)建角色
wohu@ubuntu:~$ curl -L http://localhost:2379/v3/auth/role/add -X POST -d '{"name": "root"}'
{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"27","raft_term":"3"}}
- 用戶授予角色
wohu@ubuntu:~$ curl -L http://localhost:2379/v3/auth/user/grant -X POST -d '{"user": "root", "role": "root"}'
{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"27","raft_term":"3"}}
- 開啟認證權(quán)限
wohu@ubuntu:~$ curl -L http://localhost:2379/v3/auth/enable -X POST -d '{}'
{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"27","raft_term":"3"}}
如上的請求中,我們首先創(chuàng)建了 root 用戶和角色,將 root 角色賦予到 root 用戶,這樣就可以開啟用戶的權(quán)限。接下來就是進行身份驗證,并進行 HTTP 訪問。流程如下圖所示:
使用 /v3/auth/authenticate API 接口對 etcd 進行身份驗證以獲取身份驗證令牌:
wohu@ubuntu:~$ curl -L http://localhost:2379/v3/auth/authenticate -X POST -d '{"name": "root", "password": "123456"}'
{"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"27","raft_term":"3"},"token":"BGQDrdEVPaGQBCGh.51"}
請求獲取到 token 的值為 BGQDrdEVPaGQBCGh.51。接下來,設(shè)置請求的頭部 Authorization 為剛剛獲取到的身份驗證令牌,以使用身份驗證憑據(jù)設(shè)置 key 值:
curl -L http://localhost:2379/v3/kv/put -H 'Authorization:BGQDrdEVPaGQBCGh.51' -X POST -d '{"key": "ZGVtbw==", "value": "QUFB"}'
如果 token 不合法會報錯誤:
{"error":"etcdserver: invalid auth token","message":"etcdserver: invalid auth token","code":16}
etcd gRPC-Gateway 中提供的 API 接口還有諸如 /v3/auth/role/delete、/v3/auth/role/get 等其他接口,請參考 官網(wǎng)
3. 總結(jié)
-
etcd網(wǎng)關(guān)通常用于etcd集群的門戶,是一個簡單的TCP代理,將客戶端請求轉(zhuǎn)發(fā)到etcd集群,對外屏蔽了etcd集群內(nèi)部的實際情況,在集群出現(xiàn)故障或者異常時,可以通過etcd網(wǎng)關(guān)進行切換; -
gRPC-Gateway則是對于etcd的gRPC通信協(xié)議的補充,有些語言的客戶端不支持gRPC通信協(xié)議,此時就可以使用gRPC-Gateway對外提供的HTTP API接口。通過HTTP請求,實現(xiàn)與gRPC調(diào)用協(xié)議同樣的功能。
總結(jié)
以上是生活随笔為你收集整理的etcd 笔记(04)— etcd 网关与 gRPC 网关的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国氧化铟锡薄膜行业
- 下一篇: 2022-2028年中国ITO薄膜行业市