Fix destination rule issues (#282)

This commit is contained in:
澄潭
2023-04-10 13:41:43 +08:00
committed by GitHub
parent a9742bbae1
commit 283432b6eb
10 changed files with 145 additions and 92 deletions

View File

@@ -559,27 +559,36 @@ func (m *IngressConfig) convertDestinationRule(configs []common.WrapperConfig) [
IngressLog.Debugf("traffic policy number %d", len(convertOptions.Service2TrafficPolicy)) IngressLog.Debugf("traffic policy number %d", len(convertOptions.Service2TrafficPolicy))
for _, wrapperTrafficPolicy := range convertOptions.Service2TrafficPolicy { for _, wrapperTrafficPolicy := range convertOptions.Service2TrafficPolicy {
m.annotationHandler.ApplyTrafficPolicy(wrapperTrafficPolicy.TrafficPolicy, wrapperTrafficPolicy.WrapperConfig.AnnotationsConfig) m.annotationHandler.ApplyTrafficPolicy(wrapperTrafficPolicy.TrafficPolicy, wrapperTrafficPolicy.PortTrafficPolicy, wrapperTrafficPolicy.WrapperConfig.AnnotationsConfig)
} }
// Merge multi-port traffic policy per service into one destination rule. // Merge multi-port traffic policy per service into one destination rule.
destinationRules := map[string]*common.WrapperDestinationRule{} destinationRules := map[string]*common.WrapperDestinationRule{}
for key, wrapperTrafficPolicy := range convertOptions.Service2TrafficPolicy { for key, wrapperTrafficPolicy := range convertOptions.Service2TrafficPolicy {
serviceName := util.CreateServiceFQDN(key.Namespace, key.Name) var serviceName string
if key.ServiceFQDN != "" {
serviceName = key.ServiceFQDN
} else {
serviceName = util.CreateServiceFQDN(key.Namespace, key.Name)
}
dr, exist := destinationRules[serviceName] dr, exist := destinationRules[serviceName]
if !exist { if !exist {
trafficPolicy := &networking.TrafficPolicy{}
if wrapperTrafficPolicy.PortTrafficPolicy != nil {
trafficPolicy.PortLevelSettings = []*networking.TrafficPolicy_PortTrafficPolicy{wrapperTrafficPolicy.PortTrafficPolicy}
} else if wrapperTrafficPolicy.TrafficPolicy != nil {
trafficPolicy = wrapperTrafficPolicy.TrafficPolicy
}
dr = &common.WrapperDestinationRule{ dr = &common.WrapperDestinationRule{
DestinationRule: &networking.DestinationRule{ DestinationRule: &networking.DestinationRule{
Host: serviceName, Host: serviceName,
TrafficPolicy: &networking.TrafficPolicy{ TrafficPolicy: trafficPolicy,
PortLevelSettings: []*networking.TrafficPolicy_PortTrafficPolicy{wrapperTrafficPolicy.TrafficPolicy},
},
}, },
WrapperConfig: wrapperTrafficPolicy.WrapperConfig, WrapperConfig: wrapperTrafficPolicy.WrapperConfig,
ServiceKey: key, ServiceKey: key,
} }
} else { } else if wrapperTrafficPolicy.PortTrafficPolicy != nil {
dr.DestinationRule.TrafficPolicy.PortLevelSettings = append(dr.DestinationRule.TrafficPolicy.PortLevelSettings, wrapperTrafficPolicy.TrafficPolicy) dr.DestinationRule.TrafficPolicy.PortLevelSettings = append(dr.DestinationRule.TrafficPolicy.PortLevelSettings, wrapperTrafficPolicy.PortTrafficPolicy)
} }
destinationRules[serviceName] = dr destinationRules[serviceName] = dr

View File

@@ -192,8 +192,8 @@ func (h *AnnotationHandlerManager) ApplyRoute(route *networking.HTTPRoute, confi
} }
} }
func (h *AnnotationHandlerManager) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy_PortTrafficPolicy, config *Ingress) { func (h *AnnotationHandlerManager) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy, portTrafficPolicy *networking.TrafficPolicy_PortTrafficPolicy, config *Ingress) {
for _, handler := range h.trafficPolicyHandlers { for _, handler := range h.trafficPolicyHandlers {
handler.ApplyTrafficPolicy(trafficPolicy, config) handler.ApplyTrafficPolicy(trafficPolicy, portTrafficPolicy, config)
} }
} }

View File

@@ -38,5 +38,5 @@ type RouteHandler interface {
type TrafficPolicyHandler interface { type TrafficPolicyHandler interface {
// ApplyTrafficPolicy parsed ingress annotation config reflected on traffic policy // ApplyTrafficPolicy parsed ingress annotation config reflected on traffic policy
ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy_PortTrafficPolicy, config *Ingress) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy, portTrafficPolicy *networking.TrafficPolicy_PortTrafficPolicy, config *Ingress)
} }

View File

@@ -136,14 +136,16 @@ func (l loadBalance) Parse(annotations Annotations, config *Ingress, _ *GlobalCo
return nil return nil
} }
func (l loadBalance) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy_PortTrafficPolicy, config *Ingress) { func (l loadBalance) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy, portTrafficPolicy *networking.TrafficPolicy_PortTrafficPolicy, config *Ingress) {
loadBalanceConfig := config.LoadBalance loadBalanceConfig := config.LoadBalance
if loadBalanceConfig == nil { if loadBalanceConfig == nil {
return return
} }
var loadBalancer *networking.LoadBalancerSettings
if loadBalanceConfig.cookie != nil { if loadBalanceConfig.cookie != nil {
trafficPolicy.LoadBalancer = &networking.LoadBalancerSettings{ loadBalancer = &networking.LoadBalancerSettings{
LbPolicy: &networking.LoadBalancerSettings_ConsistentHash{ LbPolicy: &networking.LoadBalancerSettings_ConsistentHash{
ConsistentHash: &networking.LoadBalancerSettings_ConsistentHashLB{ ConsistentHash: &networking.LoadBalancerSettings_ConsistentHashLB{
HashKey: &networking.LoadBalancerSettings_ConsistentHashLB_HttpCookie{ HashKey: &networking.LoadBalancerSettings_ConsistentHashLB_HttpCookie{
@@ -171,18 +173,25 @@ func (l loadBalance) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy_
}, },
} }
} }
trafficPolicy.LoadBalancer = &networking.LoadBalancerSettings{ loadBalancer = &networking.LoadBalancerSettings{
LbPolicy: &networking.LoadBalancerSettings_ConsistentHash{ LbPolicy: &networking.LoadBalancerSettings_ConsistentHash{
ConsistentHash: consistentHash, ConsistentHash: consistentHash,
}, },
} }
} else { } else {
trafficPolicy.LoadBalancer = &networking.LoadBalancerSettings{ loadBalancer = &networking.LoadBalancerSettings{
LbPolicy: &networking.LoadBalancerSettings_Simple{ LbPolicy: &networking.LoadBalancerSettings_Simple{
Simple: loadBalanceConfig.simple, Simple: loadBalanceConfig.simple,
}, },
} }
} }
if trafficPolicy != nil {
trafficPolicy.LoadBalancer = loadBalancer
}
if portTrafficPolicy != nil {
portTrafficPolicy.LoadBalancer = loadBalancer
}
} }
func isCookieAffinity(annotations Annotations) bool { func isCookieAffinity(annotations Annotations) bool {

View File

@@ -229,7 +229,7 @@ func TestLoadBalanceApplyTrafficPolicy(t *testing.T) {
for _, inputCase := range inputCases { for _, inputCase := range inputCases {
t.Run("", func(t *testing.T) { t.Run("", func(t *testing.T) {
loadBalance.ApplyTrafficPolicy(inputCase.input, inputCase.config) loadBalance.ApplyTrafficPolicy(nil, inputCase.input, inputCase.config)
if !reflect.DeepEqual(inputCase.input, inputCase.expect) { if !reflect.DeepEqual(inputCase.input, inputCase.expect) {
t.Fatal("Should be equal") t.Fatal("Should be equal")
} }

View File

@@ -75,6 +75,20 @@ func (u upstreamTLS) Parse(annotations Annotations, config *Ingress, _ *GlobalCo
} }
} }
if sslVerify, err := annotations.ParseStringASAP(proxySSLVerify); err == nil {
if OnOffRegex.MatchString(sslVerify) {
upstreamTLSConfig.SSLVerify = onOffToBool(sslVerify)
}
}
upstreamTLSConfig.SNI, _ = annotations.ParseStringASAP(proxySSLName)
if enableSNI, err := annotations.ParseStringASAP(proxySSLServerName); err == nil {
if OnOffRegex.MatchString(enableSNI) {
upstreamTLSConfig.EnableSNI = onOffToBool(enableSNI)
}
}
secretName, _ := annotations.ParseStringASAP(proxySSLSecret) secretName, _ := annotations.ParseStringASAP(proxySSLSecret)
namespacedName := util.SplitNamespacedName(secretName) namespacedName := util.SplitNamespacedName(secretName)
if namespacedName.Name == "" { if namespacedName.Name == "" {
@@ -86,32 +100,19 @@ func (u upstreamTLS) Parse(annotations Annotations, config *Ingress, _ *GlobalCo
} }
upstreamTLSConfig.SecretName = namespacedName.String() upstreamTLSConfig.SecretName = namespacedName.String()
if sslVerify, err := annotations.ParseStringASAP(proxySSLVerify); err == nil {
if OnOffRegex.MatchString(sslVerify) {
upstreamTLSConfig.SSLVerify = onOffToBool(sslVerify)
}
}
upstreamTLSConfig.SNI, _ = annotations.ParseStringASAP(proxySSLName)
if enableSNI, err := annotations.ParseStringASAP(proxySSLServerName); err == nil {
if OnOffRegex.MatchString(enableSNI) {
upstreamTLSConfig.SSLVerify = onOffToBool(enableSNI)
}
}
return nil return nil
} }
func (u upstreamTLS) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy_PortTrafficPolicy, config *Ingress) { func (u upstreamTLS) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy, portTrafficPolicy *networking.TrafficPolicy_PortTrafficPolicy, config *Ingress) {
if config.UpstreamTLS == nil { if config.UpstreamTLS == nil {
return return
} }
upstreamTLSConfig := config.UpstreamTLS upstreamTLSConfig := config.UpstreamTLS
var connectionPool *networking.ConnectionPoolSettings
if isH2(upstreamTLSConfig.BackendProtocol) { if isH2(upstreamTLSConfig.BackendProtocol) {
trafficPolicy.ConnectionPool = &networking.ConnectionPoolSettings{ connectionPool = &networking.ConnectionPoolSettings{
Http: &networking.ConnectionPoolSettings_HTTPSettings{ Http: &networking.ConnectionPoolSettings_HTTPSettings{
H2UpgradePolicy: networking.ConnectionPoolSettings_HTTPSettings_UPGRADE, H2UpgradePolicy: networking.ConnectionPoolSettings_HTTPSettings_UPGRADE,
}, },
@@ -125,9 +126,15 @@ func (u upstreamTLS) ApplyTrafficPolicy(trafficPolicy *networking.TrafficPolicy_
} else if isHTTPS(upstreamTLSConfig.BackendProtocol) { } else if isHTTPS(upstreamTLSConfig.BackendProtocol) {
tls = processSimple(config) tls = processSimple(config)
} }
if trafficPolicy != nil {
trafficPolicy.ConnectionPool = connectionPool
trafficPolicy.Tls = tls trafficPolicy.Tls = tls
} }
if portTrafficPolicy != nil {
portTrafficPolicy.ConnectionPool = connectionPool
portTrafficPolicy.Tls = tls
}
}
func processMTLS(config *Ingress) *networking.ClientTLSSettings { func processMTLS(config *Ingress) *networking.ClientTLSSettings {
namespacedName := util.SplitNamespacedName(config.UpstreamTLS.SecretName) namespacedName := util.SplitNamespacedName(config.UpstreamTLS.SecretName)

View File

@@ -47,6 +47,7 @@ func TestUpstreamTLSParse(t *testing.T) {
SSLVerify: true, SSLVerify: true,
SNI: "SSLName", SNI: "SSLName",
SecretName: "namespace/SSLSecret", SecretName: "namespace/SSLSecret",
EnableSNI: true,
}, },
}, },
{ {
@@ -60,9 +61,10 @@ func TestUpstreamTLSParse(t *testing.T) {
}, },
expect: &UpstreamTLSConfig{ expect: &UpstreamTLSConfig{
BackendProtocol: "HTTP2", BackendProtocol: "HTTP2",
SSLVerify: false, SSLVerify: true,
SNI: "", SNI: "SSLName",
SecretName: "", SecretName: "",
EnableSNI: true,
}, },
}, },
} }
@@ -143,7 +145,7 @@ func TestApplyTrafficPolicy(t *testing.T) {
for _, testCase := range testCases { for _, testCase := range testCases {
t.Run("", func(t *testing.T) { t.Run("", func(t *testing.T) {
parser.ApplyTrafficPolicy(testCase.input, testCase.config) parser.ApplyTrafficPolicy(nil, testCase.input, testCase.config)
if diff := cmp.Diff(testCase.expect, testCase.input); diff != "" { if diff := cmp.Diff(testCase.expect, testCase.input); diff != "" {
t.Fatalf("TestApplyTrafficPolicy() mismatch (-want +got): \n%s", diff) t.Fatalf("TestApplyTrafficPolicy() mismatch (-want +got): \n%s", diff)
} }

View File

@@ -30,6 +30,7 @@ import (
type ServiceKey struct { type ServiceKey struct {
Namespace string Namespace string
Name string Name string
ServiceFQDN string
Port int32 Port int32
} }
@@ -98,7 +99,8 @@ type WrapperVirtualService struct {
} }
type WrapperTrafficPolicy struct { type WrapperTrafficPolicy struct {
TrafficPolicy *networking.TrafficPolicy_PortTrafficPolicy TrafficPolicy *networking.TrafficPolicy
PortTrafficPolicy *networking.TrafficPolicy_PortTrafficPolicy
WrapperConfig *WrapperConfig WrapperConfig *WrapperConfig
} }

View File

@@ -848,20 +848,9 @@ func (c *controller) ConvertTrafficPolicy(convertOptions *common.ConvertOptions,
} }
if ingressV1Beta.Backend != nil { if ingressV1Beta.Backend != nil {
serviceKey, err := c.createServiceKey(ingressV1Beta.Backend, cfg.Namespace) err := c.storeBackendTrafficPolicy(wrapper, ingressV1Beta.Backend, convertOptions.Service2TrafficPolicy)
if err != nil { if err != nil {
IngressLog.Errorf("ignore default service %s within ingress %s/%s", serviceKey.Name, cfg.Namespace, cfg.Name) IngressLog.Errorf("ignore default service within ingress %s/%s, since error:%v", cfg.Namespace, cfg.Name, err)
} else {
if _, exist := convertOptions.Service2TrafficPolicy[serviceKey]; !exist {
convertOptions.Service2TrafficPolicy[serviceKey] = &common.WrapperTrafficPolicy{
TrafficPolicy: &networking.TrafficPolicy_PortTrafficPolicy{
Port: &networking.PortSelector{
Number: uint32(serviceKey.Port),
},
},
WrapperConfig: wrapper,
}
}
} }
} }
@@ -871,22 +860,46 @@ func (c *controller) ConvertTrafficPolicy(convertOptions *common.ConvertOptions,
} }
for _, httpPath := range rule.HTTP.Paths { for _, httpPath := range rule.HTTP.Paths {
if httpPath.Backend.ServiceName == "" { err := c.storeBackendTrafficPolicy(wrapper, &httpPath.Backend, convertOptions.Service2TrafficPolicy)
continue
}
serviceKey, err := c.createServiceKey(&httpPath.Backend, cfg.Namespace)
if err != nil { if err != nil {
IngressLog.Errorf("ignore service %s within ingress %s/%s", serviceKey.Name, cfg.Namespace, cfg.Name) IngressLog.Errorf("ignore service within ingress %s/%s, since error:%v", cfg.Namespace, cfg.Name, err)
continue }
}
} }
if _, exist := convertOptions.Service2TrafficPolicy[serviceKey]; exist { return nil
continue
} }
convertOptions.Service2TrafficPolicy[serviceKey] = &common.WrapperTrafficPolicy{ func (c *controller) storeBackendTrafficPolicy(wrapper *common.WrapperConfig, backend *ingress.IngressBackend, store map[common.ServiceKey]*common.WrapperTrafficPolicy) error {
TrafficPolicy: &networking.TrafficPolicy_PortTrafficPolicy{ if backend == nil {
return errors.New("invalid empty backend")
}
if common.ValidateBackendResource(backend.Resource) && wrapper.AnnotationsConfig.Destination != nil {
for _, dest := range wrapper.AnnotationsConfig.Destination.McpDestination {
serviceKey := common.ServiceKey{
Namespace: "mcp",
Name: dest.Destination.Host,
ServiceFQDN: dest.Destination.Host,
}
if _, exist := store[serviceKey]; !exist {
store[serviceKey] = &common.WrapperTrafficPolicy{
TrafficPolicy: &networking.TrafficPolicy{},
WrapperConfig: wrapper,
}
}
}
} else {
if backend.ServiceName == "" {
return nil
}
serviceKey, err := c.createServiceKey(backend, wrapper.Config.Namespace)
if err != nil {
return fmt.Errorf("ignore service %s within ingress %s/%s", serviceKey.Name, wrapper.Config.Namespace, wrapper.Config.Name)
}
if _, exist := store[serviceKey]; !exist {
store[serviceKey] = &common.WrapperTrafficPolicy{
PortTrafficPolicy: &networking.TrafficPolicy_PortTrafficPolicy{
Port: &networking.PortSelector{ Port: &networking.PortSelector{
Number: uint32(serviceKey.Port), Number: uint32(serviceKey.Port),
}, },
@@ -895,7 +908,6 @@ func (c *controller) ConvertTrafficPolicy(convertOptions *common.ConvertOptions,
} }
} }
} }
return nil return nil
} }

View File

@@ -848,20 +848,9 @@ func (c *controller) ConvertTrafficPolicy(convertOptions *common.ConvertOptions,
} }
if ingressV1.DefaultBackend != nil { if ingressV1.DefaultBackend != nil {
serviceKey, err := c.createServiceKey(ingressV1.DefaultBackend.Service, cfg.Namespace) err := c.storeBackendTrafficPolicy(wrapper, ingressV1.DefaultBackend, convertOptions.Service2TrafficPolicy)
if err != nil { if err != nil {
IngressLog.Errorf("ignore default service %s within ingress %s/%s", serviceKey.Name, cfg.Namespace, cfg.Name) IngressLog.Errorf("ignore default service within ingress %s/%s, since error:%v", cfg.Namespace, cfg.Name, err)
} else {
if _, exist := convertOptions.Service2TrafficPolicy[serviceKey]; !exist {
convertOptions.Service2TrafficPolicy[serviceKey] = &common.WrapperTrafficPolicy{
TrafficPolicy: &networking.TrafficPolicy_PortTrafficPolicy{
Port: &networking.PortSelector{
Number: uint32(serviceKey.Port),
},
},
WrapperConfig: wrapper,
}
}
} }
} }
@@ -871,22 +860,46 @@ func (c *controller) ConvertTrafficPolicy(convertOptions *common.ConvertOptions,
} }
for _, httpPath := range rule.HTTP.Paths { for _, httpPath := range rule.HTTP.Paths {
if httpPath.Backend.Service == nil { err := c.storeBackendTrafficPolicy(wrapper, &httpPath.Backend, convertOptions.Service2TrafficPolicy)
continue
}
serviceKey, err := c.createServiceKey(httpPath.Backend.Service, cfg.Namespace)
if err != nil { if err != nil {
IngressLog.Errorf("ignore service %s within ingress %s/%s", serviceKey.Name, cfg.Namespace, cfg.Name) IngressLog.Errorf("ignore service within ingress %s/%s, since error:%v", cfg.Namespace, cfg.Name, err)
continue }
}
} }
if _, exist := convertOptions.Service2TrafficPolicy[serviceKey]; exist { return nil
continue
} }
convertOptions.Service2TrafficPolicy[serviceKey] = &common.WrapperTrafficPolicy{ func (c *controller) storeBackendTrafficPolicy(wrapper *common.WrapperConfig, backend *ingress.IngressBackend, store map[common.ServiceKey]*common.WrapperTrafficPolicy) error {
TrafficPolicy: &networking.TrafficPolicy_PortTrafficPolicy{ if backend == nil {
return errors.New("invalid empty backend")
}
if common.ValidateBackendResource(backend.Resource) && wrapper.AnnotationsConfig.Destination != nil {
for _, dest := range wrapper.AnnotationsConfig.Destination.McpDestination {
serviceKey := common.ServiceKey{
Namespace: "mcp",
Name: dest.Destination.Host,
ServiceFQDN: dest.Destination.Host,
}
if _, exist := store[serviceKey]; !exist {
store[serviceKey] = &common.WrapperTrafficPolicy{
TrafficPolicy: &networking.TrafficPolicy{},
WrapperConfig: wrapper,
}
}
}
} else {
if backend.Service == nil {
return nil
}
serviceKey, err := c.createServiceKey(backend.Service, wrapper.Config.Namespace)
if err != nil {
return fmt.Errorf("ignore service %s within ingress %s/%s", serviceKey.Name, wrapper.Config.Namespace, wrapper.Config.Name)
}
if _, exist := store[serviceKey]; !exist {
store[serviceKey] = &common.WrapperTrafficPolicy{
PortTrafficPolicy: &networking.TrafficPolicy_PortTrafficPolicy{
Port: &networking.PortSelector{ Port: &networking.PortSelector{
Number: uint32(serviceKey.Port), Number: uint32(serviceKey.Port),
}, },
@@ -895,7 +908,6 @@ func (c *controller) ConvertTrafficPolicy(convertOptions *common.ConvertOptions,
} }
} }
} }
return nil return nil
} }