Skip to content

Commit

Permalink
Merge pull request envoyproxy#133 from vgbhfive/zh
Browse files Browse the repository at this point in the history
vgbh translate upgrade
  • Loading branch information
helight committed Nov 17, 2020
2 parents b4676a3 + 6bd9629 commit e77d5ce
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 89 deletions.
131 changes: 53 additions & 78 deletions docs/root/intro/arch_overview/http/upgrades.rst
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
.. _arch_overview_upgrades:

HTTP upgrades
===========================

Envoy Upgrade support is intended mainly for WebSocket and CONNECT support, but may be used for
arbitrary upgrades as well. Upgrades pass both the HTTP headers and the upgrade payload
through an HTTP filter chain. One may configure the
:ref:`upgrade_configs <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.upgrade_configs>`
with or without custom filter chains. If only the
:ref:`upgrade_type <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.UpgradeConfig.upgrade_type>`
is specified, both the upgrade headers, any request and response body, and HTTP data payload will
pass through the default HTTP filter chain. To avoid the use of HTTP-only filters for upgrade payload,
one can set up custom
:ref:`filters <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.UpgradeConfig.filters>`
for the given upgrade type, up to and including only using the router filter to send the HTTP
data upstream.

Upgrades can be enabled or disabled on a :ref:`per-route <envoy_v3_api_field_config.route.v3.RouteAction.upgrade_configs>` basis.
Any per-route enabling/disabling automatically overrides HttpConnectionManager configuration as
laid out below, but custom filter chains can only be configured on a per-HttpConnectionManager basis.
HTTP 升级
==========

Envoy 升级主要用于支持 WebSocket 和 CONNECT 在 HTTP 请求中的的升级,同时也支持其他依赖于 HTTP 的升级。
HTTP 升级在通常情况下是通过 HTTP 过滤链来传递 HTTP header 和 HTTP 升级所需的负载信息。
除此之外也可以使用或者不使用自定义过滤链来配置 :ref:`upgrade_configs <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.upgrade_configs>`
如果指定了 :ref:`upgrade_type <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.UpgradeConfig.upgrade_type>`
的类型,那么升级后的HTTP 头信息、请求体、返回体、HTTP 负载数据默认都将通过 HTTP 过滤器链。
此外为了避免升级负载仅使用 HTTP 过滤器,可以为给定的升级类型设置自定义的过滤器,同时也只能使用路由
:ref:`filters <envoy_v3_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.UpgradeConfig.filters>` 将数据发往上游。

HTTP 升级可以根据 :ref:`每个路由 <envoy_v3_api_field_config.route.v3.RouteAction.upgrade_configs>` 进行启用还是禁用。
同时任意的路由启用/禁用都会自动覆盖 HttpConnectionManager 配置信息。
如下图所示,自定义过滤器链只能基于每个 HttpConnectionManager 进行配置。

+-----------------------+-------------------------+-------------------+
| *HCM Upgrade Enabled* | *Route Upgrade Enabled* | *Upgrade Enabled* |
Expand All @@ -32,73 +27,53 @@ laid out below, but custom filter chains can only be configured on a per-HttpCon
| F | F | F |
+-----------------------+-------------------------+-------------------+

Note that the statistics for upgrades are all bundled together so WebSocket and other upgrades
:ref:`statistics <config_http_conn_man_stats>` are tracked by stats such as
downstream_cx_upgrades_total and downstream_cx_upgrades_active
注意!所有升级的统计信息是绑定在一起的,例如 WebSocket 或者其他的 HTTP 升级都是通过 downstream_cx_upgrades_total 和 downstream_cx_upgrades_active 来统计信息的。

Websocket over HTTP/2 hops
^^^^^^^^^^^^^^^^^^^^^^^^^^
越过 HTTP1.2 生成 WebSocket
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

While HTTP/2 support for WebSockets is off by default, Envoy does support tunneling WebSockets over
HTTP/2 streams for deployments that prefer a uniform HTTP/2 mesh throughout; this enables, for example,
a deployment of the form:
默认情况下,HTTP1.2 对 WebSocket 的支持都是关闭的,但 Envoy 却支持 WebSocket 在 HTTP1.2 上进行隧道传输,以便在整个部署过程中可以使用统一的 HTTP1.2 网络。
例如,可以这样进行部署:

[Client] ---- HTTP/1.1 ---- [Front Envoy] ---- HTTP/2 ---- [Sidecar Envoy ---- H1 ---- App]

In this case, if a client is for example using WebSocket, we want the Websocket to arrive at the
upstream server functionally intact, which means it needs to traverse the HTTP/2 hop.

This is accomplished via `Extended CONNECT (RFC8441) <https://tools.ietf.org/html/rfc8441>`_ support,
turned on by setting :ref:`allow_connect <envoy_v3_api_field_config.core.v3.Http2ProtocolOptions.allow_connect>`
true at the second layer Envoy. The
WebSocket request will be transformed into an HTTP/2 CONNECT stream, with :protocol header
indicating the original upgrade, traverse the HTTP/2 hop, and be downgraded back into an HTTP/1
WebSocket Upgrade. This same Upgrade-CONNECT-Upgrade transformation will be performed on any
HTTP/2 hop, with the documented flaw that the HTTP/1.1 method is always assumed to be GET.
Non-WebSocket upgrades are allowed to use any valid HTTP method (i.e. POST) and the current
upgrade/downgrade mechanism will drop the original method and transform the Upgrade request to
a GET method on the final Envoy-Upstream hop.

Note that the HTTP/2 upgrade path has very strict HTTP/1.1 compliance, so will not proxy WebSocket
upgrade requests or responses with bodies.

CONNECT support
^^^^^^^^^^^^^^^

Envoy CONNECT support is off by default (Envoy will send an internally generated 403 in response to
CONNECT requests). CONNECT support can be enabled via the upgrade options described above, setting
the upgrade value to the special keyword "CONNECT".

While for HTTP/2, CONNECT request may have a path, in general and for HTTP/1.1 CONNECT requests do
not have a path, and can only be matched using a
:ref:`connect_matcher <envoy_v3_api_msg_config.route.v3.RouteMatch.ConnectMatcher>`

Envoy can handle CONNECT in one of two ways, either proxying the CONNECT headers through as if they
were any other request, and letting the upstream terminate the CONNECT request, or by terminating the
CONNECT request, and forwarding the payload as raw TCP data. When CONNECT upgrade configuration is
set up, the default behavior is to proxy the CONNECT request, treating it like any other request using
the upgrade path.
If termination is desired, this can be accomplished by setting
:ref:`connect_config <envoy_v3_api_field_config.route.v3.RouteAction.UpgradeConfig.connect_config>`
If it that message is present for CONNECT requests, the router filter will strip the request headers,
and forward the HTTP payload upstream. On receipt of initial TCP data from upstream, the router
will synthesize 200 response headers, and then forward the TCP data as the HTTP response body.
在上面的示例中,客户端需要使用 WebSocket,同时我们也希望 WebSocket 可以直接到达上游业务服务器,那就意味着只穿过 HTTP 1.2 即可到达。

上述实例中的方法是通过扩展连接( `RFC8441 <https://tools.ietf.org/html/rfc8441>`_ )支持实现的,通过在第二层 Envoy 中设置 :ref:`allow_connect <envoy_v3_api_field_config.core.v3.Http2ProtocolOptions.allow_connect>` 打开的。
在 WebSocket 请求被转换为 HTTP CONNECT 流时,其中包含protocol 头指示原始升级、遍历 跳转 HTTP1.2 、降级回 HTTP1.1 WebSocket Upgrade。
相同的 Upgrade-CONNECT-Upgrade 转换将会在任意 HTTP1.2 上跳转执行,即假设 HTTP1.1 中请求方法为 GET 。
非 WebSocket 升级则允许任何有效的 HTTP 方法(例如 POST 请求),当前的升级/降级机制也会丢弃原有的请求方式,最终Envoy 会将请求转换为去往上游的 GET 方法。

注意!HTTP1.2 升级会非常严格的 HTTP1.1 的路径,因此不能使用代理用于WebSocket 升级的请求和响应。

CONNECT 支持
^^^^^^^^^^^^^^

默认情况下,Envoy 内部的 CONNECT 支持都是处于关闭状态的(Envoy 会返回403 状态码以响应 CONNECT 请求)。
因此,可以通过上述的选项来启用 CONNECT 支持,其中将设置特殊关键字为 “ CONNECT ”。

在HTTP1.2 中,CONNECT 请求可能会是一个路径,但是在HTTP1.1 中,CONNECT 请求通常是没有路径的,只能使用 :ref:`connect_matcher <envoy_v3_api_msg_config.route.v3.RouteMatch.ConnectMatcher>` 进行匹配。

注意!当对 CONNECT 请求执行非通配符域匹配时,CONNECT 的目标是匹配主机和端口才能成功,而不是匹配 Host 或者授权信息。

Envoy 可以使用两种方法来处理 CONNECT 请求,一种是代理 CONNECT 报文头,让上游终止 CONNECT 请求,就类似于其他的请求一样;或者终止 CONNECT 请求,将负载信息作为原始 TCP 信息转发。

而当 CONNECT 升级配置信息被配置时,默认情况下就是使用代理连接请求,并使用升级路径将其处理为任何其他请求。

如果需要终止,也可以通过设置 :ref:`connect_config <envoy_v3_api_field_config.route.v3.RouteAction.UpgradeConfig.connect_config>` 来完成。
如果仅仅只是针对 CONNECT 请求,路由过滤器将会去掉请求头,并将请求发往上游。
在收到来自上游的 TCP 数据时,路由就会生成 HTTP 200 响应头信息,然后将上游返回的 TCP 数据作为 HTTP 响应体。

.. warning::
This mode of CONNECT support can create major security holes if not configured correctly, as the upstream
will be forwarded *unsanitized* headers if they are in the body payload. Please use with caution
如果配置不正确,这种 CONNECT 支持连接会造成严重的安全漏洞。例如如果上游的安全漏洞存在于负载中,那么上游就会转发未经初始化的头信息。谨慎使用!

HTTP1.2 之上的TCP 隧道
^^^^^^^^^^^^^^^^^^^^^^^^

Tunneling TCP over HTTP/2
^^^^^^^^^^^^^^^^^^^^^^^^^
Envoy also has support for transforming raw TCP into HTTP/2 CONNECT requests. This can be used to
proxy multiplexed TCP over pre-warmed secure connections and amortize the cost of any TLS handshake.
An example set up proxying SMTP would look something like this
Envoy 还支持将原始 TCP 请求转化为 HTTP1.2 CONNECT 请求,这是通过提前预备的安全链路来代理多路传输的 TCP 请求,并且可以分摊 TLS 握手的成本。
例如设置代理 SMTP 的流程如下:

[SMTP Upstream] --- raw SMTP --- [L2 Envoy] --- SMTP tunneled over HTTP/2 --- [L1 Envoy] --- raw SMTP --- [Client]

Examples of such a set up can be found in the Envoy example config :repo:`directory <configs/>`
If you run `bazel-bin/source/exe/envoy-static --config-path configs/encapsulate_in_connect.v3.yaml --base-id 1`
and `bazel-bin/source/exe/envoy-static --config-path configs/terminate_connect.v3.yaml`
you will be running two Envoys, the first listening for TCP traffic on port 10000 and encapsulating it in an HTTP/2
CONNECT request, and the second listening for HTTP/2 on 10001, stripping the CONNECT headers, and forwarding the
original TCP upstream, in this case to google.com.
如果运行 bazel-bin/source/exe/envoy-static –config-path configs/encapsulate_in_connect.yaml –base-id 1 and bazel-bin/source/exe/envoy-static –config-path configs/terminate_connect.yaml 则能在示例配置 :repo:`文件 <configs/>` 中找到对应的示例。
其中将会运行两个 Envoy ,第一个会监听10000 端口 上的 TCP 流量,接着会将其封装为 HTTP1.2 请求;另一个会监听10001 端口上的 HTTP1.2 请求,去掉请求的请求头,接着将原始 TCP 请求转到上游,在本示例中是 google.com。
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
.. _arch_overview_compression_libraries:

Compression Libraries
=====================
压缩库
======

Underlying implementation
基础实现
-------------------------

Currently Envoy uses `zlib <http://zlib.net>`_ as a compression library.
目前 Envoy 在使用 `zlib <http://zlib.net>`_ 作为压缩库。

.. note::

`zlib-ng <https://github.com/zlib-ng/zlib-ng>`_ is a fork that hosts several 3rd-party
contributions containing new optimizations. Those optimizations are considered useful for
`improving compression performance <https://github.com/envoyproxy/envoy/issues/8448#issuecomment-667152013>`_.
Envoy can be built to use `zlib-ng <https://github.com/zlib-ng/zlib-ng>`_ instead of regular
`zlib <http://zlib.net>`_ by using ``--define zlib=ng`` Bazel option. The relevant build options
used to build `zlib-ng <https://github.com/zlib-ng/zlib-ng>`_ can be evaluated in :repo:`here
<bazel/foreign_cc/BUILD>`. Currently, this option is only available on Linux.
`zlib-ng <https://github.com/zlib-ng/zlib-ng>`_ 是一个存在多个包含最新优化的第三方贡献 Fork 库。
这其中的很多优化对于 `提高压缩性能 <https://github.com/envoyproxy/envoy/issues/8448#issuecomment-667152013>`_ 有很大的用处。
比如 Envoy 可以通过使用 --define zlib=ngbazel 选项,来构建 `zlib-ng <https://github.com/zlib-ng/zlib-ng>`_ 代替之前的 `zlib <http://zlib.net>`_ 。
用于构建 `zlib-ng <https://github.com/zlib-ng/zlib-ng>`_ 的相关参数选项,可以在 :repo:`这里 <bazel/foreign_cc/BUILD>` 找到。
但是,这些参数选项目前只能在 Linux 上使用。

0 comments on commit e77d5ce

Please sign in to comment.