- A+
什么是控制面板
这篇我们来看看如何通过控制平面(Control Panel)来配置Envoy。
控制平面就是一个提供Envoy配置信息的单独服务,Envoy可以通过调用这个服务的api来加载配置。
配置控制面板
官方为我们提供了两种已经实现好的控制面板。
go控制面板:https://github.com/envoyproxy/go-control-plane
java控制面板:https://github.com/envoyproxy/java-control-plane
我们下载官方的go语言控制面板,先来看看go控制面板中提供的样例结构。
其中有三个核心文件,main.go,server.go,与resource.go
1.main.go:启动go-controll-panel的入口
2.server.go:定义go-controll-panel的grpc服务
3.resource.go:定义了envoy相关的资源配置,包括cluster,listener,endpoint等
其中resource.go组成了一个结构化的配置信息,并通过server.go中的grpc提供给envoy,而main.go则是启动了grpc,因此我们需要修改的就是resource.go中的资源配置,需要将里面的cluster,listener,endpoint等设置为我们自己的服务信息。下面我们就来将resource.go中的配置信息改成我们自己的测试项目配置。
首先修改upstream信息,指定我们的上游服务的ip与两个上游服务的端口
const ( ClusterName = "example_proxy_cluster" RouteName = "local_route" ListenerName = "listener_0" ListenerPort = 10000 UpstreamHost = "192.168.43.94" UpstreamPort = 5000 UpstreamPort2 = 5001 )
然后我们修改dns类型,将其修改为静态dns解析
func makeCluster(clusterName string) *cluster.Cluster { return &cluster.Cluster{ Name: clusterName, ConnectTimeout: ptypes.DurationProto(5 * time.Second), ClusterDiscoveryType: &cluster.Cluster_Type{Type: cluster.Cluster_STATIC}, LbPolicy: cluster.Cluster_ROUND_ROBIN, LoadAssignment: makeEndpoint(clusterName), DnsLookupFamily: cluster.Cluster_V4_ONLY, } }
修改makeEndpoint方法,指定两个测试server,server1与server2的地址为Endpoint
func makeEndpoint(clusterName string) *endpoint.ClusterLoadAssignment { return &endpoint.ClusterLoadAssignment{ ClusterName: clusterName, Endpoints: []*endpoint.LocalityLbEndpoints{{ LbEndpoints: []*endpoint.LbEndpoint{{ HostIdentifier: &endpoint.LbEndpoint_Endpoint{ Endpoint: &endpoint.Endpoint{ Address: &core.Address{ Address: &core.Address_SocketAddress{ SocketAddress: &core.SocketAddress{ Protocol: core.SocketAddress_TCP, Address: UpstreamHost, PortSpecifier: &core.SocketAddress_PortValue{ PortValue: UpstreamPort, }, }, }, }, }, }, }, { HostIdentifier: &endpoint.LbEndpoint_Endpoint{ Endpoint: &endpoint.Endpoint{ Address: &core.Address{ Address: &core.Address_SocketAddress{ SocketAddress: &core.SocketAddress{ Protocol: core.SocketAddress_TCP, Address: UpstreamHost, PortSpecifier: &core.SocketAddress_PortValue{ PortValue: UpstreamPort2, }, }, }, }, }, }, }, }, }}, } }
启动控制平面
控制平面监听在18000端口
配置Envoy
我们需要配置Envoy.yaml让Envoy从控制平面中获取详细的配置信息。我们可以参考官网的推荐配置。
1.需要在dynamic_resources中配置ads_config,并让cds_config与lds_config从中读取
2.另外我们需要配置xds cluster,让Envoy知道控制平面的地址。
具体配置信息如下:
admin: address: socket_address: address: 0.0.0.0 port_value: 9902 node: cluster: test-cluster id: test-id 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: {} static_resources: clusters: - type: STRICT_DNS typed_extension_protocol_options: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicit_http_config: http2_protocol_options: {} name: xds_cluster load_assignment: cluster_name: xds_cluster endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 192.168.43.94 port_value: 18000
运行Envoy
我们通过docker运行Envoy
docker run --rm -it -p 9902:9902 -p 10000:10000 -v D:/gateway/envoy/config/dynamic-plane/:/etc/envoy/ -v D:/gateway/envoy/logs:/logs envoyproxy/envoy-dev -c /etc/envoy/envoy.yaml
然后启动我们上一节的server1与server2
测试
我们通过http://localhost:10000/Name来判断我们的配置是不是配置成功
可以看到其中一次调用返回了server1,另一次调用返回了server2,控制面板验证成功!
二次开发
目前的样例代码中提供的配置都是硬编码的方式,把配置写死在代码中,如果生产环境中我们想使用这种方式来配置envoy,我们可以基于现在的代码二次开发。开发的步骤如下:
1.新增数据库表结构组织Envoy中的资源,比如Listener表,Cluster表,Endpoint表,Route表
2.新增接口来对Listener,Cluster,Endpoint,Route等资源进行增删改查
3.新增UI来调用增删改查接口,对资源进行管理
4.定时刷新Snapshot信息
这样我们就可以实现一个可视化的界面来动态的配置我们的Envoy。