动态配置(控制平面)

此示例演示了如何使用 Go Control Plane 参考实现来配置 Envoy。

它演示了提供给 Envoy 的配置如何持久化,即使控制平面不可用,并提供了一个简单的示例来说明如何动态更新 Envoy 的配置。

步骤 1:启动代理容器

将目录更改为 Envoy 存储库中的 examples/dynamic-config-cp

首先构建容器并启动 proxy 容器。

这也应该启动两个上游 HTTP 回声服务器,service1service2

控制平面尚未启动。

$ pwd
envoy/examples/dynamic-config-cp
$ docker compose pull
$ docker compose up --build -d proxy
$ docker compose ps

       Name                            Command                State                     Ports
------------------------------------------------------------------------------------------------------------------------
dynamic-config-cp_proxy_1      /docker-entrypoint.sh /usr ... Up      0.0.0.0:10000->10000/tcp, 0.0.0.0:19000->19000/tcp
dynamic-config-cp_service1_1   /bin/echo-server               Up      8080/tcp
dynamic-config-cp_service2_1   /bin/echo-server               Up      8080/tcp

步骤 2:检查初始配置和 Web 响应

由于我们尚未启动控制平面,因此端口 10000 上不应该有任何响应。

$ curl https://127.0.0.1:10000
curl: (56) Recv failure: Connection reset by peer

转储代理的 static_clusters 配置,您应该看到名为 xds_cluster 的集群配置为控制平面

$ curl -s https://127.0.0.1:19000/config_dump  | jq '.configs[1].static_clusters'
[
  {
    "cluster": {
      "@type": "type.googleapis.com/envoy.api.v2.Cluster",
      "name": "xds_cluster",
      "type": "STRICT_DNS",
      "connect_timeout": "1s",
      "http2_protocol_options": {},
      "load_assignment": {
        "cluster_name": "xds_cluster",
        "endpoints": [
          {
            "lb_endpoints": [
              {
                "endpoint": {
                  "address": {
                    "socket_address": {
                      "address": "go-control-plane",
                      "port_value": 18000
                    }
                  }
                }
              }
            ]
          }
        ]
      }
    },
    "last_updated": "2020-10-25T20:20:54.897Z"
  }
]

尚未配置任何 dynamic_active_clusters

$ curl -s https://127.0.0.1:19000/config_dump  | jq '.configs[1].dynamic_active_clusters'
null

步骤 3:启动控制平面

启动 go-control-plane 服务。

您可能需要等待一两分钟才能使其变为 healthy

$ docker compose up --build -d go-control-plane
$ docker compose ps

        Name                                Command                  State                    Ports
-------------------------------------------------------------------------------------------------------------------------------------
dynamic-config-cp_go-control-plane_1  bin/example -debug             Up (healthy)
dynamic-config-cp_proxy_1             /docker-entrypoint.sh /usr ... Up            0.0.0.0:10000->10000/tcp, 0.0.0.0:19000->19000/tcp
dynamic-config-cp_service1_1          /bin/echo-server               Up            8080/tcp
dynamic-config-cp_service2_1          /bin/echo-server               Up            8080/tcp

步骤 4:查询代理

控制平面启动并变为 healthy 后,您应该能够向端口 10000 发出请求,该请求将由 service1 提供服务。

$ curl https://127.0.0.1:10000
Request served by service1

HTTP/1.1 GET /

Host: localhost:10000
Accept: */*
X-Forwarded-Proto: http
X-Request-Id: 1d93050e-f39c-4602-90f8-a124d6e78d26
X-Envoy-Expected-Rq-Timeout-Ms: 15000
Content-Length: 0
User-Agent: curl/7.72.0

步骤 5:转储 Envoy 的 dynamic_active_clusters 配置

如果您现在转储代理的 dynamic_active_clusters 配置,您应该看到它已配置为 example_proxy_cluster 指向 service1,并且版本为 1

$ curl -s https://127.0.0.1:19000/config_dump  | jq '.configs[1].dynamic_active_clusters'
[
  {
    "version_info": "1",
    "cluster": {
      "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
      "name": "example_proxy_cluster",
      "type": "LOGICAL_DNS",
      "connect_timeout": "5s",
      "dns_lookup_family": "V4_ONLY",
      "load_assignment": {
        "cluster_name": "example_proxy_cluster",
        "endpoints": [
          {
            "lb_endpoints": [
              {
                "endpoint": {
                  "address": {
                    "socket_address": {
                      "address": "service1",
                      "port_value": 8080
                    }
                  }
                }
              }
            ]
          }
        ]
      }
    },
    "last_updated": "2020-10-25T20:37:05.838Z"
  }
]

步骤 6:停止控制平面

停止 go-control-plane 服务

$ docker compose stop go-control-plane

Envoy 代理应该继续代理来自 service1 的响应。

$ curl https://127.0.0.1:10000 | grep "served by"
Request served by service1

步骤 7:编辑 go 文件并重启控制平面

示例设置使用自定义 resource.go 文件启动 go-control-plane 服务,该文件指定提供给 Envoy 的配置。

将其更新为使 Envoy 代理到 service2

编辑动态配置示例文件夹中的 resource.go,将 UpstreamHostservice1 更改为 service2

35const (
36	ClusterName  = "example_proxy_cluster"
37	RouteName    = "local_route"
38	ListenerName = "listener_0"
39	ListenerPort = 10000
40	UpstreamHost = "service1"
41	UpstreamPort = 8080
42)

在此文件中的更下方,您还必须将配置快照版本号从 "1" 更改为 "2",以确保 Envoy 将配置视为更新的配置

175func GenerateSnapshot() cache.Snapshot {
176	return cache.NewSnapshot(
177		"1",
178		[]types.Resource{}, // endpoints
179		[]types.Resource{makeCluster(ClusterName)},
180		[]types.Resource{makeRoute(RouteName, ClusterName)},
181		[]types.Resource{makeHTTPListener(ListenerName, RouteName)},
182		[]types.Resource{}, // runtimes
183		[]types.Resource{}, // secrets
184		[]types.Resource{}, // extensions configs
185	)
186}

现在重建并重启控制平面

$ docker compose up --build -d go-control-plane

您可能需要等待一两分钟才能使 go-control-plane 服务再次变为 healthy

步骤 8:检查 Envoy 是否使用更新的配置

现在,当您向代理发出请求时,它应该由上游服务 service2 提供服务。

$ curl https://127.0.0.1:10000 | grep "served by"
Request served by service2

转储 dynamic_active_clusters 您应该看到集群配置现在版本为 2,并且 example_proxy_cluster 配置为代理到 service2

$ curl -s https://127.0.0.1:19000/config_dump  | jq '.configs[1].dynamic_active_clusters'
[
  {
    "version_info": "2",
    "cluster": {
      "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
      "name": "example_proxy_cluster",
      "type": "LOGICAL_DNS",
      "connect_timeout": "5s",
      "dns_lookup_family": "V4_ONLY",
      "load_assignment": {
        "cluster_name": "example_proxy_cluster",
        "endpoints": [
          {
            "lb_endpoints": [
              {
                "endpoint": {
                  "address": {
                    "socket_address": {
                      "address": "service2",
                      "port_value": 8080
                    }
                  }
                }
              }
            ]
          }
        ]
      }
    },
    "last_updated": "2020-10-26T14:35:17.360Z"
  }
]

注意

在此示例中,我们为了简单起见而递增了版本。

对版本的任何更改都会触发 Envoy 的更新,并且顺序无关紧要(有关更新的更多信息,请参见 xDS 协议文档)。

另请参阅

动态配置(控制平面)快速入门指南

使用控制平面动态配置 Envoy 的快速入门指南。

Envoy 管理快速入门指南

Envoy 管理界面的快速入门指南。

动态配置(文件系统)沙箱

使用基于文件系统的动态配置来配置 Envoy。

Go 控制平面

go 编写的 Envoy 控制平面的参考实现。