github.com/polarismesh/polaris@v1.17.8/apiserver/xdsserverv3/eds.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package xdsserverv3 19 20 import ( 21 "strconv" 22 "strings" 23 24 core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 25 corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 26 endpoint "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" 27 "github.com/envoyproxy/go-control-plane/pkg/cache/types" 28 "google.golang.org/protobuf/types/known/wrapperspb" 29 30 "github.com/polarismesh/polaris/apiserver/xdsserverv3/resource" 31 "github.com/polarismesh/polaris/common/model" 32 "github.com/polarismesh/polaris/common/utils" 33 "github.com/polarismesh/polaris/service" 34 ) 35 36 // EDSBuilder . 37 type EDSBuilder struct { 38 client *resource.XDSClient 39 svr service.DiscoverServer 40 } 41 42 func (eds *EDSBuilder) Init(client *resource.XDSClient, svr service.DiscoverServer) { 43 eds.client = client 44 eds.svr = svr 45 } 46 47 func (eds *EDSBuilder) Generate(option *resource.BuildOption) (interface{}, error) { 48 var resources []types.Resource 49 switch eds.client.RunType { 50 case resource.RunTypeGateway: 51 resources = append(resources, eds.makeBoundEndpoints(option, core.TrafficDirection_OUTBOUND)...) 52 case resource.RunTypeSidecar: 53 // sidecar 场景,如果流量方向是 envoy -> 业务 POD,那么 endpoint 只能是 本地 127.0.0.1 54 inBoundEndpoints := eds.makeSelfEndpoint(option) 55 outBoundEndpoints := eds.makeBoundEndpoints(option, core.TrafficDirection_OUTBOUND) 56 resources = append(resources, inBoundEndpoints...) 57 resources = append(resources, outBoundEndpoints...) 58 } 59 return resources, nil 60 } 61 62 func (eds *EDSBuilder) makeBoundEndpoints(option *resource.BuildOption, 63 direction corev3.TrafficDirection) []types.Resource { 64 65 services := option.Services 66 selfServiceKey := model.ServiceKey{ 67 Namespace: eds.client.GetSelfNamespace(), 68 Name: eds.client.GetSelfService(), 69 } 70 71 var clusterLoads []types.Resource 72 for svcKey, serviceInfo := range services { 73 if eds.client.IsGateway() && selfServiceKey.Equal(&svcKey) { 74 continue 75 } 76 77 var lbEndpoints []*endpoint.LbEndpoint 78 for _, instance := range serviceInfo.Instances { 79 // 处于隔离状态或者权重为0的实例不进行下发 80 if !resource.IsNormalEndpoint(instance) { 81 continue 82 } 83 ep := &endpoint.LbEndpoint{ 84 HostIdentifier: &endpoint.LbEndpoint_Endpoint{ 85 Endpoint: &endpoint.Endpoint{ 86 Address: &core.Address{ 87 Address: &core.Address_SocketAddress{ 88 SocketAddress: &core.SocketAddress{ 89 Protocol: core.SocketAddress_TCP, 90 Address: instance.Host.Value, 91 PortSpecifier: &core.SocketAddress_PortValue{ 92 PortValue: instance.Port.Value, 93 }, 94 }, 95 }, 96 }, 97 }, 98 }, 99 HealthStatus: resource.FormatEndpointHealth(instance), 100 LoadBalancingWeight: utils.NewUInt32Value(instance.GetWeight().GetValue()), 101 Metadata: resource.GenEndpointMetaFromPolarisIns(instance), 102 } 103 lbEndpoints = append(lbEndpoints, ep) 104 } 105 106 cla := &endpoint.ClusterLoadAssignment{ 107 ClusterName: resource.MakeServiceName(svcKey, direction), 108 Endpoints: []*endpoint.LocalityLbEndpoints{ 109 { 110 LbEndpoints: lbEndpoints, 111 }, 112 }, 113 } 114 clusterLoads = append(clusterLoads, cla) 115 } 116 return clusterLoads 117 } 118 119 func (eds *EDSBuilder) makeSelfEndpoint(option *resource.BuildOption) []types.Resource { 120 var clusterLoads []types.Resource 121 var lbEndpoints []*endpoint.LbEndpoint 122 123 selfServiceKey := model.ServiceKey{ 124 Namespace: eds.client.GetSelfNamespace(), 125 Name: eds.client.GetSelfService(), 126 } 127 128 var servicePorts []*model.ServicePort 129 selfServiceInfo, ok := option.Services[selfServiceKey] 130 if ok { 131 servicePorts = selfServiceInfo.Ports 132 } else { 133 // sidecar 的服务没有注册,那就看下 envoy metadata 上有没有设置 sidecar_bindports 标签 134 portsSlice := strings.Split(eds.client.Metadata[resource.SidecarBindPort], ",") 135 if len(portsSlice) > 0 { 136 for i := range portsSlice { 137 ret, err := strconv.ParseUint(portsSlice[i], 10, 64) 138 if err != nil { 139 continue 140 } 141 if ret <= 65535 { 142 servicePorts = append(servicePorts, &model.ServicePort{ 143 Port: uint32(ret), 144 Protocol: "TCP", 145 }) 146 } 147 } 148 } 149 } 150 151 for _, port := range servicePorts { 152 ep := &endpoint.LbEndpoint{ 153 HostIdentifier: &endpoint.LbEndpoint_Endpoint{ 154 Endpoint: &endpoint.Endpoint{ 155 Address: &core.Address{ 156 Address: &core.Address_SocketAddress{ 157 SocketAddress: &core.SocketAddress{ 158 Protocol: core.SocketAddress_TCP, 159 Address: "127.0.0.1", 160 PortSpecifier: &core.SocketAddress_PortValue{ 161 PortValue: port.Port, 162 }, 163 }, 164 }, 165 }, 166 }, 167 }, 168 LoadBalancingWeight: wrapperspb.UInt32(100), 169 HealthStatus: core.HealthStatus_HEALTHY, 170 } 171 lbEndpoints = append(lbEndpoints, ep) 172 } 173 cla := &endpoint.ClusterLoadAssignment{ 174 ClusterName: resource.MakeServiceName(selfServiceKey, core.TrafficDirection_INBOUND), 175 Endpoints: []*endpoint.LocalityLbEndpoints{ 176 { 177 LbEndpoints: lbEndpoints, 178 }, 179 }, 180 } 181 clusterLoads = append(clusterLoads, cla) 182 return clusterLoads 183 }