etcd 升级到 3.x 版本后,其对外 API 的协议从普通的 HTTP1 切换到了 gRPC。为了兼顾那些不能使用 gRPC 的特殊群体,etcd 通过 gRPC-gateway 的方式代理 HTTP1 请求,以 gRPC 形式去访问新的 gRPC API。(由于 HTTP1 念起来太过拗口,以下将之简化成 HTTP,正好和 gRPC 能够对应。请不要纠结 gRPC 也是 HTTP 请求的这种问题。)

Apache APISIX 开始用 etcd 的时候,用的是 etcd v2 的 API。从 Apache APISIX 2.0 版本起,我们把依赖的 etcd 版本升级到 3.x。由于 Lua 生态圈里面没有 gRPC 库,所以 etcd 对 HTTP 的兼容帮了我们很大的忙,这样就不用花很大心思去补这个短板了。

从去年 10 月发布 Apache APISIX 2.0 版本以来,现在已经过去了 8 个月。在实践过程中,我们也发现了 etcd 的 HTTP API 的一些跟 gRPC API 交互的问题。事实上,拥有 gRPC-gateway 并不意味着能够完美支持 HTTP 访问,这里还是有些细微的差别。

打破 gRPC 的默认限制

就在几天前,etcd 发布了 v3.5.0 版本。这个版本的发布,了却困扰我们很长时间的一个问题。

跟 HTTP 不同的是,gRPC 默认限制了一次请求可以读取的数据大小。这个限制叫做 “MaxCallRecvMsgSize”,默认是 4MiB。当 Apache APISIX 全量同步 etcd 数据时,假如配置够多,就会触发这一上限,报错 “grpc: received message larger than max”。

神奇的是,如果你用 etcdctl 去访问,这时候却不会有任何问题。这是因为这个限制是可以在跟 gRPC server 建立连接时动态设置的,etcdctl 给这个限制设置了一个很大的整数,相当于去掉了这一限制。

由于不少用户碰到过同样的问题,我们曾经讨论过对策。

一个想法是用增量同步模拟全量同步,这么做有两个弊端:

  1. 实现起来复杂,要改不少代码

  2. 会延长同步所需的时间

另一个想法是修改 etcd。既然能够在 etcdctl 里面去除限制,为什么不对 gRPC-gateway 一视同仁呢?同样的改动可以作用在 gRPC-gateway 上。

我们采用了第二种方案,给 etcd 提了个 PR:https://github.com/etcd-io/etcd/pull/13077

最新发布的 v3.5.0 版本就包含了我们贡献的这个改动。如果你遇到 “grpc: received message larger than max”,不妨试一下这个版本。这一改动也被 etcd 开发者 backport 到 3.4 分支上了。3.4 分支的下一个发布,也会带上这个改动。

这件事也说明 gRPC-gateway 并非百试百灵。即使用了它,也不能保证 HTTP 访问能够跟 gRPC 访问有一样的体验。

对服务端证书的有趣用法

Apache APISIX 增加了对 etcd mTLS 的支持后,有用户反馈一直没法完成校验,而用 etcdctl 访问则是成功的。在跟用户交流后,我决定拿他的证书来复现下。

在复现过程中,我注意到 etcd 日志里面有这样的报错:

2021-06-09 11:10:13.022735 I | embed: rejected connection from "127.0.0.1:50898" (error "tls: failed to verify client's certificate: x509: certificate specifies an incompatible key usage", ServerName "")
WARNING: 2021/06/09 11:10:13 grpc: addrConn.createTransport failed to connect to {127.0.0.1:12379 0 }. Err :connection error: desc = "transport: authentication handshake failed: remote error: tls: bad certificate". Reconnecting...

“bad certificate” 错误信息,初看像是因为我们发给 etcd 的客户端证书不对。但仔细瞧瞧,会发现这个报错是在 gRPC server 里面报的。

gRPC-gateway 在 etcd 里面起到一个代理的作用,把外面的 HTTP 请求变成 gRPC server 能处理的 gRPC 请求。

大体架构如下:

etcdctl ----> gRPC server
Apache APISIX ---> gRPC-gateway ---> gRPC server

为什么 etcdctl 直连 gRPC server 能通,而中间加一层 gRPC-gateway 就不行?

原来当 etcd 启用了客户端证书校验之后,用 gRPC-gateway 连接 gRPC server 就需要提供一个客户端证书。猜猜这个证书从哪来?

etcd 把配置的服务端证书直接作为这里的客户端证书用了。

一个证书既在服务端上提供验证,又在客户端上表明身份,看上去也没什么问题。除非……

除非证书上启用了 server auth 的拓展,但是没有启用 client auth。

对有问题的证书执行

openssl x509 -text -noout -in /tmp/bad.crt

会看到这样的输出:

X509v3 extensions:X509v3 Key Usage: criticalDigital Signature, Key EnciphermentX509v3 Extended Key Usage:TLS Web Server Authentication

注意这里的 “TLS Web Server Authentication”,如果我们把它改成 “TLS Web Server Authentication, TLS Web Client Authentication”,抑或不加这个拓展,就没有问题了。

etcd 上也有关于这个问题的 issue:https://github.com/etcd-io/etcd/issues/9785

结语

虽然我们在上文列出了几点小问题,但是瑕不掩瑜,etcd 对 HTTP 访问的支持还是一个非常有用的特性。

感谢 Apache APISIX 的用户们,正是因为我们有着广阔的用户群,才能发现 etcd 的这些细节上的问题。我们作为 etcd 的一大用户,在之后的日子里也将一如既往地跟 etcd 的开发者多多交流。

关于作者

罗泽轩,支流科技工程师,主要负责 Apache APISIX DP 面的开发,专注于 API 网关领域技术,毕业于华南理工大学。

参考阅读

  • 一文搞懂 etcd 3.5 核心特性

  • 谈谈实体的 ID 与“键”

  • 消息中间件:为什么我们选择 RocketMQ

  • 分布式一致性算法Raft

  • dubbogo 是如何炼成的?

原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。

2021年GIAC调整到7月30-31日在深圳举行,点击阅读原文了解更多详情。

差之毫厘:etcd 3 完美支持 HTTP 访问相关推荐

  1. PHP生成PDF完美支持中文,解决TCPDF乱码

    PHP生成PDF完美支持中文,解决TCPDF乱码 2011-09-26 09:04 418人阅读 评论(0) 收藏 举报 phpfontsheaderttfxhtml文档 PHP生成PDF完美支持中文 ...

  2. scss2css vscode设置_VSCode下让CSS文件完美支持SCSS或SASS语法方法

    VSCode下让CSS文件完美支持SCSS或SASS语法方法 习惯Webpack + PostCSS后, 通常PostCSS都是直接对CSS文件进行处理, 但是大部分习惯SCSS/SASS/LESS的 ...

  3. 加粉推广全能助手 推广辅助工具 好多粉微信号加粉复制统计工具加强版,加粉推广神器,持续完善升级,新增统计点击转化,页面插件功能,完美支持ocpc接口

    最新一次版本是3.7版了,相比最开始的版本,新增了行为转化统计,落地页插件功能. 可能大家还不明白我们的这个系统有什么用了? 好吧,那就简单的介绍下,我们的系统可以给目前的加粉推广的提供最完善的数据统 ...

  4. Retrofit 2.0 超能实践(一),okHttp完美支持Https传输

    http: //blog.csdn.net/sk719887916/article/details/51597816 Tamic首发 前阵子看到圈子里Retrofit 2.0,RxJava(Andro ...

  5. thinkphp5整合系列之汉字转拼音完美支持多音字

    thinkphp5整合系列之汉字转拼音完美支持多音字 1.进入thinkphp5项目的根目录,用composer 安装扩展 2.接下来需要做的事就是在控制器中引入 /vendor/overtrue/p ...

  6. OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持 RxJava,比 Retrofit 更简单易用。

    okhttp-OkGo 项目地址:jeasonlzy/okhttp-OkGo 简介:OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持 RxJava,比 Retrofit 更简单易 ...

  7. 开源OkHttpUtils升级版OkGo,完美支持RxJava

    转载自:http://blog.csdn.net/sky_pjf/article/details/52781025 OkGo - OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持 ...

  8. OkHttpUtils | okhttp-OkGo的使用,完美支持RxJava

    github欢迎fork,star OkGo - OkHttpUtils-2.0.0 升级后改名 OkGo,全新完美支持RxJava 该库是封装了okhttp的网络框架,可以与RxJava完美结合,比 ...

  9. 英特尔第十代处理器为什么不支持win7_10代处理器能装win7吗(9代cpu完美支持win7)...

    10代处理器能装win7吗 AMD Athlon LLX3450是一个64位处理器,当然,您可以安装64位Win7System. 最佳内存为4g以上,安装价格约800元的中档消费低调显卡. 英特尔核心 ...

最新文章

  1. 村上春树 开始写作_如何克服对写作的恐惧并找到开始的动力
  2. Python获取屏幕分辨率大小
  3. 全志a64linux内核编译,芯灵思Sinlinx A64 Linuxqt编译安装
  4. Material组件之MaterialApp、Scaffold、AppBar学习笔记
  5. FZU-2218 Simple String Problem(状态压缩DP)
  6. python八大选择排序_python之八大排序方法
  7. 计算机考研分析题,2020计算机考研,易错题分析与常考点总结
  8. STM8学习笔记---定时器 TIM2功能实现
  9. HDU2206 IP的计算【文本处理】
  10. xenCenter创建镜像库和挂载硬盘
  11. 软考软件设计师下午真题-面向对象的程序设计与实现-装饰设计模式(2012年上半年试题六))Java代码讲解
  12. 关于.dll文件的注册,如何注册.dll文件
  13. Android WIFI连接开发 WIFI工具类
  14. 英文词源 —— 法语、西班牙语、古希腊语
  15. linux上传文件到百度云盘(使用shell脚本,不依赖python库)
  16. linux命令man ls,linux 命令ls man手册的详解
  17. 考研复试计算机网络篇
  18. 张小飞的Java之路——第三章
  19. 0x80073712_Win10更新提示0x80073712错误代码解决方法
  20. JAVA基础学习-复习day11

热门文章

  1. js银行卡、手机号等校验汇总
  2. “易+”开源 | 简单可信赖,GameSentry 正式开源
  3. 大陆首款车量AI芯片 开启国产替代新纪元
  4. 【软件测试】离开“浪浪山“测试人迎来的春天......
  5. 2的31次方-1的python表达式_[python]运算符与表达式
  6. kzzi k980 三模键盘 说明书
  7. BFC是什么?BFC的四种理解方式
  8. 计算机设备预计净残值,电子设备折旧年限及残值率
  9. uniapp 密码显示隐藏
  10. 通过youtube上传视频赚钱并免费宣传你的业务