什么是控制面板
這篇我們來看看如何通過控制平面(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
.NET網關與Gateway實戰-Envoy與kong課程希望大家支持 https://ke.qq.com/course/4033027?tuin=1271860f

我們需要配置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。
