什麼是控制皮膚
這篇我們來看看如何通過控制平面(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。