envoy初识

一、Envoy 核心组件介绍

Envoy 是一个开源的边缘和服务代理,设计用于单体服务和微服务架构中的通信优化。本文将介绍 Envoy 的四个核心组件:监听器、过滤器、路由和集群。

个人理解:
公司的微服务使用到了envoy,之前没有用过这个产品,最开始以为和nginx类似,稍微了解以后感觉要比nginx复杂很多,并且实现的功能也不太一样。nginx主要作用是南北流量,envoy更多实现的是东西流量。网络中的南北就是服务器和用户,东西就是服务器和服务器之间,这个名词还是有必要了解的。

envoy在k8s集群中替代了一部分kube-proxy的工作,如果之前有一个pod,那么配置sidecar envoy后就会有两个pod,envoy定义好以后会和nginx一样起一个监听端口,例如我envoy启动了8080端口,服务访问http://localhost:8080就会到达envoy。

此示例都是envoy v3版本后的语法,从0.20版本以后都是v3语法,v2语法不可用

监听器(Listener)

监听器定义了 Envoy 如何处理入站请求,Envoy 监听器主要基于 TCP。它们负责接受进入的网络连接。

listeners:
  - name: listener_0
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 8080

功能:监听器在建立连接后,会将请求传递给过滤器链进行处理。

过滤器(Filter)

过滤器在 Envoy 中用于处理入站和出站流量,是 Envoy 处理流量的关键组件。

filter_chains:
  - filters:
    - name: envoy.filters.network.http_connection_manager
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
        stat_prefix: ingress_http

功能:过滤器可以集成许多特定功能,例如通过 GZip 过滤器在数据发送到客户端之前进行压缩。

路由(Router)

路由组件负责将流量转发到具体的目标实例,这些目标实例在 Envoy 配置中被定义为集群。

route_config:
  name: local_route
  virtual_hosts:
    - name: backend
      domains: ["baga", "baga.com"]
      routes:
        - match:
            prefix: "/3"
          route:
            cluster: targetCluster
        - match:
            prefix: "/4"
          route:
            cluster: targetCluster

功能:根据请求的特征(如 URL 路径、请求头等)将请求路由到不同的后端服务。

集群(Cluster)

集群定义了流量的目标端点,同时包括一些其他可选配置,如负载均衡策略等。

clusters:
  - name: targetCluster
    connect_timeout: 5s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: targetCluster
      endpoints:
        - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: 172.17.0.3
                    port_value: 80
            - endpoint:
                address:
                  socket_address:
                    address: 172.17.0.4
                    port_value: 80

功能:定义了服务发现机制和负载均衡策略,以确保请求均匀且可靠地分发到多个服务实例。

总结一下envoy的访问流程

  1. 监听器(Listener)接收连接

    • 用户侧访问http://localhost:8080,流量到达envoy监听端口
  2. 过滤器链(Filter Chain)处理流量

    • 监听器将流量传递给过滤器链。这些过滤器按照配置的顺序依次处理流量,可以进行安全检查、协议解析、数据转换等操作。
  3. 路由决策(Router)

    • HTTP 连接管理器过滤器解析 HTTP 请求,并根据路由配置将请求路由到相应的后端服务。这涉及匹配请求的 URL、头部等信息。这里和nginx路由差不多,流量扔给cluster
  4. 集群管理(Cluster)

    • k8s里直接写service name,容器或者物理环境就写endpoint,集群对应nginx里面的upstream。
  5. 与后端服务建立连接

    • Envoy 根据确定的目标实例建立连接,并转发请求。如果配置了 TLS,这也包括 TLS 握手。
  6. 响应处理

    • Envoy 接收后端服务的响应,可能会通过响应过滤器进行处理,然后将响应返回给原始请求者。

二、测试功能

目标: 为服务配置http代理,访问到域名baga和baga.com的指定location时将流量代理到对应cluster,cluster是由两个nginx节点组成。

制作测试nginx镜像

创建一个构建Dockerfile的目录,创建default.conf

server {
    listen       80;
    server_name  localhost;

    location / {
        default_type text/plain;
        return 200 'This is on IP: $server_addr';
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

创建Dockerfile

ROM nginx:latest
COPY default.conf /etc/nginx/conf.d/default.conf

docker build -t my-nginx .构建测试nginx镜像

启动测试nginx容器

docker run --name nginx-1 -p 80:80 -d my-nginx
docker run --name nginx-2 -p 800:80 -d my-nginx
# 获取容器IP地址,在envoy cluster endpoint中配置
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-1
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx-2

启动envoy容器

这里贴出完整的测试yaml,命名为envoy.yaml

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 8080
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          codec_type: AUTO
          access_log:
          - name: envoy.access_loggers.file
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
              path: "/dev/stdout"
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains: ["baga","baga.com"]
              routes:
              - match:
                  prefix: "/3"
                route:
                  cluster: targetCluster
              - match:
                  prefix: "/4"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.filters.http.router

  clusters:
  - name: targetCluster
    connect_timeout: 5s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: targetCluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 172.17.0.3
                port_value: 80
        - endpoint:
            address:
              socket_address:
                address: 172.17.0.4
                port_value: 80

这里我将容器的8080映射到了本地8080,所以我们测试直接curl本地8080端口就行

docker run -d --name envoy -p 8080:8080 -v $(pwd)/envoy.yaml:/etc/envoy/envoy.yaml envoyproxy/envoy:v1.20-latest

测试路由功能

这里输出没做换行,但效果能看出来,/3和/4会match到我们的targetCluster,访问方式默认是轮询

$ curl -H "Host: baga.com" http://127.0.0.1:8080/3 
This is on IP: 172.17.0.3 $ curl -H "Host: baga.com" http://127.0.0.1:8080/4
This is on IP: 172.17.0.4 $ 

通过日志观察看到请求是200的

$ docker logs envoy  --tail=2
[2024-08-30T14:16:11.377Z] "GET /3 HTTP/1.1" 200 - 0 25 0 0 "-" "curl/7.81.0" "7bbc3bf1-f579-44ac-8aff-4b773a3f0f98" "baga.com" "172.17.0.3:80"
[2024-08-30T14:16:13.823Z] "GET /4 HTTP/1.1" 200 - 0 25 0 0 "-" "curl/7.81.0" "7d432758-2225-47d9-8b89-3283566b5255" "baga.com" "172.17.0.4:80"

我们再测试一个不会match的路由观察下日志,可以看到404了

$ curl -H "Host: baga.com" http://127.0.0.1:8080/baga
$ docker logs envoy  --tail=1
[2024-08-30T14:22:09.599Z] "GET /baga HTTP/1.1" 404 NR 0 0 0 - "-" "curl/7.81.0" "d6684ec2-297c-4cc7-a0ab-f2b595e3bd38" "baga.com" "-"

至此业务使用的功能已通过测试简单实现
k8s集群中cluster中的服务直接写svc名称就行

参考
https://www.thebyte.com.cn/MicroService/Envoy.html

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值