什麼是控制台
這篇我們來看看如何通過控制平面(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等資源進行增删改查