当前位置: 首页 > 工具软件 > ControlPlane > 使用案例 >

envoy 文档动态配置示例 Dynamic configuration (control plane) 解释

吴涵育
2023-12-01

Dynamic configuration (control plane)

对于envoy 使用服务器实现动态配置,需要开发相应的响应程序,文档里提到使用 go 语言开发的 control plane 作为服务器,对 xds API 请求动态配置进行响应。相关文章envoy 文档动态配置示例 Dynamic configuration (control plane) 解释

准备工作

  1. 一个含有 envoy 和envoy初始配置的容器作为前端代理,这个容器同时含有 envoy 的管理接口
  2. 一个含有响应 前端代理 xds API 的服务程序的容器Dynamic configuration (control plane)
  3. 两个响应web请求的普通web服务器

前端代理

容器 docker-compose 配置

  proxy:
    build:
      context: .
      dockerfile: Dockerfile-proxy
    depends_on:
    - service1
    - service2
    ports:
    - 10000:10000
    - 19000:19000

端口

暴露 10000 端口给客户端
暴露 19000 端口作为外界向管理接口发出请求

基础镜像

基础镜像使用 envoyproxy/envoy:v1.23.1 指定容器中初始配置文件位置 /etc/envoy.yaml

FROM envoyproxy/envoy:v1.23.1

COPY ./envoy.yaml /etc/envoy.yaml
RUN chmod go+r /etc/envoy.yaml
CMD ["/usr/local/bin/envoy", "-c /etc/envoy.yaml"]

envoy 初始配置

envoy 管理接口

监听 19000

admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 19000

envoy 使用动态配置

使用动态配置,并指定xds API 获取动态配置请求的服务器 xds_cluster

dynamic_resources:
  ads_config:
    api_type: GRPC
    transport_api_version: V3
    grpc_services:
    - envoy_grpc:
        cluster_name: xds_cluster
  cds_config:
    resource_api_version: V3
    ads: {}
  lds_config:
    resource_api_version: V3
    ads: {}

响应动态配置的服务器

动态配置服务器的位置地址为 go-control-plane 端口号为 18000

    name: xds_cluster
    load_assignment:
      cluster_name: xds_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: go-control-plane
                port_value: 18000

响应 前端代理 xds API 的服务程序的容器

容器 docker-compose 配置

  go-control-plane:
    build:
      context: .
      dockerfile: Dockerfile-control-plane
    command: bin/example
    healthcheck:
      test: nc -zv localhost 18000

基础镜像

使用 golang:1.14 作为基础镜像,使用动态配置响应程序https://github.com/envoyproxy/go-control-plane ,该程序监听 18000。编译前通过修改 resource.go 修改envoy的动态配置

const (
	ClusterName  = "example_proxy_cluster"
	RouteName    = "local_route"
	ListenerName = "listener_0"
	ListenerPort = 10000
	UpstreamHost = "service1"
	UpstreamPort = 8080
)

该程序编译好后放入镜像中,并在容器创建时运行该程序,用来响应 xds API 对动态配置的请求

FROM golang:1.14

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get -qq update \
    && apt-get -qq install --no-install-recommends -y netcat \
    && apt-get -qq autoremove -y \
    && apt-get clean \
    && rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/*

RUN git clone https://github.com/envoyproxy/go-control-plane && cd go-control-plane && git checkout b4adc3bb5fe5288bff01cd452dad418ef98c676e
ADD ./resource.go /go/go-control-plane/internal/example/resource.go
RUN cd go-control-plane && make bin/example
WORKDIR /go/go-control-plane

其它两个 web 服务器容器

容器 docker-compose 配置

  service1:
    build:
      context: ../shared/echo
    hostname: service1

  service2:
    build:
      context: ../shared/echo
    hostname: service2

基础镜像

../shared/echo/Dockerfile 里使用 jmalloc/echo-server:0.3.3 作为基础镜像
https://github.com/jmalloc/echo-server

验证

使用 docker-compose up 可以拉取并编译镜像,创建容器。

验证代理转发

通过暴露的端口 10000 请求 envoy 前端代理

$ curl http://localhost:10000
Request served by service1

HTTP/1.1 GET /

Host: localhost:10000
Accept: */*
User-Agent: curl/7.61.1
X-Envoy-Expected-Rq-Timeout-Ms: 15000
X-Forwarded-Proto: http
X-Request-Id: 386e43f0-0dee-4db5-b341-f25c3b0c51df

如果配置了多个 endpoints 的话,而且 cluster 使用的轮换的负载均衡策略 round_robin 可以尝试 while sleep 1; do curl -i http://localhost:10000; done 循环请求观察是否按策略切换 endpoint

验证管理接口

通过暴露的端口 19000 请求 envoy 前端代理容器里的管理接口

$ curl -s http://localhost:19000/config_dump  | jq '.configs[1].dynamic_active_clusters[0].cluster.load_assignment.endpoints[0].lb_endpoints[0].endpoint.address.socket_address'
{
  "address": "service1",
  "port_value": 8080
}

验证动态配置

修改 upstream 配置

由于这里将配置固定在 control plane 程序里了。这里通过重新编译 resource.go 然后重新创建 go-control-plane 所在容器的方式实现配置的变化。不需要重启前端代理 envoy

resource.go

const (
	ClusterName  = "example_proxy_cluster"
	RouteName    = "local_route"
	ListenerName = "listener_0"
	ListenerPort = 10000
	UpstreamHost = "service2"
	UpstreamPort = 8080
)

查看集群结点地址

$ curl -s http://localhost:19000/config_dump  | jq '.configs[1].dynamic_active_clusters[0].cluster.load_assignment.endpoints[0].lb_endpoints[0].endpoint.address.socket_address'
{
  "address": "service2",
  "port_value": 8080
}

代理转发

$ curl http://localhost:10000
Request served by service2

HTTP/1.1 GET /

Host: localhost:10000
Accept: */*
User-Agent: curl/7.61.1
X-Envoy-Expected-Rq-Timeout-Ms: 15000
X-Forwarded-Proto: http
X-Request-Id: 7f2d1344-be24-4301-ae7d-f8c376ad1e13

Ref

Dynamic configuration (control plane) Official DOC
dynamic-config-cp Github
go-control-plane on pkg.go.dev
example#dynamic Official DOC

 类似资料: