2023.11.4-Envoy使用案例-oss

2023-11-04 15:45
文章标签 使用 案例 oss 2023.11 envoy

本文主要是介绍2023.11.4-Envoy使用案例-oss,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2023.11.4-Envoy使用案例

image-20231102072134362

目录

image-20231104111045505

本节实战

实战名称
🚩 实战:前端代理-2023.11.2(测试成功)
🚩 实战:流量镜像-2023.11.4(测试成功)
🚩 实战:故障注入过滤器-2023.11.4(测试成功)
🚩 实战:MySQL 过滤器-2023.11.4(测试成功)
🚩 实战:Golang HTTP 过滤器-2023.11.4(测试成功)

前言

前面我们已经学习了 Envoy 的基础知识,接下来我们就可以来学习如何使用 Envoy 来进行流量管理了。Envoy 作为一个高性能的边缘和内部代理,可以用于许多不同的场景。在本节中,我们将介绍 Envoy 的流量管理功能,包括路由、负载平衡、故障转移、故障注入、速率限制和等方面。

这些案例都位于 Envoy 官方代码仓库中的 examples 目录下,我们可以在这里找到各种使用案例。

所以我们可以先 Clone 一份 Envoy 的代码仓库到本地,然后在本地的 examples 目录下面找到对应的案例进行学习。

$ git clone https://github.com/envoyproxy/envoy.git

image-20231102201943144

1、流量拆分

Envoy 的路由器可以将流量拆分到跨两个或多个上游集群的虚拟主机中的路由,有两种常见的用例。

    1. 版本升级: 一条路由的流量逐渐从一个集群转移到另一个集群。
    1. A/B 测试: 同时测试同一服务的两个或多个版本,路由的流量必须在运行同一服务的不同版本的集群之间分配。

1.两个上游之间的流量转移

路由配置中的运行时对象决定选择特定路由的概率。通过使用 runtime_fraction 配置,可以逐渐将虚拟主机中特定路由的流量从一个群集转移到另一个群集。比如以下示例配置,其中在 Envoy 配置文件中声明了名为 helloworld 的服务的两个版本 helloworld_v1helloworld_v2

virtual_hosts:- name: www2domains:- "*"routes:- match:prefix: /runtime_fraction: # 额外匹配指定的运行时键值,每次评估匹配路径时,它必需低于此字段指示的匹配百分比;支持渐进式修改;default_value:numerator: 50denominator: HUNDREDruntime_key: routing.traffic_shift.helloworldroute:cluster: helloworld_v1- match:prefix: /route:cluster: helloworld_v2

Envoy 使用首个匹配策略来匹配路由。如果路由具有 runtime_fraction 对象,则将基于 runtime_fraction额外匹配请求(如果未指定值,则为默认值)。上面的配置中我们可以看到在第一条路由中指定了 runtime_fraction 对象,可以通过更改 runtime_fraction 值来实现流量转移。

首先,将 routing.traffic_shift.helloworld 设置为 100,这样对于 helloworld 虚拟主机的所有请求,都将与 v1 路由匹配,并由 helloworld_v1 集群提供服务。

要开始转移流量到 helloworld_v2 集群,将 routing.traffic_shift.helloworld 的值设置为 0 < x < 100。例如设置为 90,此时到 helloworld 虚拟主机的每 10 个请求中有 1 个请求将与 v1 路由不匹配,并将进入 v2 路由。

逐渐减少 routing.traffic_shift.helloworld 的值以便更大比例的请求与 v2 路由匹配。

routing.traffic_shift.helloworld 的值设置为 0 时,没有到 helloworld 虚拟主机的请求与 v1 路由匹配。所有流量此时会进入 v2 路由,由 helloworld_v2 集群提供服务。

2.跨多个上游的流量拆分

现在我们有三个(v1、v2 和 v3)而不是两个版本。可以使用 weighted_clusters 选项可以用来指定每个上游集群的权重来在三个版本之间平均分配流量(比如 33%、33%、34%)。

与前面的示例不同,一个路由条目就够了。路由中的 weighted_clusters 配置块可用于指定多个上游集群以及每个上游集群的权重。

virtual_hosts:- name: www2domains:- "*"routes:- match: { prefix: / }route:weighted_clusters:runtime_key_prefix: routing.traffic_split.helloworldclusters:- name: helloworld_v1weight: 33- name: helloworld_v2weight: 33- name: helloworld_v3weight: 34

默认情况下,权重的和必须等于 100。然后就可以通过运行时变量

routing.traffic_split.helloworld.helloworld_v1

routing.traffic_split.helloworld.helloworld_v2

routing.traffic_split.helloworld.helloworld_v3 对每个集群的权重进行动态地调整。

2、前端代理

🚩 实战:前端代理-2023.11.2(测试成功)

实验环境:

Docker Compose version v2.23.0
docker 20.10.21-ce(具有docker环境)

实验软件:

链接:https://pan.baidu.com/s/1RB2YMVeNDkX18YFQQ1suZg?pwd=0820
提取码:0820
2023.11.4-Day4-2023.10.30-Envoy使用案例

image-20231104065901821

实验步骤:

graph LRA[实战步骤] -->B(1️⃣ 拉取测试demo)A[实战步骤] -->C(2️⃣ 熟悉demo)A[实战步骤] -->D(3️⃣ 启动服务)A[实战步骤] -->E(4️⃣ 测试)A[实战步骤] -->F(5️⃣ 测试 Envoy 的负载均衡功能)

这些案例大部分都是基于官方提供的一个 Front proxy 来进行演示的,该示例可以使用 Docker Compose 进行管理,其将部署一个前置 Envoy 和几个后端服务(简单的 aiohttp 应用程序),如下图所示:

img

所有传入请求都通过前端 Envoy 进行路由,前端 Envoy 充当位于 envoymesh 网络边缘的反向代理。 Docker Compose 将端口 8080、8443 和 8001 三个端口,分别处理对服务的 HTTP、HTTPS 调用和对 /admin 的请求,docker-compose.yml 文件内容如下所示:

services:front-envoy:build:context: .dockerfile: ../shared/envoy/Dockerfiledepends_on:service-envoy-1:condition: service_healthyservice-envoy-2:condition: service_healthyports:- "${PORT_PROXY:-8080}:8080"- "${PORT_HTTPS:-8443}:8443"- "${PORT_STATS:-8001}:8001"service-envoy-1:build:context: .dockerfile: ../shared/envoy/Dockerfiletarget: envoy-adminargs:ENVOY_CONFIG: ./service-envoy.yamlENVOY_ADMIN_PORT: 8001depends_on:service1:condition: service_healthyservice1:build:context: ../shared/pythontarget: aiohttp-tracing-service2environment:- SERVICE_NAME=1service-envoy-2:build:context: .dockerfile: ../shared/envoy/Dockerfiletarget: envoy-adminargs:ENVOY_ADMIN_PORT: 8001ENVOY_CONFIG: ./service-envoy-2.yamldepends_on:service2:condition: service_healthyservice2:build:context: ../shared/pythontarget: aiohttp-tracing-service2environment:- SERVICE_NAME=2

Front Envoy 路由到服务容器的所有流量实际上都被路由到 Service Envoy 上,对应的 envoy.yaml 配置如下所示:

# envoy.yaml
static_resources:listeners:- address:socket_address:address: 0.0.0.0port_value: 8080filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagercodec_type: AUTOstat_prefix: ingress_httproute_config:name: local_routevirtual_hosts:- name: backenddomains:- "*"routes:- match:prefix: "/service/1"route:cluster: service1-envoy- match:prefix: "/service/2"route:cluster: service2-envoyhttp_filters:- name: envoy.filters.http.routertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router- address:socket_address:address: 0.0.0.0port_value: 8443filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagercodec_type: AUTOstat_prefix: ingress_httproute_config:name: local_routevirtual_hosts:- name: backenddomains:- "*"routes:- match:prefix: "/service/1"route:cluster: service1-envoy- match:prefix: "/service/2"route:cluster: service2-envoyhttp_filters:- name: envoy.filters.http.routertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Routertransport_socket:name: envoy.transport_sockets.tlstyped_config:"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContextcommon_tls_context:tls_certificates:# The following self-signed certificate pair is generated using:# $ openssl req -x509 -newkey rsa:2048 -keyout a/front-proxy-key.pem -out  a/front-proxy-crt.pem -days 3650 -nodes -subj '/CN=front-envoy'## Instead of feeding it as an inline_string, certificate pair can also be fed to Envoy# via filename. Reference: https://envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/base.proto#config-core-v3-datasource.## Or in a dynamic configuration scenario, certificate pair can be fetched remotely via# Secret Discovery Service (SDS). Reference: https://envoyproxy.io/docs/envoy/latest/configuration/security/secret.- certificate_chain:inline_string: |-----BEGIN CERTIFICATE-----MIICqDCCAZACCQCquzpHNpqBcDANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDDAtmcm9udC1lbnZveTAeFw0yMDA3MDgwMTMxNDZaFw0zMDA3MDYwMTMxNDZaMBYxFDASBgNVBAMMC2Zyb250LWVudm95MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAthnYkqVQBX+Wg7aQWyCCb87hBce1hAFhbRM8Y9dQTqxoMXZiA2n8G089hUouoQpEdJgitXVS6YMFPFUUWfwcqxYAynLK4X5im26Yfa1eO8La8sZUS+4Bjao1gF5/VJxSEo2yZ7fFBo8M4E44ZehIIocipCRS+YZehFs6dmHoq/MGvh2eAHIa+O9xssPtofFcQMR8rwBHVbKy484O10tNCouX4yUkyQXqCRy6HRu7kSjOjNKSGtjfG+h5M8bh10W7ZrsJ1hWhzBulSaMZaUY3vh5ngpws1JATQVSK1Jm/dmMRciwlTK7KfzgxHlSX58ENpS7yPTISkEICcLbXkkKGEQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCmj6HgvwOxWz0xu+6fSfRL6PGJUGq6wghCfUvjfwZ7zppDUqU47fk+yqPIOzuGZMdAqi7Nv1DXkeO4A3hnMD22Rlqt25vfogAaZVToBeQxCPd/ALBLFrvLUFYuSlS3zXSBpQqQNy2IKFYsMllz5RSROONHBjaJOn5OwqenJ91MPmTAG7ujXKN6INSBM0PjX9Jy4Xb9zT+I85jRDQHnTFce1WICBDCYidTIvJtdSSokGSuy4/xyxAAc/BpZAfOjBQ4G1QRe9XwOi790LyNUYFJVyeOvNJwveloWuPLHb9idmY5YABwikUY6QNcXwyHTbRCkPB2Im+/R4XnmL4cKQ+5Z-----END CERTIFICATE-----private_key:inline_string: |-----BEGIN PRIVATE KEY-----MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2GdiSpVAFf5aDtpBbIIJvzuEFx7WEAWFtEzxj11BOrGgxdmIDafwbTz2FSi6hCkR0mCK1dVLpgwU8VRRZ/ByrFgDKcsrhfmKbbph9rV47wtryxlRL7gGNqjWAXn9UnFISjbJnt8UGjwzgTjhl6EgihyKkJFL5hl6EWzp2Yeir8wa+HZ4Achr473Gyw+2h8VxAxHyvAEdVsrLjzg7XS00Ki5fjJSTJBeoJHLodG7uRKM6M0pIa2N8b6HkzxuHXRbtmuwnWFaHMG6VJoxlpRje+HmeCnCzUkBNBVIrUmb92YxFyLCVMrsp/ODEeVJfnwQ2lLvI9MhKQQgJwtteSQoYRAgMBAAECggEAeDGdEkYNCGQLe8pvg8Z0ccoSGpeTxpqGrNEKhjfi6NrBNwyVav10iq4FxEmPd3nobzDPkAftfvWc6hKaCT7vyTkPspCMOsQJ39/ixOk+jqFxlNa1YxyoZ9IV2DIHR1iaj2Z5gB367PZUoGTgstrbafbaNY9IOSyojCIO935ubbcxDWwL24XAf51ez6sXnI8V5tXmrFlNXhbhJdH8iIxNyM45HrnlUlOk0lCK4gmLJjy910IS2H2Wh3M5zsTpihH1JvM56oAH1ahrhMXs/rVFXXkg50yD1KV+HQiEbglYKUxOeMYtfaY9i2CuLwhDnWp3oxP3HfgQQhD09OEN3e0IlQKBgQDZ/3poG9TiMZSjfKqLxnCABMXGVQsfFWNC8THoW6RRx5Rqi8q08yJrmhCu32YKvccsOljDQJQQJdQO1g09e/adJmCnTrqxNtjPkX9txV23Lp6Ak7emjiQ5ICu7iWxrcO3zf7hmKtj7z+av8sjOmDI7NkX5vnlE74nztBEjp3eC0wKBgQDV2GeJV028RW3b/QyP3Gwmax2+cKLR9PKRnJnmO5bxAT0nQ3xuJEAqMIss/Rfb/macWc2N/6CWJCRT6a2vgy6xBW+bqG6RdQMBxEZXFZl+sSKhXPkc5Wjb4lQ14YWyRPrTjMlwez3k4UolIJhJmwl+D7OkMRrOUEROEtUvc7odCwKBgBi+nhdZKWXveM7B5N3uzXBKmmRz3MpPdC/yDtcwJ8u8msUpTv4RJxQNrd0bsIqBli0YBmFLYEMg+BwjAee7vXeDFq+HCTv6XMva2RsNryCO4yD3I359XfE6DJzB8ZOUgv4Dvluie3TB2Y6ZQV/p+LGt7G13yG4hvofyJYvlg3RPAoGAcjDg+OH5zLN2eqah8qBN0CYa9/rFt0AJ19+7/smLTJ7QvQq4g0gwS1couplcCEnNGWiK72y1n/ckvvplmPeAE19HveMvR9UoCeV5ej86fACy8V/oVpnaaLBvL2aCMjPLjPP9DWeCIZp8MV86cvOrGfngf6kJG2qZTueXl4NAuwkCgYEArKkhlZVXjwBoVvtHYmN2o+F6cGMlRJTLhNc391WApsgDZfTZSdeJsBsvvzS/Nc0burrufJg0wYioTlpReSy4ohhtprnQQAddfjHP7rh2LGt+irFzhdXXQ1ybGaGM9D764KUNCXLuwdly0vzXU4HUq5sGxGrC1RECGB5Zwx2S2ZY=-----END PRIVATE KEY-----clusters:- name: service1-envoytype: STRICT_DNSlb_policy: ROUND_ROBINload_assignment:cluster_name: service1-envoyendpoints:- lb_endpoints:- endpoint:address:socket_address:address: service-envoy-1port_value: 8000- name: service2-envoytype: STRICT_DNSlb_policy: ROUND_ROBINload_assignment:cluster_name: service2-envoyendpoints:- lb_endpoints:- endpoint:address:socket_address:address: service-envoy-2port_value: 8000
admin:address:socket_address:address: 0.0.0.0port_value: 8001layered_runtime: # 用于设置 Envoy 的运行时参数layers:- name: static_layer_0static_layer: # 静态层,用于设置 Envoy 的运行时参数envoy:resource_limits:listener:example_listener_name:connection_limit: 10000

上面的配置文件我们可以看到 Envoy 中定义了两个 Listener,分别监听 8080 和 8443 端口,分别对应 http 和 https 请求,我们可以看到 8443 这个监听器配置了 TLS 证书,这个证书是自签名的。然后根据路由规则,将匹配路由 /service/1 的请求路由到 service1-envoy 这个集群中,将匹配路由 /service/2 的请求路由到 service2-envoy 这个集群中。

这两个集群分别对应了 service-envoy-1service-envoy-2 这两个后端服务,需要注意的是这里的两个后端服务并不是最终的 aiohttp 应用程序,而是 aiohttp 应用前面的 Service Envoy 代理,这样所有的请求都会先经过 Envoy 代理,然后再路由到最终的 aiohttp 应用程序中。

下面是 service1 这个服务前面的 Envoy 代理的配置文件:

# service-envoy.yaml
static_resources:listeners:- address:socket_address:address: 0.0.0.0port_value: 8000filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagercodec_type: AUTOstat_prefix: service_envoy_1route_config:name: local_routevirtual_hosts:- name: backenddomains:- "*"routes:- match:prefix: "/service/1"route:cluster: service1http_filters:- name: envoy.filters.http.routertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Routerclusters:- name: service1type: STRICT_DNSlb_policy: ROUND_ROBINload_assignment:cluster_name: service1endpoints:- lb_endpoints:- endpoint:address:socket_address:address: service1port_value: 8080
admin:address:socket_address:address: 0.0.0.0port_value: 8001

我们可以看到收到的请求都会被路由到 service1 这个集群中,这个集群对应的是 service1 这个服务,这个服务就是一个 真正的后端 aiohttp 应用程序了,Service Envoy 相当于充当应用程序的 Sidecar,这样所有请求均由 Envoy 处理,然后有效路由到您的服务。

🍀

下面我们路由到 examples/front-proxy 目录,然后使用 Docker Compose 启动这个案例:

这个是要安装docker-compose的。

$ pwd
/Users/cnych/Documents/course/istio/manifests/envoy/examples/front-proxy
$ docker-compose up --build -d
#docker compose up --build -d
$ docker-compose ps
NAME                            IMAGE                         COMMAND                                                           SERVICE           CREATED              STATUS                    PORTS
front-proxy-front-envoy-1       front-proxy-front-envoy       "/docker-entrypoint.sh /usr/local/bin/envoy -c /etc/envoy.yaml"   front-envoy       About a minute ago   Up 35 seconds             0.0.0.0:8001->8001/tcp, :::8001->8001/tcp, 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:8443->8443/tcp, :::8443->8443/tcp, 10000/tcp
front-proxy-service-envoy-1-1   front-proxy-service-envoy-1   "/docker-entrypoint.sh /usr/local/bin/envoy -c /etc/envoy.yaml"   service-envoy-1   About a minute ago   Up 37 seconds (healthy)   10000/tcp
front-proxy-service-envoy-2-1   front-proxy-service-envoy-2   "/docker-entrypoint.sh /usr/local/bin/envoy -c /etc/envoy.yaml"   service-envoy-2   About a minute ago   Up 37 seconds (healthy)   10000/tcp
front-proxy-service1-1          front-proxy-service1          "python3 /code/service.py"                                        service1          About a minute ago   Up 38 seconds (healthy)
front-proxy-service2-1          front-proxy-service2          "python3 /code/service.py"                                        service2          About a minute ago   Up 38 seconds (healthy)

在使用docker-compose启动的时候报错了:。。。

汇总踩坑如下:

1.要升级docker-compse版本新一点
2.要手动拉取2个镜像才行

⚠️ 注意:

安装docker compose出问题了。。。

老师当时测试都是没问题的。

  • 报错现象

image-20231102220259226

  • 当前环境(自己之前的docker-compse版本是v1.26.2)
[root@docker front-proxy]#docker-compose --version
docker-compose version 1.26.2, build eefe0d31docker-ce 20.10.21

image-20231104061627564

  • 奇怪,不知道是哪里出了问题。。。–> 感觉还是自己的docker compose有点问题。。。,可能自己docker compose版本太低了。。。

image-20231102220514084

  • 安装了新版本,还是不行。。。
[root@docker front-proxy]#docker-compose --version
Docker Compose version v2.23.0
  • 提问

image-20231104061714263

  • 自己再次测试

image-20231104061312821

这次就可以了,估计还是和自己的docker-compose版本有关。

  • 拉取报错了:。。。

第一次拉取失败:。。。

image-20231104062011684

第2次拉取失败:。。。

image-20231104062031410

估计还是自己linux虚机无法访问外网导致的。。。

  • 自己pc是可以科学上网的的。

image-20231104062201769

image-20231104062320880

image-20231104062423609

export https_proxy=http://127.0.0.1:33210 http_proxy=http://127.0.0.1:33210 all_proxy=socks5://127.0.0.1:33211

  • 在linux虚机里配置了终端代理后,再次测试看下现象

image-20231104062502684

image-20231104062700799

不行呀。。。。

  • 这个镜像有问题。。。
[service2 python-base 1/3] FROM docker.io/library/python:3.11.5-slim-bullseye@sha256:9f35f3a6420693c209c11bba63dcf103d88e47ebe0b205336b5168c122967edf 

可以单独拉取成功的:

image-20231104063048386

哦,这边可以正常下载了。。。

image-20231104063216230

image-20231104063527921

  • 重启了机器后,再次测试。。。

怎么还一直卡在这里呀。。。。

image-20231104064145494

image-20231104064309689

  • 再次拉取镜像:

image-20231104064530391

  • 终于拉启动好了:

image-20231104064641654


🍀

执行命令后会启动 5 个容器,其中 3 个是 Envoy 代理,2 个是 aiohttp 应用程序:

img

image-20231104065051832

🍀

启动完成后,我们现在可以通过前端代理向两个服务发送请求来测试 Envoy 的路由功能了,我们可以使用 curl 命令来测试:

service1

[root@docker front-proxy]#curl -v localhost:8080/service/1
* About to connect() to localhost port 8080 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /service/1 HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 200 OK
< content-type: text/plain; charset=utf-8
< content-length: 79
< date: Fri, 03 Nov 2023 22:51:21 GMT
< server: envoy
< x-envoy-upstream-service-time: 4
< 
Hello from behind Envoy (service 1)! hostname 221f01bef482 resolved 172.19.0.3
* Connection #0 to host localhost left intact

service2

[root@docker front-proxy]#curl -v localhost:8080/service/2
* About to connect() to localhost port 8080 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /service/2 HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 200 OK
< content-type: text/plain; charset=utf-8
< content-length: 79
< date: Fri, 03 Nov 2023 22:51:41 GMT
< server: envoy
< x-envoy-upstream-service-time: 4
< 
Hello from behind Envoy (service 2)! hostname eb0e9d483971 resolved 172.19.0.2
* Connection #0 to host localhost left intact

可以看到每个请求我们都是直接发送到 Front Envoy,然后 Front Envoy 再根据路由规则将请求路由到对应的 Service Envoy,然后再路由到最终的 aiohttp 应用程序中的。

🍀

此外还可以使用 HTTPS 来调用 Envoy 后面的服务,例如调用 service1:

[root@docker front-proxy]#curl https://localhost:8443/service/1 -k -v
* About to connect() to localhost port 8443 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 8443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* 	subject: CN=front-envoy
* 	start date: 7月 08 01:31:46 2020 GMT
* 	expire date: 7月 06 01:31:46 2030 GMT
* 	common name: front-envoy
* 	issuer: CN=front-envoy
> GET /service/1 HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8443
> Accept: */*
> 
< HTTP/1.1 200 OK
< content-type: text/plain; charset=utf-8
< content-length: 79
< date: Fri, 03 Nov 2023 22:52:35 GMT
< server: envoy
< x-envoy-upstream-service-time: 3
< 
Hello from behind Envoy (service 1)! hostname 221f01bef482 resolved 172.19.0.3
* Connection #0 to host localhost left intact

🍀

接下来我们还可以继续测试 Envoy 的负载均衡功能,我们可以将 service1 服务扩展到 3 个实例:

[root@docker front-proxy]#docker-compose scale service1=3
[+] Running 3/3✔ Container front-proxy-service1-1  Running                                                                                                                                   0.0s ✔ Container front-proxy-service1-3  Started                                                                                                                                   0.0s ✔ Container front-proxy-service1-2  Started                                                                                                                                   0.0s 

🍀

然后我们多次向 service1 发送请求,前端 Envoy 将通过对三台 service1 机器进行轮询来对请求进行负载平衡:

[root@docker front-proxy]#curl localhost:8080/service/1
Hello from behind Envoy (service 1)! hostname 221f01bef482 resolved 172.19.0.3
[root@docker front-proxy]#curl localhost:8080/service/1
Hello from behind Envoy (service 1)! hostname 221f01bef482 resolved 172.19.0.3
[root@docker front-proxy]#curl localhost:8080/service/1
Hello from behind Envoy (service 1)! hostname 4f39d0e0afc7 resolved 172.19.0.7
[root@docker front-proxy]#curl localhost:8080/service/1
Hello from behind Envoy (service 1)! hostname f6699d0a5de9 resolved 172.19.0.8
[root@docker front-proxy]#curl localhost:8080/service/1
Hello from behind Envoy (service 1)! hostname 4f39d0e0afc7 resolved 172.19.0.7
[root@docker front-proxy]#curl localhost:8080/service/1
Hello from behind Envoy (service 1)! hostname f6699d0a5de9 resolved 172.19.0.8
[root@docker front-proxy]#curl localhost:8080/service/1
Hello from behind Envoy (service 1)! hostname 221f01bef482 resolved 172.19.0.3

🍀

测试完成后可以执行 docker-compose down 命令来停止所有容器。

[root@docker front-proxy]#docker-compose down
[+] Running 8/8✔ Container front-proxy-front-envoy-1      Removed                                                                                                                            0.2s ✔ Container front-proxy-service-envoy-2-1  Removed                                                                                                                            0.2s ✔ Container front-proxy-service-envoy-1-1  Removed                                                                                                                            0.2s ✔ Container front-proxy-service2-1         Removed                                                                                                                            0.3s ✔ Container front-proxy-service1-1         Removed                                                                                                                            0.4s ✔ Container front-proxy-service1-3         Removed                                                                                                                            0.4s ✔ Container front-proxy-service1-2         Removed                                                                                                                            0.3s ✔ Network front-proxy_default              Removed                                                                                                                            0.1s 
[root@docker front-proxy]#docker-compose ps
NAME      IMAGE     COMMAND   SERVICE   CREATED   STATUS    PORTS
[root@docker front-proxy]#docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

测试结束。😘

3、流量镜像

这里说的集群都是envoy集群。

流量镜像功能允许您将流量复制到另一个集群,而不会影响主要流量。这对于测试新版本的服务或将流量发送到另一个集群以进行分析非常有用。

🚩 实战:流量镜像-2023.11.4(测试成功)

实验环境:

Docker Compose version v2.23.0
docker 20.10.21-ce(具有docker环境)

实验软件:

链接:https://pan.baidu.com/s/1RB2YMVeNDkX18YFQQ1suZg?pwd=0820
提取码:0820
2023.11.4-Day4-2023.10.30-Envoy使用案例

image-20231104065901821

实验步骤:

graph LRA[实战步骤] -->B(1️⃣ 拉取测试demo)A[实战步骤] -->C(2️⃣ 熟悉demo)A[实战步骤] -->D(3️⃣ 启动服务)A[实战步骤] -->E(4️⃣ 测试流量镜像功能)

🍀

image-20231103062452126

这里的演示应用一共包含 5 个容器,对应的 docker-compose.yml 文件内容如下所示:

services:envoy-front-proxy:build:context: .dockerfile: ../shared/envoy/Dockerfileports:- "${PORT_PROXY:-10000}:10000"depends_on:service1:condition: service_healthyservice1-mirror:condition: service_healthyservice2:condition: service_healthyservice2-mirror:condition: service_healthyservice1:build:context: ../shared/pythontarget: aiohttp-tracing-serviceenvironment:- SERVICE_NAME=1service1-mirror:build:context: ../shared/pythontarget: aiohttp-tracing-serviceenvironment:- SERVICE_NAME=1service2:build:context: ../shared/pythontarget: aiohttp-tracing-serviceenvironment:- SERVICE_NAME=2service2-mirror:build:context: ../shared/pythontarget: aiohttp-tracing-serviceenvironment:- SERVICE_NAME=2

🍀

输入请求由 envoy-front-proxy 服务接收,路径为 /service/1 的请求被静态复制。每个请求由 service1 集群处理,并且额外转发到 service1-mirror 集群:

img

对于路径 /service/2 的请求将根据 x-mirror-cluster 标头的存在和值进行动态镜像。此路径的所有请求都会转发到 service2 集群,并且还会镜像到标头中指定的集群。

例如,如果我们发送带有头信息 x-mirror-cluster: service2-mirror 的请求,则该请求将被镜像转发到 service2-mirror 集群。

另外需要注意 Envoy 只会将从主集群接收到的响应返回给客户端。比如我们这里来自 service1service2 集群的响应将会发送给客户端。而来自 service1-mirrorservice2-mirror 集群的响应则不会被发送回客户端。这也意味着在镜像集群中请求处理过程中的任何问题或延迟都不会影响客户端接收到的响应。

🍀

现在切换到 examples/route-mirror 目录,然后启动应用:

# examples/route-mirror 路径
$ docker-compose up --build -d
$ docker compose ps
NAME                               IMAGE                            COMMAND                                                           SERVICE             CREATED         STATUS                   PORTS
route-mirror-envoy-front-proxy-1   route-mirror-envoy-front-proxy   "/docker-entrypoint.sh /usr/local/bin/envoy -c /etc/envoy.yaml"   envoy-front-proxy   6 seconds ago   Up 4 seconds             0.0.0.0:10000->10000/tcp, :::10000->10000/tcp
route-mirror-service1-1            route-mirror-service1            "python3 /code/service.py"                                        service1            6 seconds ago   Up 5 seconds (healthy)
route-mirror-service1-mirror-1     route-mirror-service1-mirror     "python3 /code/service.py"                                        service1-mirror     6 seconds ago   Up 5 seconds (healthy)
route-mirror-service2-1            route-mirror-service2            "python3 /code/service.py"                                        service2            6 seconds ago   Up 5 seconds (healthy)
route-mirror-service2-mirror-1     route-mirror-service2-mirror     "python3 /code/service.py"                                        service2-mirror     6 seconds ago   Up 5 seconds (healthy)

image-20231104075828305

🍀

现在让我们向 envoy-front-proxy 服务发送一个请求,该服务将请求转发到 service1,并将请求镜像发送到服 service1-mirror

$ curl localhost:10000/service/1
Hello from behind Envoy (service 1)!

然后我们可以分别查看 service1service1-mirror 服务的日志:

$ docker-compose logs service1
$ docker-compose logs service1-mirror或者:
docker logs -f route-mirror-service1-1
docker logs -f route-mirror-service1-mirror-1

正常情况下这两个服务都将接收到请求。
img

而且对于对 service1-mirror 服务的请求,Envoy 将 Host 头信息修改为在主机名中添加了 -shadow后缀。

image-20231104080236953

image-20231104080146595

🍀

如果在对 service2 的请求中没有指定 x-mirror-cluster,或者指定未知的集群,则该请求将不会被镜像,而是会以正常方式处理。

$ curl localhost:10000/service/2
Hello from behind Envoy (service 2)!
$ curl --header "x-mirror-cluster: service2-mirror-non-existent" localhost:10000/service/2
Hello from behind Envoy (service 2)!

我们可以查看日志来验证结果:

$ docker compose logs service2
route-mirror-service2-1  | DEBUG:asyncio:Using selector: EpollSelector
route-mirror-service2-1  | ======== Running on http://0.0.0.0:8080 ========
route-mirror-service2-1  | (Press CTRL+C to quit)
route-mirror-service2-1  | Host: localhost:10000
route-mirror-service2-1  | INFO:aiohttp.access:192.168.227.6 [30/Oct/2023:09:21:03 +0000] "GET /service/2 HTTP/1.1" 200 189 "-" "curl/7.87.0"
route-mirror-service2-1  | Host: localhost:10000
route-mirror-service2-1  | INFO:aiohttp.access:192.168.227.6 [30/Oct/2023:09:23:06 +0000] "GET /service/2 HTTP/1.1" 200 189 "-" "curl/7.87.0"
route-mirror-service2-1  | Host: localhost:10000
route-mirror-service2-1  | INFO:aiohttp.access:192.168.227.6 [30/Oct/2023:09:23:11 +0000] "GET /service/2 HTTP/1.1" 200 189 "-" "curl/7.87.0"
$ docker compose logs service2-mirror
route-mirror-service2-mirror-1  | DEBUG:asyncio:Using selector: EpollSelector
route-mirror-service2-mirror-1  | ======== Running on http://0.0.0.0:8080 ========
route-mirror-service2-mirror-1  | (Press CTRL+C to quit)
route-mirror-service2-mirror-1  | Host: localhost-shadow:10000
route-mirror-service2-mirror-1  | INFO:aiohttp.access:192.168.227.6 [30/Oct/2023:09:21:03 +0000] "GET /service/2 HTTP/1.1" 200 189 "-" "curl/7.87.0"

可以看到 service2 中有对应的请求日志,但是 service2-mirror 中并没有。

image-20231104080609998

🍀

接下来我们再发送一个请求,这次我们将请求发送到 service2 服务,但是我们在请求头中添加了 x-mirror-cluster: service2-mirror 这个头信息,这样 Envoy 将会将请求镜像到 service2-mirror 集群:

$ curl --header "x-mirror-cluster: service2-mirror" localhost:10000/service/2
Hello from behind Envoy (service 2)!

请求后查看这两个服务的日志来验证请求是否已被镜像:

img

同样的对于对 service2-mirror 服务的请求,Envoy 将 Host 头信息修改为在主机名中添加了 -shadow后缀。

image-20231104080646911

🍀

停掉测试容器:

[root@docker route-mirror]#docker-compose down
[+] Running 6/5? Container route-mirror-envoy-front-proxy-1  Removed                                                                                                                                                       0.1s ? Container route-mirror-service2-1           Removed                                                                                                                                                       0.3s ? Container route-mirror-service2-mirror-1    Removed                                                                                                                                                       0.3s ? Container route-mirror-service1-1           Removed                                                                                                                                                       0.2s ? Container route-mirror-service1-mirror-1    Removed                                                                                                                                                       0.3s ? Network route-mirror_default                Removed                                                                                                                                                       0.0s 

测试完成。😘

4、故障注入过滤器

🚩 实战:故障注入过滤器-2023.11.4(测试成功)

实验环境:

Docker Compose version v2.23.0
docker 20.10.21-ce(具有docker环境)

实验软件:

链接:https://pan.baidu.com/s/1RB2YMVeNDkX18YFQQ1suZg?pwd=0820
提取码:0820
2023.11.4-Day4-2023.10.30-Envoy使用案例

image-20231104065901821

实验步骤:

graph LRA[实战步骤] -->B(1️⃣ 拉取测试demo)A[实战步骤] -->C(2️⃣ 熟悉demo)A[实战步骤] -->D(3️⃣ 启动服务)A[实战步骤] -->E(4️⃣ 故障注入过滤器)

这里我们可以使用 Envoy 的故障注入过滤器来模拟故障,例如模请求中止、失败以及延迟响应等,这样我们就可以测试服务的容错能力了。该功能主要利用 Envoy 的运行时支持来控制故障注入的能力。

image-20231104081217135

🍀

image-20231104081456653

这里我们的入口 Envoy 的配置如下所示:

# envoy.yaml
static_resources:listeners:- address:socket_address:address: 0.0.0.0port_value: 9211filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagercodec_type: AUTOstat_prefix: ingress_httpaccess_log:- name: envoy.access_loggers.stdouttyped_config:"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLogroute_config:name: local_routevirtual_hosts:- name: servicedomains:- "*"routes:- match:prefix: /route:cluster: local_servicehttp_filters:- name: envoy.filters.http.faulttyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFaultabort:http_status: 503percentage:numerator: 0denominator: HUNDREDdelay:fixed_delay: 3spercentage:numerator: 0denominator: HUNDRED- name: envoy.filters.http.routertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Routerclusters:- name: local_servicetype: STRICT_DNSlb_policy: ROUND_ROBINload_assignment:cluster_name: local_serviceendpoints:- lb_endpoints:- endpoint:address:socket_address:address: backendport_value: 80
layered_runtime:layers:- name: disk_layer_0disk_layer:symlink_root: /srv/runtime/currentsubdirectory: envoy

上面的配置文件中我们使用了一个 layered_runtime 属性,这个属性用于运行时配置提供程序的配置,这里我们使用了 disk_layer,这个参数用于设置 Envoy 的运行时参数存储在哪个目录下,这里我们设置为 /srv/runtime/current,子目录为 envoy,然后就可以这这个目录下面创建配置文件。

注意下环境:

image-20231104082049265

image-20231104082106856

奇怪:(没关系的,不影响测试效果。)

image-20231104081842398

image-20231104081921649

为了实现故障注入功能,我们这里需要添加一个 envoy.filters.http.fault 的过滤器,这个过滤器用于实现故障注入功能,我们可以通过 typed_config 属性来配置故障注入的功能,这里我们配置了 abortdelay 两个功能,abort 用于模拟请求中止,delay 用于模拟延迟响应,这两个参数至少需要配置一个。

- name: envoy.filters.http.faulttyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFaultabort:http_status: 503percentage:numerator: 0denominator: HUNDREDdelay:fixed_delay: 3spercentage:numerator: 0 # 分子denominator: HUNDRED # 分母
  • delay:如果指定了此参数,该过滤器将根据对象中的值注入延迟。

    • fixed_delay:在向上游转发操作之前添加固定延迟,对于 HTTP / Mongo,指定的延迟将在发出新请求/操作之前注入。
    • header_delay:故障延迟通过一个 HTTP 头部来控制(如果适用)。
    • percentage:注入延迟的操作/连接/请求的百分比。
  • abort:如果指定,过滤器将根据对象中的值中止请求。

    • http_status:用于中止 HTTP 请求的 HTTP 状态码。
    • grpc_status:用于中止 gRPC 请求的 gRPC 状态码。
    • header_abort:故障中止通过一个 HTTP 头部来控制(如果适用)。
    • percentage:注入中止的操作/连接/请求的百分比。

另外需要注意如果存在以下运行时配置值,则故障过滤器的值会被覆盖。

  • fault.http.abort.abort_percent
  • fault.http.abort.http_status
  • fault.http.delay.fixed_delay_percent
  • fault.http.delay.fixed_duration_ms

我们这里就是通过 disk_layer 方式来配置运行时参数的,我们可以在 所以我们需要在 /srv/runtime/current/envoy 目录下添加配置来控制故障注入的功能。

🍀

下面我们来测试下故障注入的功能,我们路由到 examples/fault-injection 目录,然后使用 Docker Compose 启动这个案例:

$ pwd
/Users/cnych/Documents/course/istio/manifests/envoy/examples/fault-injection
$ docker-compose up --build -d
$ docker-compose ps
NAME                        IMAGE                     COMMAND                                                           SERVICE   CREATED         STATUS         PORTS
fault-injection-backend-1   fault-injection-backend   "gunicorn -b 0.0.0.0:80 httpbin:app -k gevent"                    backend   9 seconds ago   Up 7 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp
fault-injection-envoy-1     fault-injection-envoy     "/docker-entrypoint.sh /usr/local/bin/envoy -c /etc/envoy.yaml"   envoy     9 seconds ago   Up 7 seconds   0.0.0.0:9211->9211/tcp, :::9211->9211/tcp, 10000/tcp

image-20231104084031868

🍀

启动后我们开始发送连续的 HTTP 请求,重新开一个终端窗口,然后执行下面的命令:

# examples/fault-injection 目录下
$ docker-compose exec envoy bash
bash send_request.sh

这里的 send_request.sh 脚本我们将会向 Envoy 一直发送 HTTP 请求,Envoy 将请求转发到后端容器,直到我们手动停止脚本,脚本内容如下所示:

#!/usr/bin/env bash
set -exwhile :; docurl -v localhost:9211/status/200sleep 1
done

image-20231104084145800

🍀

虽然我们已经在 Envoy 中配置了故障注入功能,但是现在我们还没有启用它,但是目前的配置的分子都为 0,所以我们的请求都是正常的,我们可以看到请求的状态码都是 200

下面我们再开一个新的终端,通过以下命令,在运行时打开中断故障注入。

# examples/fault-injection 目录下
$ docker compose exec envoy bash
$ bash enable_abort_fault_injection.sh

这里执行的 enable_abort_fault_injection.sh 脚本可以对 100%的请求进行 HTTP 中止,对应的内容如下所示:

#!/usr/bin/env bash
set -exmkdir -p /srv/runtime/v1/envoy/fault/http/abort
echo '100' > /srv/runtime/v1/envoy/fault/http/abort/abort_percent
echo '503' > /srv/runtime/v1/envoy/fault/http/abort/http_statuspushd /srv/runtime
ln -s /srv/runtime/v1 new && mv -Tf new current
popd

当我们执行了该脚本后前面一直发送的请求就会出现中断的情况,我们可以看到请求的状态码都是 503

在容器里执行。

image-20231104083620313

img

image-20231104084526671

这是因为我们在 Envoy 中配置了故障注入功能,然后通过运行时配置将故障注入功能打开了,配置 abort_percent 为 100%,这样所有请求都会被中断了。

可以再次执行 disable_abort_fault_injection.sh 脚本来关闭中断功能。

bash disable_abort_fault_injection.sh

该脚本实现也非常简单,只需要将上面的运行时配置文件删除即可,脚本内容如下所示:

#!/usr/bin/env bash
set -exrm /srv/runtime/v1/envoy/fault/http/abort/abort_percent
rm /srv/runtime/v1/envoy/fault/http/abort/http_statuspushd /srv/runtime
ln -s /srv/runtime/v1 new && mv -Tf new current
popd

正常现在我们的请求就恢复正常的响应了。

image-20231104084547673

🍀

用同样的方式我们还可以通过一下命令通过运行时打开延迟故障注入。

# examples/fault-injection 目录下
$ docker compose exec envoy bash
$ bash enable_delay_fault_injection.sh

这里的 enable_delay_fault_injection.sh 脚本和前面一样,只是将 abort 改为了 delay,将 fixed_delay_percent 设置为 50,fixed_duration_ms 设置为 3000,表示 50% 的请求会被延迟 3 秒钟,脚本内容如下所示:

#!/usr/bin/env bash
set -exmkdir -p /srv/runtime/v1/envoy/fault/http/delay
echo '50' > /srv/runtime/v1/envoy/fault/http/delay/fixed_delay_percent
echo '3000' > /srv/runtime/v1/envoy/fault/http/delay/fixed_duration_mspushd /srv/runtime
ln -s /srv/runtime/v1 new && mv -Tf new current
popd

上面脚本执行后,可以看到所有请求的响应码都为 200,但是其中一半的请求将需要 3 秒钟才能完成。

img

同样要关闭延迟故障注入功能,只需要执行 disable_delay_fault_injection.sh 脚本即可

bash disable_delay_fault_injection.sh

🍀

最后我们可以通过查看当前运行时文件系统来了解当前的运行时配置。

$ tree /srv/runtime
/srv/runtime
|-- current -> /srv/runtime/v1
`-- v1`-- envoy`-- fault`-- http|-- abort`-- delay7 directories, 0 files

到这里我们就验证了 Envoy 的故障注入功能。

🍀

终止docker-compose:

[root@docker fault-injection]#docker-compose down
[+] Running 3/2? Container fault-injection-backend-1  Removed                                                                                                                                                              0.9s ? Container fault-injection-envoy-1    Removed                                                                                                                                                              0.1s ? Network fault-injection_default      Removed                                                                                                                                                              0.0s 

测试完成。😘

5、MySQL 过滤器

🚩 实战:MySQL 过滤器-2023.11.4(测试成功)

实验环境:

Docker Compose version v2.23.0
docker 20.10.21-ce(具有docker环境)

实验软件:

链接:https://pan.baidu.com/s/1RB2YMVeNDkX18YFQQ1suZg?pwd=0820
提取码:0820
2023.11.4-Day4-2023.10.30-Envoy使用案例

image-20231104065901821

实验步骤:

graph LRA[实战步骤] -->B(1️⃣ 拉取测试demo)A[实战步骤] -->C(2️⃣ 熟悉demo)A[实战步骤] -->D(3️⃣ 启动服务)A[实战步骤] -->E(4️⃣ MySQL 过滤器)

这里我们将来展示如何在 Envoy 代理中使用 MySQL 过滤器。Envoy 代理配置包括一个 MySQL 过滤器,用于解析查询并收集 MySQL 特定的指标

🍀

首先切换到 examples/mysql 目录下面,然后启动服务:

image-20231104084948854

# examples/mysql 目录
$ docker-compose up --build -d
$ docker-compose ps
NAME            IMAGE         COMMAND                                                           SERVICE   CREATED          STATUS          PORTS
mysql-mysql-1   mysql-mysql   "docker-entrypoint.sh mysqld"                                     mysql     14 seconds ago   Up 13 seconds   3306/tcp, 33060/tcp
mysql-proxy-1   mysql-proxy   "/docker-entrypoint.sh /usr/local/bin/envoy -c /etc/envoy.yaml"   proxy     14 seconds ago   Up 13 seconds   0.0.0.0:8001->8001/tcp, :::8001->8001/tcp, 10000/tcp

记得要手动拉取2个镜像才行:

docker pull docker.io/library/mysql:8.2.0@sha256:1773f3c7aa9522f0014d0ad2bbdaf597ea3b1643c64c8ccc2123c64afd8b82b1
docker pull docker.io/envoyproxy/envoy:contrib-dev

image-20231104095419918

这个应用中我们通过 Envoy 来代理 MySQL 的请求,然后我们可以通过 mysql 客户端来连接 Envoy 代理,然后执行一些命令,这些命令将会被 Envoy 代理转发到后端的 MySQL 服务。对应的 Envoy 配置如下所示:

static_resources:listeners:- name: mysql_listeneraddress:socket_address:address: 0.0.0.0port_value: 1999filter_chains:- filters:- name: envoy.filters.network.mysql_proxytyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.mysql_proxy.v3.MySQLProxystat_prefix: egress_mysql- name: envoy.filters.network.tcp_proxytyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxystat_prefix: mysql_tcpcluster: mysql_clusterclusters:- name: mysql_clustertype: STRICT_DNSload_assignment:cluster_name: mysql_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: mysqlport_value: 3306admin:address:socket_address:address: 0.0.0.0port_value: 8001

由于 MySQL 服务是 TCP 协议了,所有我们现在配置的是全新的过滤器链,这里我们使用的是 envoy.filters.network.mysql_proxy 以及 envoy.filters.network.tcp_proxy 两个过滤器。

MySQL 代理过滤器解码 MySQL 客户端和服务器之间的网络协议。它解码载荷中的 SQL 查询,解码的信息被发出作为动态元数据,可以与访问日志过滤器结合使用,以获取有关访问表以及对每个表执行的操作的详细信息。它是一个透明的过滤器,所以不会影响客户端和服务器的正常进度。此外 MySQL 代理过滤器应与 TCP 代理过滤器链接在一起。

上面的配置就是通过 Envoy 的 1999 端口来接收 MySQL 的代理请求,然后转发给 mysql_cluster 集群下面配置的 mysql 后端服务。

🍀

下面我们来验证下 MySQL 代理过滤器的功能,我们可以通过 mysql 客户端来连接 Envoy 代理:

$ docker run --rm -it --platform=linux/amd64 --network mysql_default mysql:5.7 mysql -h proxy -P 1999 -u root --skip-ssl
# ......
mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.00 sec)mysql> USE test;
Database changed
mysql> CREATE TABLE test ( text VARCHAR(255) );
Query OK, 0 rows affected (0.01 sec)mysql> SELECT COUNT(*) FROM test;
+----------+
| COUNT(*) |
+----------+
|        0 |
+----------+
1 row in set (0.01 sec)mysql> INSERT INTO test VALUES ('hello, world!');
Query OK, 1 row affected (0.00 sec)mysql> SELECT COUNT(*) FROM test;
+----------+
| COUNT(*) |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)mysql> exit
Bye

🍀

然后我们可以检查下流量出口的数据统计:

$ curl -s "http://localhost:8001/stats?filter=egress_mysql"
mysql.egress_mysql.auth_switch_request: 1
mysql.egress_mysql.decoder_errors: 0
mysql.egress_mysql.login_attempts: 1
mysql.egress_mysql.login_failures: 0
mysql.egress_mysql.protocol_errors: 0
mysql.egress_mysql.queries_parse_error: 2
mysql.egress_mysql.queries_parsed: 7
mysql.egress_mysql.sessions: 1
mysql.egress_mysql.upgraded_to_ssl: 0

🍀

可以看到已经有相关的数据了。同样还可以查看下入口的 TCP 的统计数据:

curl -s "http://localhost:8001/stats?filter=mysql_tcp"
tcp.mysql_tcp.downstream_cx_no_route: 0
tcp.mysql_tcp.downstream_cx_rx_bytes_buffered: 0
tcp.mysql_tcp.downstream_cx_rx_bytes_total: 451
tcp.mysql_tcp.downstream_cx_total: 1
tcp.mysql_tcp.downstream_cx_tx_bytes_buffered: 0
tcp.mysql_tcp.downstream_cx_tx_bytes_total: 679
tcp.mysql_tcp.downstream_flow_control_paused_reading_total: 0
tcp.mysql_tcp.downstream_flow_control_resumed_reading_total: 0
tcp.mysql_tcp.idle_timeout: 0
tcp.mysql_tcp.max_downstream_connection_duration: 0
tcp.mysql_tcp.upstream_flush_active: 0
tcp.mysql_tcp.upstream_flush_total: 0

这样我们就实现了通过 Envoy 来代理 MySQL 的请求。

🍀

停止docker-comose:

[root@docker mysql]#docker-compose down
[+] Running 3/2✔ Container mysql-proxy-1  Removed                                                                                                                                                                          0.1s ✔ Container mysql-mysql-1  Removed                                                                                                                                                                          1.2s ✔ Network mysql_default    Removed                                                                                                                                                                          0.0s 

测试结束。😘

6、Golang HTTP 过滤器

🚩 实战:Golang HTTP 过滤器-2023.11.4(测试成功)

实验环境:

Docker Compose version v2.23.0
docker 20.10.21-ce(具有docker环境)

实验软件:

链接:https://pan.baidu.com/s/1RB2YMVeNDkX18YFQQ1suZg?pwd=0820
提取码:0820
2023.11.4-Day4-2023.10.30-Envoy使用案例

image-20231104065901821

实验步骤:

graph LRA[实战步骤] -->B(1️⃣ 拉取测试demo)A[实战步骤] -->C(2️⃣ 熟悉demo)A[实战步骤] -->D(3️⃣ 启动服务)A[实战步骤] -->E(4️⃣ Golang HTTP 过滤器)

HTTP Golang 过滤器允许在请求和响应流期间运行 Golang,并简化了对 Envoy 的扩展。这个过滤器使用的 Go 插件可以独立于 Envoy 重新编译,这使得在不重新编译 Envoy 的情况下更新插件变得容易。

另外需要注意 Envoy 的 Go 插件必须实现 StreamFilter API。构建 Go 插件动态库时,必须使用与 Envoy 的 glibc 版本一致的 Go 版本。

下面我们就来演示下如何使用 Golang HTTP 过滤器,这里的示例将展示一个 Go 插件,它可以直接响应请求,并且还可以更新上游服务器提供的响应。

🍀

同样定位到 examples/golang-http 目录,首先构建 go 插件库:

image-20231104101539685

# examples/golang-http 目录
$ docker-compose -f docker-compose-go.yaml run --rm go_plugin_compile

image-20231104102031599

docker pull docker.io/library/golang:1.21.3-bullseye@sha256:26c7537d6ac3827eb4638034d16edc64de57bb011c8cc8fe301ac13a6568f6f4

⚠️ 注意:

记得配置这个参数,否则可能下载不了go包:

image-20231104101838899

image-20231104101705741

编译后的库文件会出现在 lib 文件夹中。

$ ls lib
simple.so

image-20231104102948308

🍀

然后接下来可以直接启动我们的服务:

$ docker-compose up --build -d
$ docker-compose ps
NAME                               COMMAND                  SERVICE              STATUS              PORTS
golang-http-helloworld_service-1   "python3 /code/servi…"   helloworld_service   running (healthy)
golang-http-proxy-1                "/docker-entrypoint.…"   proxy                running             0.0.0.0:10000->10000/tcp, :::10000->10000/tcp

这里我们同样要重点了解下 Envoy 代理的配置文件:

static_resources:listeners:- name: listener_0address:socket_address:address: 0.0.0.0port_value: 10000filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: ingress_httphttp_filters:- name: envoy.filters.http.golangtyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Configlibrary_id: simplelibrary_path: "lib/simple.so"plugin_name: simpleplugin_config:"@type": type.googleapis.com/xds.type.v3.TypedStructvalue:prefix_localreply_body: "Configured local reply from go"- name: envoy.filters.http.routertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Routerroute_config:name: local_routevirtual_hosts:- name: local_servicedomains: ["*"]routes:- match:prefix: "/"route:cluster: helloworld_service_clusterclusters:- name: helloworld_service_clustertype: STRICT_DNSlb_policy: ROUND_ROBINload_assignment:cluster_name: helloworld_service_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: helloworld_serviceport_value: 8080

整体上和之前的配置文件差不多,会将所有的请求都转发到后端的 helloworld_service 服务,但是这里我们在 http_filters 中还添加了一个 envoy.filters.http.golang 过滤器,这个过滤器就是我们编译的 go 插件,这个过滤器的配置如下所示:

- name: envoy.filters.http.golangtyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Configlibrary_id: simplelibrary_path: "lib/simple.so"plugin_name: simpleplugin_config:"@type": type.googleapis.com/xds.type.v3.TypedStructvalue:prefix_localreply_body: "Configured local reply from go"

这里我们配置了 go 插件的路径,然后还配置了 plugin_config,这个配置会传递给 go 插件,这里我们配置了 prefix_localreply_body,这个配置会在 go 插件中使用,我们可以在 go 插件中获取到这个配置,然后将其添加到响应体中。

🍀

下面我们可以使用 curl 命令来测试下 go 插件的功能:

curl -v localhost:10000 2>&1

img

正常我们可以看到由 Go 插件添加的 rsp-header-from-go: bar-test 这个 Header 头信息。

🍀

然后我们再发出一个由上游处理并由 Go 插件更新的请求:

$ curl localhost:10000/update_upstream_response 2>&1
upstream response body updated by the simple plugin%

该请求的响应结果是由 Go 插件更新的。

🍀

最后我们使用自定义配置进行处理的 Go 插件进行请求。

$ curl localhost:10000/localreply_by_config  2>&1
Configured local reply from go, path: /localreply_by_config

得到的结果是由 Go 插件提供的包含 prefix_localreply_body 值的 body。

img

当然这些都是我们在插件里面去实现的,具体要实现什么样的功能完全取决于我们自己。

测试结束。😘

总结

我们这里只是挑选了几个过滤器来进行演示,实际上 Envoy 还有很多其他的过滤器,这里就不一一介绍了,如果想了解更多的过滤器可以参考 Envoy 官方文档 了解更多使用方式。

最重要的是我们要了解 Envoy 的过滤器的工作原理,了解 Envoy 的配置流程,这样我们才能更好的使用 Envoy。

关于我

我的博客主旨:

  • 排版美观,语言精炼;
  • 文档即手册,步骤明细,拒绝埋坑,提供源码;
  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码
x2675263825 (舍得), qq:2675263825。

image-20230107215114763

🍀 微信公众号
《云原生架构师实战》

image-20230107215126971

🍀 个人博客站点

http://onedayxyy.cn/

image-20231021104335916

image-20231021104405837

🍀 语雀

https://www.yuque.com/xyy-onlyone

image-20231030124453217

🍀 csdn

https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

image-20230107215149885

🍀 知乎

https://www.zhihu.com/people/foryouone

image-20230107215203185

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

image-20231104104454932

这篇关于2023.11.4-Envoy使用案例-oss的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/345372

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]