AICon 深圳站聚焦 Agent 技术、应用与生态,大咖分享实战干货 了解详情
写点什么

服务网格数据平面的关键:层层剖析 Envoy 配置

  • 2020-05-18
  • 本文字数:6613 字

    阅读完需:约 22 分钟

服务网格数据平面的关键:层层剖析Envoy配置

服务网格是微服务设置中的通信层,也就是说往返于每个服务的所有请求都通过网格。服务网格在微服务设置中也成为基础架构层,它能够让服务之间的通信变得安全可靠。关于 Service Mesh 的基础内容,我们已经在这篇文章中详细介绍过。


每一个服务都有自己的代理服务(sidecars),然后所有代理服务一起形成服务网格。Sidecars 处理服务之间的通信,也就是说所有的流量都会通过网格并且该透明层可以控制服务之间如何交互。


服务网格通过由 API 控制的组件提供可观察性、服务发现以及负载均衡等。


实际上,如果一个服务要调用另一个服务,它不会直接调用目标服务。而是先将请求路由到本地代理,然后代理再将该请求路由到目标服务。这一过程意味着服务实例不会和其他服务直接接触,仅与本地代理进行通信。



本地代理服务


根据 ThoughtWorks Technology Radar(这是一份半年度的文档,用于评估现有技术和新生技术的风险和收益)指出,“服务网格提供一致的发现、安全性、跟踪(tracing)、监控以及故障处理,而无需共享资源(如 API 网关或 ESB)。一个十分典型的用例是轻量的反向代理进程会与每个服务进程或单独的容器一起部署。”


当谈到服务网格时,不可避免谈到的是“sidecar”——可用于每个服务实例的代理。每个 sidecar 负责管理一个服务的一个实例。我们将在本文中进一步详细讨论 sidecar。

服务网格可以交付什么?


服务网格可以交付的功能


当前,越来越多的企业和组织开始转向微服务架构。这样的企业需要服务网格所提供的上述功能。解耦库的使用或自定义代码的方法无疑是赢家。

为什么使用 Envoy?

Envoy 不是构建一个服务网格的唯一选择,市面上还有其他的代理如 Nginx、Traefik 等。我之所以选择 Envoy,这个用 C++编写的高性能代理,是因为我更喜欢 Envoy 的轻量、强大的路由,及其提供的可观察性和可扩展性。


让我们首先构建 1 个包含 3 个服务的服务网格设置,这是我们正在尝试构建的架构:



sidecar 代理的服务设置

Front Envoy

在我们的设置中 Front Envoy 是一个边缘代理,我们通常在其中执行 TLS 终止、身份验证、生成请求头等操作。


我们来看看 Front Envoy 配置:


---admin:  access_log_path: "/tmp/admin_access.log"  address:     socket_address:       address: "127.0.0.1"      port_value: 9901static_resources:   listeners:    -       name: "http_listener"      address:         socket_address:           address: "0.0.0.0"          port_value: 80      filter_chains:          filters:             -               name: "envoy.http_connection_manager"              config:                stat_prefix: "ingress"                route_config:                   name: "local_route"                  virtual_hosts:                     -                       name: "http-route"                      domains:                         - "*"                      routes:                         -                           match:                             prefix: "/"                          route:                            cluster: "service_a"                http_filters:                  -                     name: "envoy.router"  clusters:    -       name: "service_a"      connect_timeout: "0.25s"      type: "strict_dns"      lb_policy: "ROUND_ROBIN"      hosts:        -           socket_address:             address: "service_a_envoy"            port_value: 8786
复制代码


Envoy 配置主要由以下部分组成:


1、 监听器(Listener)


2、 路由


3、 集群


4、 端点

监听器

一个或多个监听器可以在单个 Envoy 实例中运行。在以上 9 到 36 行的代码提到了当前监听器的地址和端口。每个监听器也可以有一个或多个网络过滤器。这些过滤器可以启用路由、tls 终止、流量转移等活动。除了 envoy.http_connection_manager 使用的是内置过滤器之外,Envoy 还有其他几个过滤器。

路由

22 行到 34 行代码为过滤器配置了路由规范,同时它也指定了我们所接受请求的域以及路由匹配器。路由匹配器可以根据配置的规则匹配每个请求,并将请求转发到适当的集群。

集群

集群是 Envoy 将流量路由到的上游服务规范。41 行到 48 行代码定义了“Service A”,这是 Front Envoy 要通信的唯一上游。“connect_timeout”是在返回 503 之前建立与上游服务的连接的时间限制。


通常情况下,有多个“Serivce A”实例,并且 Envoy 支持多种负载均衡算法来路由流量。在本例中,我们使用了一个简单的循环算法。

端点

“host”指定我们要将流量路由到的 Service A 的实例。在本例中,我们只有 1 个实例。


第 47 行代码没有直接与 Service A 进行通信,而是与 Service A 的 Envoy 代理实例进行通信,该代理将路由到本地 Service A 实例。


我们还可以利用返回 Service A 的所有实例的服务名称(如 Kubernetes 中的 headless 服务),来执行客户端负载均衡。Envoy 缓存 Service A 的所有 host,并每 5 秒刷新一次 host 列表。


此外,Envoy 还支持主动和被动的健康检查。因此,如果我们要进行主动健康检查,我们需要在集群配置部分对其进行配置。

其他

第 2 行到第 7 行配置了管理服务器,它能够帮助查看配置、更改日志级别、查看统计信息等。


第 8 行的“static_resources”可以手动加载所有配置。我们将在下文讨论如何动态地执行此操作。


虽然这里描述了许多其他配置,但是我们的目标不是全面介绍所有配置,而是以最少的配置开始。

Service A

这是 Service A 的 Envoy 配置:


admin:  access_log_path: "/tmp/admin_access.log"  address:     socket_address:       address: "127.0.0.1"      port_value: 9901static_resources:  listeners:
- name: "service-a-svc-http-listener" address: socket_address: address: "0.0.0.0" port_value: 8786 filter_chains: - filters: - name: "envoy.http_connection_manager" config: stat_prefix: "ingress" codec_type: "AUTO" route_config: name: "service-a-svc-http-route" virtual_hosts: - name: "service-a-svc-http-route" domains: - "*" routes: - match: prefix: "/" route: cluster: "service_a" http_filters: - name: "envoy.router" - name: "service-b-svc-http-listener" address: socket_address: address: "0.0.0.0" port_value: 8788 filter_chains: - filters: - name: "envoy.http_connection_manager" config: stat_prefix: "egress" codec_type: "AUTO" route_config: name: "service-b-svc-http-route" virtual_hosts: - name: "service-b-svc-http-route" domains: - "*" routes: - match: prefix: "/" route: cluster: "service_b" http_filters: - name: "envoy.router"
- name: "service-c-svc-http-listener" address: socket_address: address: "0.0.0.0" port_value: 8791 filter_chains: - filters: - name: "envoy.http_connection_manager" config: stat_prefix: "egress" codec_type: "AUTO" route_config: name: "service-b-svc-http-route" virtual_hosts: - name: "service-b-svc-http-route" domains: - "*" routes: - match: prefix: "/" route: cluster: "service_c" http_filters: - name: "envoy.router" clusters: - name: "service_a" connect_timeout: "0.25s" type: "strict_dns" lb_policy: "ROUND_ROBIN" hosts: - socket_address: address: "service_a" port_value: 8081 - name: "service_b" connect_timeout: "0.25s" type: "strict_dns" lb_policy: "ROUND_ROBIN" hosts: - socket_address: address: "service_b_envoy" port_value: 8789
- name: "service_c" connect_timeout: "0.25s" type: "strict_dns" lb_policy: "ROUND_ROBIN" hosts: - socket_address: address: "service_c_envoy" port_value: 8790
复制代码


11 行到 39 行定义了一个监听器来路由流量到实际的 Service A 实例。在 103 行到 111 行中找到 service_a 实例的相应集群定义。


Service A 与 Service B 和 Service C 进行通信,它指向了两个以上的监听器以及集群。在本例中,我们为每个上游(localhost、Service B 和 Service C)分离了监听器。另一种方法是使用单个监听器,并根据 URL 或请求头路由到任意上游。

Service B 和 Service C

Service B 和 Service C 处于叶级,除了本地主机服务实例外,不与任何其他上游通信。因此其配置十分简单。


而让事情变得复杂的是上述配置中的单个监听器和单个集群。


配置完成后,我们将此设置部署到 Kubernetes 或使用 docker-compose 对其进行测试。你可以运行 docker-compose build 和 docker-compose up 并点击 localhost:8080,以查看请求是否成功通过所有服务和 Envoy 代理。我们可以使用日志对其进行验证。

Envoy xDS

我们为每个 sidecar 提供了配置,并且根据不同的服务,服务之间的配置也有所不同。虽然我们可以手动制作和管理 sidecar 配置,但最初至少要提供 2 或 3 个服务,并且随着服务数量的增加,配置会变得十分复杂。此外,每次 sidecar 配置更改时,你都必须重新启动 Envoy 实例,以使更改生效。


正如上文所讨论的,我们可以通过使用 API server 来避免手动配置并加载所有组件:集群(CDS)、端点(EDS)、监听器(LDS)以及路由(RDS)。所以每个 sidecar 将与 API server 通信并接收配置。当新配置更新到 API server 时,它将自动反映在 Envoy 实例中,从而避免了重新启动。


你可以在以下链接中了解关于动态配置的信息:


https://www.envoyproxy.io/docs/envoy/latest/configuration/overview/v2_overview#dynamic


这有一个简单的 xDS server:


https://github.com/tak2siva/Envoy-Pilot

如何在 Kubernetes 中实现

本部分将讨论如果我们要在 Kubernetes 中实现所讨论的设置该怎么办。以下是架构图:


因此,将需要更改:


  • Pod

  • 服务

部署 Pod

尽管 Pod 规范中仅定义了一个容器——按照定义,一个 Pod 可以容纳一个或多个容器。为了对每个服务实例运行 sidecar 代理,我们将 Envoy 容器添加到每个 Pod 中。为了与外界通信,服务容器将通过 localhost 与 Envoy 容器进行对话。


部署文件如下所示:


admin:  access_log_path: "/tmp/admin_access.log"  address:     socket_address:       address: "127.0.0.1"      port_value: 9901static_resources:  listeners:
- name: "service-b-svc-http-listener" address: socket_address: address: "0.0.0.0" port_value: 8789 filter_chains: - filters: - name: "envoy.http_connection_manager" config: stat_prefix: "ingress" codec_type: "AUTO" route_config: name: "service-b-svc-http-route" virtual_hosts: - name: "service-b-svc-http-route" domains: - "*" routes: - match: prefix: "/" route: cluster: "service_b" http_filters: - name: "envoy.router" clusters: - name: "service_b" connect_timeout: "0.25s" type: "strict_dns" lb_policy: "ROUND_ROBIN" hosts: - socket_address: address: "service_b" port_value: 8082
复制代码


在容器部分添加了 Envoy sidecar,并且在 33 到 39 行的 configmap 中我们挂载了我们的 Envoy 配置文件。

更改服务

Kubernetes 服务负责维护 Pod 端点列表,该列表可以路由流量。尽管 kube-proxy 通常处理 Pod 端点之间的负载均衡,但在本例中,我们将执行客户端负载均衡,并且我们不希望 kube-proxy 进行负载均衡。此外,我们想要提取 Pod 端点列表并对其进行负载均衡。为此,我们需要使用“headless 服务“来返回端点列表。


如下所示:


kind: Deploymentmetadata:  name: serviceaspec:  replicas: 2  template:    metadata:      labels:        app: servicea    spec:      containers:      - name: servicea        image: dnivra26/servicea:0.6        ports:        - containerPort: 8081          name: svc-port          protocol: TCP      - name: envoy        image: envoyproxy/envoy:latest        ports:          - containerPort: 9901            protocol: TCP            name: envoy-admin          - containerPort: 8786            protocol: TCP            name: envoy-web        volumeMounts:          - name: envoy-config-volume            mountPath: /etc/envoy-config/        command: ["/usr/local/bin/envoy"]        args: ["-c", "/etc/envoy-config/config.yaml", "--v2-config-only", "-l", "info","--service-cluster","servicea","--service-node","servicea", "--log-format", "[METADATA][%Y-%m-%d %T.%e][%t][%l][%n] %v"]      volumes:        - name: envoy-config-volume          configMap:            name: sidecar-config            items:              - key: envoy-config                path: config.yaml
复制代码


有两件事需要注意。一是第 6 行使服务变成 headless,二是我们不是将 Kubernetes 服务端口映射到应用程序的服务端口,而是映射到 Envoy 监听器端口。这意味着,流量首先通向 Envoy。即便如此,Kubernetes 也可以完美运行。


在本文中,我们看到了如何使用 Envoy 代理构建服务网格。其中,我们设置了所有通信都将通过网格。因此,现在网格不仅有大量有关流量的数据,而且还具有控制权。


以下链接中你可以获取我们所讨论的配置和代码:


https://github.com/dnivra26/envoy_servicemesh


原文链接:

https://www.thoughtworks.com/insights/blog/building-service-mesh-envoy-0


2020-05-18 18:071303

评论

发布
暂无评论
发现更多内容

2023年度十佳课题公布:华为云GaussDB获权威认可

华为云开发者联盟

数据库 后端 华为云 华为云GaussDB 华为云开发者联盟

18个JavaScript技巧:编写简洁高效的代码

南城FE

JavaScript 前端 代码质量

macOS思维导图软件 ClickCharts for Mac v9.0.3激活版

Rose

苹果软件下载 思维导图软件 ClickCharts Mac破解

非内积级联学习

京东科技开发者

文心一言 VS 讯飞星火 VS chatgpt (190)-- 算法导论14.1 7题

福大大架构师每日一题

福大大架构师每日一题

室内设计软件Room Arranger 中文直装版 v9.8.2.644

Rose

室内设计 Room Arranger破解版 Room Arranger下载

矢量插图设计绘制Canvas X Draw v7.0.4激活版

Rose

Canvas X Draw 插图绘制软件 苹果软件资源下载

更简单高效地Git客户端 Tower for Mac注册版 兼容m1/m2

Rose

Git客户端 Tower破解版 Tower mac版

Wireshark的捕获过滤器

小齐写代码

LED屏模组偏色怎么办?

Dylan

LED显示屏 全彩LED显示屏 led显示屏厂家

基于volcano实现节点真实负载感知调度

华为云开发者联盟

云原生 后端 华为云 Volcano 华为云开发者联盟

【年后跳槽必看篇-非广告】Kafka核心知识点 第三章

派大星

kafka Java’

华为云DTSE助力车卫士架构升级,探索智能出行行业数字化新路径

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 华为云DTSE

MIAOYUN获评OpenCloudOS社区2023年度优秀贡献企业

MIAOYUN

开源 云原生 开源操作系统 MIAOYUN OpenCloudOS 社区

iZotope智能混音插件Mac版下载 iZotope Neutron 4破解 v4.5.0激活版

Rose

Mac软件 iZotope Neutron 4 智能混音插件

报名AI产品原型设计公开课!与ProtoPie一起打造高保真AI原型

飞桨PaddlePaddle

百度 AI 百度飞桨 应用开发 飞桨星河社区

图片浏览和管理软件EdgeView 4 for Mac v4.4.7激活版

Rose

mac软件下载 苹果软件资源 EdgeView 4 图片浏览

【分布式技术专题】「探索高性能远程通信」基于Netty的分布式通信框架实现(Dispatcher和EventListener)(下)

码界西柚

分布式 Netty RPC 远程通信 2024年第二十六篇文章

一文搞懂设计模式—责任链模式

Java随想录

Java 设计模式

GraphicConverter 12 :简单好用的图片浏览编辑器

Rose

GraphicConverter 12中文 GraphicConverter破解 Mac图片编辑器

苹果电脑 电子邮件客户端 Mimestream for Mac

Rose

Mac软件 Mimestream Mac破解版 Mimestream 下载 邮件客户端 Gmail邮箱

如何在网页上下载高质量视频和音频文件?推荐使用PullTube for Mac在线视频下载器

Rose

Mac视频下载器 PullTube使用教程 PullTube mac

用Chrome,Edge,360等浏览器如何调用底层硬件模块?

非也

chrome edge 信创 360安全浏览器 前端ui组件库

Amadine for Mac矢量绘图软件 v1.5.5激活版 兼容m1/m2

Rose

矢量图设计 Amadine破解版 Amadine Mac

Boxy SVG v4.23.2免激活版 mac矢量图编辑器 支持m1/m2

Rose

苹果软件下载 矢量图形编辑软件 Boxy SVG破解版 Boxy SVG mac下载

服务网格数据平面的关键:层层剖析Envoy配置_文化 & 方法_Rancher_InfoQ精选文章