Skip to content

Commit

Permalink
istio: avoid copy virtual services for sidecar scope calculation
Browse files Browse the repository at this point in the history
This CL patches commit e40f57e from
upstream istio into air-release-1.14.4 to improve propagation delay.

Original PR:
istio#41101

Change-Id: I7b0da42f591a6da9e20342235ccbf93f2741132b
Reviewed-on: https://gerrit.musta.ch/c/public/istio/+/3822
Reviewed-by: Weibo He <weibo.he@airbnb.com>
  • Loading branch information
ying-zhu committed Oct 4, 2022
1 parent ea641c7 commit 6215efe
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 20 deletions.
5 changes: 5 additions & 0 deletions pilot/pkg/model/push_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,11 @@ func (ps *PushContext) IsServiceVisible(service *Service, namespace string) bool
// VirtualServicesForGateway lists all virtual services bound to the specified gateways
// This replaces store.VirtualServices. Used only by the gateways
// Sidecars use the egressListener.VirtualServices().
//
// Note that for generating the imported virtual services of sidecar egress
// listener, we don't call this function to copy configs for performance issues.
// Instead, we pass the virtualServiceIndex directly into SelectVirtualServices
// function.
func (ps *PushContext) VirtualServicesForGateway(proxyNamespace, gateway string) []config.Config {
res := make([]config.Config, 0, len(ps.virtualServiceIndex.privateByNamespaceAndGateway[proxyNamespace][gateway])+
len(ps.virtualServiceIndex.exportedToNamespaceByGateway[proxyNamespace][gateway])+
Expand Down
3 changes: 1 addition & 2 deletions pilot/pkg/model/sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,7 @@ func convertIstioListenerToWrapper(ps *PushContext, configNamespace string,
out.listenerHosts[parts[0]] = append(out.listenerHosts[parts[0]], host.Name(parts[1]))
}

vses := ps.VirtualServicesForGateway(configNamespace, constants.IstioMeshGateway)
out.virtualServices = SelectVirtualServices(vses, out.listenerHosts)
out.virtualServices = SelectVirtualServices(ps.virtualServiceIndex, configNamespace, out.listenerHosts)
svces := ps.servicesExportedToNamespace(configNamespace)
out.services = out.selectServices(svces, configNamespace, out.listenerHosts)

Expand Down
37 changes: 22 additions & 15 deletions pilot/pkg/model/virtualservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ import (
)

// SelectVirtualServices selects the virtual services by matching given services' host names.
// This is a common function used by both sidecar converter and http route.
func SelectVirtualServices(virtualServices []config.Config, hosts map[string][]host.Name) []config.Config {
// This function is used by sidecar converter.
func SelectVirtualServices(vsidx virtualServiceIndex, configNamespace string, hosts map[string][]host.Name) []config.Config {
importedVirtualServices := make([]config.Config, 0)

vsset := sets.New()
Expand All @@ -54,24 +54,31 @@ func SelectVirtualServices(virtualServices []config.Config, hosts map[string][]h
}
}
}
for _, c := range virtualServices {
configNamespace := c.Namespace
// Selection algorithm:
// virtualservices have a list of hosts in the API spec
// if any host in the list matches one service hostname, select the virtual service
// and break out of the loop.

// Check if there is an explicit import of form ns/* or ns/host
if importedHosts, nsFound := hosts[configNamespace]; nsFound {
addVirtualService(c, importedHosts)
}
loopAndAdd := func(vses []config.Config) {
for _, c := range vses {
configNamespace := c.Namespace
// Selection algorithm:
// virtualservices have a list of hosts in the API spec
// if any host in the list matches one service hostname, select the virtual service
// and break out of the loop.

// Check if there is an explicit import of form ns/* or ns/host
if importedHosts, nsFound := hosts[configNamespace]; nsFound {
addVirtualService(c, importedHosts)
}

// Check if there is an import of form */host or */*
if importedHosts, wnsFound := hosts[wildcardNamespace]; wnsFound {
addVirtualService(c, importedHosts)
// Check if there is an import of form */host or */*
if importedHosts, wnsFound := hosts[wildcardNamespace]; wnsFound {
addVirtualService(c, importedHosts)
}
}
}

loopAndAdd(vsidx.privateByNamespaceAndGateway[configNamespace][constants.IstioMeshGateway])
loopAndAdd(vsidx.exportedToNamespaceByGateway[configNamespace][constants.IstioMeshGateway])
loopAndAdd(vsidx.publicByGateway[constants.IstioMeshGateway])

return importedVirtualServices
}

Expand Down
20 changes: 17 additions & 3 deletions pilot/pkg/model/virtualservice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
networking "istio.io/api/networking/v1alpha3"
"istio.io/istio/pilot/pkg/serviceregistry/provider"
"istio.io/istio/pkg/config"
"istio.io/istio/pkg/config/constants"
"istio.io/istio/pkg/config/host"
"istio.io/istio/pkg/config/protocol"
"istio.io/istio/pkg/config/schema/collections"
Expand Down Expand Up @@ -2035,9 +2036,22 @@ func TestSelectVirtualService(t *testing.T) {
},
Spec: virtualServiceSpec7,
}
configs := SelectVirtualServices(
[]config.Config{virtualService1, virtualService2, virtualService3, virtualService4, virtualService5, virtualService6, virtualService7},
hostsByNamespace)

index := virtualServiceIndex{
publicByGateway: map[string][]config.Config{
constants.IstioMeshGateway: {
virtualService1,
virtualService2,
virtualService3,
virtualService4,
virtualService5,
virtualService6,
virtualService7,
},
},
}

configs := SelectVirtualServices(index, "some-ns", hostsByNamespace)
expectedVS := []string{virtualService1.Name, virtualService2.Name, virtualService4.Name, virtualService7.Name}
if len(expectedVS) != len(configs) {
t.Fatalf("Unexpected virtualService, got %d, epxected %d", len(configs), len(expectedVS))
Expand Down

0 comments on commit 6215efe

Please sign in to comment.