1. etcd 网关

etcd 网关是一个简单的 TCP 代理,可将网络数据转发到 etcd 集群。网关是无状态且透明的,它既不会检查客户端请求,也不会干扰集群响应,支持多个 etcd 服务器实例,并采用简单的循环策略。

etcd 网关将请求路由到可用端点,并向客户端隐藏故障,使得客户端感知不到服务端的故障。

1.1 适用场景

我们使用客户端连接到 etcd 服务器时,每个访问 etcd 的应用程序必须知道所要访问的 etcd 集群实例的地址,即用来提供客户端服务的地址:ETCD_LISTEN_CLIENT_URLS

如果同一服务器上的多个应用程序访问相同的 etcd 集群,每个应用程序仍需要知道 etcd 集群的广播的客户端端点地址。如果将 etcd 集群重新配置,拥有不同的端点,那么每个应用程序还需要更新其端点列表。在大规模集群环境下,重新配置的操作既造成了重复又容易出错。

以上问题,都可以通过 etcd 网关来解决:

  • 使用 etcd 网关作为稳定的本地端点,对于客户端应用程序来说,不会感知到集群实例的变化。
  • 典型的 etcd 网关配置是使每台运行网关的计算机在本地地址上侦听,并且每个 etcd 应用程序都连接对应的本地网关,发生 etcd 集群实例的变更时,只需要网关更新其端点,而不需要更新每个客户端应用程序的代码实现。

1.2 不适用场景

  • 性能提升

etcd 网关不是为提高 etcd 集群性能设计的。它不提供缓存、watch 流合并或批量处理等功能。

  • 在集群上运行管理系统

类似 Kubernetes 的高级集群管理系统本身支持服务发现。应用程序可以使用系统默认的 DNS 名称或虚拟 IP 地址访问 etcd 集群。例如,负责为 Service 提供 Cluster 内部的服务发现和负载均衡的 Kube-proxy 其实等效于 etcd 网关的职能。

总而言之,为了自动传播集群端点更改,etcd 网关在每台机器上都运行,为多个应用提供访问相同的 etcd 集群服务。

2. gRPC 网关

gRPC-Gateway 为非 gRPC 的客户端提供 HTTP 接口。

etcd v3 使用 gRPC 作为消息传输协议。

etcd 项目中包括了基于 gRPCGo client 和命令行工具 etcdctl,客户端通过 gRPC 框架与 etcd 集群通讯。对于不支持 gRPC 的客户端语言,etcd 提供 JSONgRPC-Gateway,通过 gRPC-Gateway 提供 RESTful 代理,转换 HTTP/JSON 请求为 gRPCProtocol Buffer 格式的消息。

这里你需要注意的是,在 HTTP 请求体中的 JSON 对象,其包含的 keyvalue 字段都被定义成了 byte 数组,因此必须在 JSON 对象中,使用 base64 编码对内容进行处理

2.1 etcd 版本与 gRPC-Gateway 接口对应的关系

gRPC-Gateway 提供的接口路径自 etcd v3.3 已经变更:

  • 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 版本的对应关系,你可以看到,即使是 v3 版本下的 APIgRPC-Gateway 提供的接口路径在内部细分的版本下也有不同,所以需要注意当前正在使用的 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 编码结果为 ZGVtbw==
  • AAA 字符串的 base64 编码结果为 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 接口来监测 keys,我们来 watch 刚刚写入的 ZGVtbw==,请求如下所示:

curl -N http://localhost:2379/v3/watch -X POST -d '{"create_request": {"key":"ZGVtbw=="}}'

然后另开一个窗口,执行以下命令

etcdctl put demo 123

查看 watch 结果输出:

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"}}]}}

当写入键值后,触发了监测事件的发生,控制台输出了时间的细节。HTTP 请求客户端与 etcd 服务端建立长连接,当监听的键值对发生变更时,便会将事件通知给客户端。

2.4 HTTP 请求的安全认证

HTTP 的方式访问 etcd 服务端,需要考虑安全的问题,gRPC-Gateway 中提供的 API 接口支持开启安全认证。通过 /v3/auth 接口设置认证,需要实现以下 4 个步骤:

  1. 创建用户
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"}}
  1. 创建角色
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"}}
  1. 用户授予角色
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"}}
  1. 开启认证权限
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"}}

如上的请求中,我们首先创建了 root 用户和角色,将 root 角色赋予到 root 用户,这样就可以开启用户的权限。接下来就是进行身份验证,并进行 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。接下来,设置请求的头部 Authorization 为刚刚获取到的身份验证令牌,以使用身份验证凭据设置 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 等其他接口,请参考 官网

3. 总结

  • etcd 网关通常用于 etcd 集群的门户,是一个简单的 TCP 代理,将客户端请求转发到 etcd 集群,对外屏蔽了 etcd 集群内部的实际情况,在集群出现故障或者异常时,可以通过 etcd 网关进行切换;

  • gRPC-Gateway 则是对于 etcdgRPC 通信协议的补充,有些语言的客户端不支持 gRPC 通信协议,此时就可以使用 gRPC-Gateway 对外提供的 HTTP API 接口。通过 HTTP 请求,实现与 gRPC 调用协议同样的功能。

etcd 笔记(04)— etcd 网关与 gRPC 网关相关推荐

  1. etcd 笔记(05)— etcd 代码结构、各模块功能、整体架构、各模块之间的交互、请求和应答流程

    1. etcd 项目结构和功能 etcd 项目代码的目录结构如下: $ tree ├── auth ├── build ├── client ├── clientv3 ├── contrib ├── ...

  2. etcd 笔记(01)— etcd 简介、特点、应用场景、常用术语、分布式 CAP 理论、分布式原理

    1. etcd 简介 etcd 官网定义: A highly-available key value store for shared configuration and service discov ...

  3. gRPC 网关,针对 HTTP 2.0 长连接性能优化,提升吞吐量

    最近要搞个网关GateWay,由于系统间请求调用是基于gRPC框架,所以网关第一职责就是能接收并转发gRPC请求,大致的系统架构如下所示: 简单看下即可,由于含有定制化业务背景,架构图看不懂也没关系, ...

  4. ENSPLAB笔记:配置VXLAN(分布式网关,BGP EVPN方式)(Part1)

    目录 1.实验目的 2.实验环境 2.1 实验拓扑 2.2 数据准备 2.3 设备型号 3.实验内容 4.配置步骤 4.1 基础配置 4.2 配置业务接入点 4.3 配置BGP EVPN Peer 4 ...

  5. Etcd教程 — 第一章 Etcd简介、Etcd单机安装

    Etcd教程 - 第一章 一.Etcd介绍 1.1 介绍 1.2 etcd特点 二. Etcd单机安装 2.1 安装方式 2.1.1 yum install etcd 2.1.2 通过系统工具安装et ...

  6. 什么是物联网网关?物联网网关具备什么功能?_转

    参考:什么是物联网?物联网产业链体系深度分析 随着物联网概念的不断深入,商业级的网络应用遍地开花,各种智能家电层出不穷,改善着我们的生活.与此同时,物联网网关也将成为连接的重要纽带.作为网关设备,物联 ...

  7. 取得 Git 仓库 —— Git 学习笔记 04

    取得 Git 仓库 -- Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区.索引.本地版本库之间的交互:二是本地版本库和远程版本库之间的交互.第一块是基础,第二块是难点. 下面, ...

  8. SpringMVC-学习笔记04【SpringMVC返回值类型及响应数据类型】

    Java后端 学习路线 笔记汇总表[黑马程序员] SpringMVC-学习笔记01[SpringMVC概述及入门案例][day01] SpringMVC-学习笔记02[参数绑定及自定义类型转换] Sp ...

  9. Spring-学习笔记04【Spring的常用注解】

    Java后端 学习路线 笔记汇总表[黑马程序员] Spring-学习笔记01[Spring框架简介][day01] Spring-学习笔记02[程序间耦合] Spring-学习笔记03[Spring的 ...

最新文章

  1. InServ-T级存储系统能否挑战传统存储架构?
  2. 机器学习--线性回归、逻辑回归
  3. 详解深度学习中的Normalization,不只是BN(2)
  4. C++自定义自适应中值滤波
  5. 数据结构与算法--图论-深度优先搜索及其应用
  6. Win7\xp添加虚拟网Microsoft Loopback Adapter
  7. python的安装和运行
  8. tomcat 在linux下的关闭问题
  9. 【转】设计模式六大原则(1):单一职责原则
  10. centos Apache、php、mysql默认安装路径
  11. ICP算法原理及优缺点(简洁明了)
  12. ISBN书号怎么查询
  13. Goolgle推荐   onActivityResult的替代方式
  14. 模型常见问题及规范--模型制作PBR流程规范规范
  15. “靠天吃饭”坐拥百万资产客户,富途摆脱被动局面难?
  16. office教程:如何给excel表格重命名工作表
  17. 词霸天下---词根290【-it- 走】
  18. C语言 输入n,输出n各位数字之和
  19. 墨言教育摄影技能干货分享|优秀作品评析,想学摄影的看这里
  20. PhD positions 008-2021-FEB

热门文章

  1. 2022-2028年中国互联网+不良资产处置行业深度调研及投资前景预测报告
  2. C++核心编程(四)--文件操作
  3. 如何通过HTTP优雅调用第三方-Feign
  4. 将代码生成器带入TVM
  5. TinyML设备设计的Arm内核
  6. 微信架构 支付架构(下)
  7. 【CV】吴恩达机器学习课程笔记 | 第1-15章
  8. [JavaScript] JavaScript 运算符与流程控制
  9. 7.12 其他面向对象设计原则3: 依赖倒置原则DIP
  10. Linux 准确查找结构体定义位置