在 AWS 上使用 Kubernetes 部署 HTTP/2 Web 服务器

Posted

技术标签:

【中文标题】在 AWS 上使用 Kubernetes 部署 HTTP/2 Web 服务器【英文标题】:Deploying an HTTP/2 web-server with Kubernetes on AWS 【发布时间】:2019-01-06 01:58:57 【问题描述】:

我有一个 Go 服务器,目前在 AWS 上运行 Kubernetes。该网站位于 route-53 和管理 SSL 终止的 ELB 下。 现在,我想在我的网络服务器中支持 HTTP/2 以便将资源推送到客户端,我看到 HTTP/2 要求网络服务器使用 HTTPS。据此,我有几个问题。

HTTP/2 需要 HTTPS - 在我的情况下,HTTPS 逻辑位于 ELB 中,它为我管理 SSL 终止。我的应用程序将解密数据作为简单的 HTTP 请求获取。我是否需要删除 ELB 才能在我的网络服务器中启用 HTTP/2? 有没有办法让 ELB 留在那里并在我的网络服务器中启用 HTTP/2?

在我的本地开发中,我使用 openssl 生成证书。如果我部署 Web 服务器,我需要从 AWS 获取 CA 证书并将其存储在 Kubernetes 证书管理器中的某个位置,并在初始化时注入我的 Web 服务器。推荐的方法是什么?

我觉得我错过了一些东西,所以我会很感激任何帮助。谢谢

【问题讨论】:

你在你的 kubernetes 中使用了任何入口控制器吗? 【参考方案1】:

新的 ELB 支持 HTTP/2 (https://aws.amazon.com/blogs/aws/new-aws-application-load-balancer/) 但不支持 Push 属性 (https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html#listener-configuration):“You can't use the server-push feature of HTTP/2”

如果您想使用 Push,您可以将 ELB 用作四级 TCP LoadBalancer,并在您的网络服务器上启用它。对于 HaProxy,仍然可以使用此设置 (HTTP/2 behind reverse proxy) 抵消 SSL/TLS,但不确定在 ELB 下是否可能(可能不是)。这是因为虽然 HTTP/2 需要来自所有主要浏览器的 HTTPS,但它不是协议本身的要求,因此负载平衡器 -> 服务器可以在没有 HTTPS 的情况下通过 HTTP/2(称为 h2c)。

但是,我想说 HTTP/2 推送非常复杂 - 请阅读 Google 的 Jake Archibald 撰写的这篇精彩文章:https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/。通常发现它在少数情况下会受益,并且不会导致大多数情况发生变化,甚至会导致其他情况下的性能下降。归根结底,它在 HTTP/2 功能方面有点让人失望,但我个人认为它的探索还不够多,所以可能还有一些积极的结果。

所以如果你不想要 Push 那么前端升级到 HTTP/2 还有意义吗?在我看来是的,正如我在此处的回答中所详述的那样:HTTP2 with node.js behind nginx proxy。这也表明,从 LB 到 Web 服务器的后端没有真正需要 HTTP/2,这意味着您可以将其保留为 HTTPS 卸载面包平衡器。

需要注意的是,有些用例 HTTP/2 比较慢:

    数据包丢失严重(即 Internet 连接非常差)。这里 HTTP/2 使用的单个 TCP 连接和它的 TCP Head of Line Blocking 意味着该连接遭受超过 6 个单独的 HTTP/1 连接。 QUIC 是一种比 HTTP/2 更新的协议(它还没有推出,所以除了在 Google 服务器上之外还没有真正可用)解决了这个问题。 由于 AWS 的具体实施,对于大数据包。有趣的帖子在这里:https://medium.com/@ptforsberg/on-the-aws-application-load-balancer-http-2-support-fad4bc67b21a。对于最有可能用于 API 的真正大型下载来说,这只是一个真正的问题,并且对于大多数网站来说不应该是一个问题(如果是这样,那么您应该优化您的网站,因为 HTTP/2 无论如何都无济于事!) .可以通过升级 HTTP/2 窗口大小设置轻松修复,但看起来 ELB 不允许您设置此设置。

【讨论】:

巴里,我觉得你的回答很有趣。您没有明确反驳我的答案,而是插入了诸如 QUIC 等 AWS 中尚不存在的前向技术。您还与 AWS 讨论了与我的回答一致的问题(限制),您只是使用了不同的措辞 - 但您发现我的回答是错误的。你的反回答也有缺陷。这是我的建议,让我们创建一个新问题,您和我可以在下面进行辩论。主题将是 AWS 上的 HTTP/2。明天没有关于 HTTP/2 的技术理论,只是 AWS 如何在今天的现实世界中实现 HTTP/2。 我的回答不是为了对您的回答提出异议,而是为了回答这个问题,并提供我认为可能有趣且相关的额外信息(很像您回答的最后一部分)。我对您的回答的评论是对您的回答的 2 个特定部分提出异议,我认为这些部分是不正确的。就目前 AWS 支持的内容而言,也许它们是“正确的”,如果您更新答案以反映这一点,那么我很乐意撤回我的保留并删除我的 cmets,因为我认为现在还不清楚。如果您的回答有缺陷,请告诉我,以便我更正。 同意。明天我会进一步评论。【参考方案2】:

如果您的后端也不是 HTTP2,那么在 AWS 负载均衡器上部署 HTTP2 没有任何好处。从技术上讲,HTTP2 不需要 HTTPS,但没有人为 HTTP 实现 HTTP2。 HTTP2 是一种协议优化(简单观点),它消除了 SSL 协商中的往返,改进了流水线等。如果负载均衡器通过 HTTP 与您的后端通信,则不会有任何改进。由于 HTTPS 设置期间的往返次数减少,负载均衡器的负载会略有下降。

我建议您将后端服务配置为仅使用 HTTPS(将客户端重定向到 HTTPS)并使用 SSL 证书。然后配置HTTP2,顺便也不容易。您可以使用 Let's Encrypt for SSL,效果很好。您还可以使用 OpenSSL 自签名证书(我不推荐)。您不能使用 AWS 服务为您的后端服务创建 SSL 证书,只能用于 AWS 托管服务(CloudFront、ALB 等)。

您还可以使用第 4 层 (TCP) 侦听器设置负载平衡器。这就是我在后端服务器上设置 HTTP2 时所做的。现在从客户端到后端的整个路径都使用 HTTP2,没有双重 SSL 加密/解密层。

负载平衡器的一个很好的功能称为“SSL 卸载”。这意味着您在负载平衡器上启用 SSL,并且仅在后端 Web 服务器上启用 HTTP。这违背了 HTTP2。因此,请仔细考虑您真正想要完成的任务,然后设计您的服务以实现这些目标。

另一点需要考虑。由于您正在研究 HTTP2,同时在您的服务中删除对旧 TLS 版本以及不安全的加密和散列算法的支持。今天应该强制删除 TLS 1.0,我建议也删除 TLS 1.1。除非你真的需要支持古老的浏览器或定制的低端硬件,否则 TLS 1.2 应该是今天的标准。您的日志文件可以告诉您客户端是否通过旧协议进行连接。

【讨论】:

只有前端有很多好处 (***.com/questions/41637076/…)。 HTTP/2 也没有改进 SSL 协商,除了不需要它用于额外的流。目前正在进行的 QUIC 是一项进一步的改进,它确实改进了这一点,但还没有。 @BarryPollard - AWS 服务上的 HTTP2 链接显示我的答案是错误的。我很乐意更新我的答案。 请证明您的答案的链接。有几个地方不正确。 @BarryPollard - 你刚刚卖掉了你的一本书。我会读的。为了争论,请评论我到底错在哪里。我也非常了解 HTTP2。 @BarryPollard - 我们俩都可以写出技术性很强的答案,以至于很少有人会阅读它们。关键不在于理论,而在于现实世界中发生了什么。我详细阅读了你的回答。我仍然没有在我的答案中看到错误。但是,我很喜欢您在 HTTP2 上发表的大量帖子。作为常驻专家,我将听从您的意见。来自我的 +1 票。

以上是关于在 AWS 上使用 Kubernetes 部署 HTTP/2 Web 服务器的主要内容,如果未能解决你的问题,请参考以下文章

在 AWS EKS 上使用 Kubernetes 身份验证方法部署 Hashicorp Vault 时出现证书错误

如何在本地运行Kubernetes?

Kubernetes AWS EKS 负载均衡器未配置

使用 AWS 和 Kubernetes 提供商的 Terraform 循环

如何在 Kubernetes 中使用 Aws EBS 挂载 postgresql 卷

在 AWS EKS 上部署 EMQX MQTT 集群