gRPC网关

为什么用 grpc-gateway

etcd v3 使用 gRPC 作为它的消息协议。etcd 项目包括基于 gRPC 的 Go client 和 命令行工具 etcdctl,通过 gRPC 和 etcd 集群通讯。对于不支持 gRPC 支持的语言,etcd 提供 JSON 的 grpc-gateway。这个网关提供 RESTful 代理,翻译 HTTP/JSON 请求为 gRPC 消息。

使用 grpc-gateway

网关接受 etcd 的 protocol buffer 消息定义的 JSON mapping 。注意 keyvalue 字段被定义为 byte 数组,因此必须在 JSON 中以 base64 编码。下面例子使用 curl,但是任何 HTTP/JSON 客户端都可以如此工作。

设置和获取键

使用 v3alpha/kv/rangev3alpha/kv/put 服务来读取和写入键:

  1. # https://www.base64encode.org/
  2. # foo is 'Zm9v' in Base64
  3. # bar is 'YmFy'
  4. curl -L http://localhost:2379/v3alpha/kv/put \
  5. -X POST -d '{"key": "Zm9v", "value": "YmFy"}'
  6. # {"header":{"cluster_id":"12585971608760269493","member_id":"13847567121247652255","revision":"2","raft_term":"3"}}
  7. curl -L http://localhost:2379/v3alpha/kv/range \
  8. -X POST -d '{"key": "Zm9v"}'
  9. # {"header":{"cluster_id":"12585971608760269493","member_id":"13847567121247652255","revision":"2","raft_term":"3"},"kvs":[{"key":"Zm9v","create_revision":"2","mod_revision":"2","version":"1","value":"YmFy"}],"count":"1"}

观察键

使用 v3alpha/watch 服务来观察键:

  1. curl http://localhost:2379/v3alpha/watch \
  2. -X POST -d '{"create_request": {"key":"Zm9v"} }' &
  3. # {"result":{"header":{"cluster_id":"12585971608760269493","member_id":"13847567121247652255","revision":"1","raft_term":"2"},"created":true}}
  4. curl -L http://localhost:2379/v3alpha/kv/put \
  5. -X POST -d '{"key": "Zm9v", "value": "YmFy"}' >/dev/null 2>&1
  6. # {"result":{"header":{"cluster_id":"12585971608760269493","member_id":"13847567121247652255","revision":"2","raft_term":"2"},"events":[{"kv":{"key":"Zm9v","create_revision":"2","mod_revision":"2","version":"1","value":"YmFy"}}]}}

事务

使用 v3alpha/kv/txn 发起事务:

  1. curl -L http://localhost:2379/v3alpha/kv/txn \
  2. -X POST \
  3. -d '{"compare":[{"target":"CREATE","key":"Zm9v","createRevision":"2"}],"success":[{"requestPut":{"key":"Zm9v","value":"YmFy"}}]}'
  4. # {"header":{"cluster_id":"12585971608760269493","member_id":"13847567121247652255","revision":"3","raft_term":"2"},"succeeded":true,"responses":[{"response_put":{"header":{"revision":"3"}}}]}

认证

使用 v3alpha/auth 服务搭建认证:

  1. # 创建 root 用户
  2. curl -L http://localhost:2379/v3alpha/auth/user/add \
  3. -X POST -d '{"name": "root", "password": "pass"}'
  4. # {"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"1","raft_term":"2"}}
  5. # 创建 root 角色
  6. curl -L http://localhost:2379/v3alpha/auth/role/add \
  7. -X POST -d '{"name": "root"}'
  8. # {"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"1","raft_term":"2"}}
  9. # 授予 root 角色
  10. curl -L http://localhost:2379/v3alpha/auth/user/grant \
  11. -X POST -d '{"user": "root", "role": "root"}'
  12. # {"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"1","raft_term":"2"}}
  13. # 开启认证
  14. curl -L http://localhost:2379/v3alpha/auth/enable -X POST -d '{}'
  15. # {"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"1","raft_term":"2"}}

使用 v3alpha/auth/authenticate 为认证 token 做认证:

  1. # 为 root 用户 获取认证 token
  2. curl -L http://localhost:2379/v3alpha/auth/authenticate \
  3. -X POST -d '{"name": "root", "password": "pass"}'
  4. # {"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"1","raft_term":"2"},"token":"sssvIpwfnLAcWAQH.9"}

为认证 token 设置 Authorization header,以便在获取键时使用认证证书:

  1. curl -L http://localhost:2379/v3alpha/kv/put \
  2. -H 'Authorization : sssvIpwfnLAcWAQH.9' \
  3. -X POST -d '{"key": "Zm9v", "value": "YmFy"}'
  4. # {"header":{"cluster_id":"14841639068965178418","member_id":"10276657743932975437","revision":"2","raft_term":"2"}}

Swagger

生成的 Swagger API 定义可以在 rpc.swagger.json 找到.