Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize GlobalTrafficPolicy fetching and endpoint generation time #206

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
d457913
Bootstrapping admiral
aattuluri Sep 19, 2019
7b9a2ff
Add circle ci config
aattuluri Sep 19, 2019
c9e80a5
Fix the working directory for builds
aattuluri Sep 19, 2019
76b9561
Bootstrapping admiral
aattuluri Sep 19, 2019
85aeeaa
Add circle ci config
aattuluri Sep 19, 2019
fe313cc
Fix the working directory for builds
aattuluri Sep 19, 2019
306ad93
Merge branch 'master' of https://github.com/aattuluri/admiral
aattuluri Sep 19, 2019
a9fa409
Add build status badge.
aattuluri Sep 19, 2019
4ae717d
Revert "Add build status badge."
aattuluri Sep 19, 2019
ff09cfb
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 19, 2019
eb51849
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 20, 2019
928c0d2
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 20, 2019
2fb3364
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 23, 2019
ea3ed61
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 23, 2019
15e7845
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 24, 2019
3b34036
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 29, 2019
656bf71
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 29, 2019
0245314
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 29, 2019
111c3de
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 4, 2019
e39651c
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 4, 2019
b280c0b
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 6, 2019
4b74679
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 16, 2019
09b8a5b
Merge remote-tracking branch 'upstream/master'
aattuluri Oct 30, 2019
6546170
Merge remote-tracking branch 'upstream/master'
aattuluri Dec 27, 2019
1b0dfeb
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 2, 2020
9b0010b
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 9, 2020
7b68379
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 21, 2020
5ae2f4c
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 24, 2020
6e297db
Publish images: i) latest from master, ii) TAG if its set and iii) co…
aattuluri Jan 24, 2020
d6674b9
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 19, 2020
e45ef03
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 26, 2020
9096f16
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 27, 2020
1e7a3d5
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 8, 2020
a9e55b3
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 20, 2020
c40a8be
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 27, 2020
798b06a
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 6, 2020
f028e1e
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 16, 2020
0956d03
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 27, 2020
cecd2ca
Merge remote-tracking branch 'upstream/master'
aattuluri May 13, 2020
b46682c
Merge remote-tracking branch 'upstream/master'
aattuluri May 14, 2020
2d3460c
Merge remote-tracking branch 'upstream/master'
aattuluri May 26, 2020
77c46e0
Merge remote-tracking branch 'upstream/master'
aattuluri Jun 15, 2020
82a4223
Merge remote-tracking branch 'upstream/master'
aattuluri Jul 24, 2020
065b6d4
Merge remote-tracking branch 'upstream/master'
aattuluri Aug 26, 2020
933650b
Merge remote-tracking branch 'upstream/master'
aattuluri Sep 20, 2020
d2e76cb
Merge remote-tracking branch 'upstream/master'
aattuluri Nov 2, 2020
63b4c60
Merge remote-tracking branch 'upstream/master'
aattuluri Nov 6, 2020
7b6626f
Merge remote-tracking branch 'upstream/master'
aattuluri Nov 12, 2020
0631dce
Merge remote-tracking branch 'upstream/master'
aattuluri Nov 13, 2020
51a27da
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 21, 2021
8683c4e
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 23, 2021
e05e909
Merge remote-tracking branch 'upstream/master'
aattuluri Jun 3, 2021
85a586e
Merge remote-tracking branch 'upstream/master'
aattuluri Jan 30, 2022
5a3d36f
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 4, 2022
0f387e1
Merge remote-tracking branch 'upstream/master'
aattuluri Feb 10, 2022
cf0996e
Do not do destructive updates during bootup time
aattuluri Feb 10, 2022
accf659
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 2, 2022
0ef1a24
Merge remote-tracking branch 'upstream/master'
aattuluri Mar 22, 2022
f85d4b0
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 8, 2022
a9b8aee
Merge remote-tracking branch 'upstream/master'
aattuluri Apr 12, 2022
2cc69e7
Add GTP cache
aattuluri Apr 18, 2022
99cb02f
Merge remote-tracking branch 'upstream/master' into Optimize-gtp-fetc…
aattuluri Apr 18, 2022
9b2c91c
Code to refactor GTP usage
aattuluri Apr 19, 2022
96f1db8
Add tests
aattuluri Apr 19, 2022
f289e80
Fix tests and lint errors
aattuluri Apr 19, 2022
7500da0
Remove GTP handler as we no longer handle GTP updates beyond caching
aattuluri Apr 19, 2022
66a411d
Remove test which has now moved to GlobalTrafficController
aattuluri Apr 19, 2022
b15a99b
Also use gtp selector
aattuluri Apr 22, 2022
3eb966a
Address review comments
aattuluri May 2, 2022
8348e42
Address review comments
aattuluri May 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
.idea/vcs.xml

out*
*.tar.gz
*.tar.gz
*.out
4 changes: 0 additions & 4 deletions admiral/pkg/clusters/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import (
"fmt"
"github.com/istio-ecosystem/admiral/admiral/pkg/apis/admiral/v1"
"github.com/istio-ecosystem/admiral/admiral/pkg/controller/istio"
v12 "k8s.io/api/apps/v1"
"k8s.io/client-go/rest"
"sync"
"time"

argo "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1"
"github.com/istio-ecosystem/admiral/admiral/pkg/controller/admiral"
"github.com/istio-ecosystem/admiral/admiral/pkg/controller/common"
"github.com/istio-ecosystem/admiral/admiral/pkg/controller/secret"
Expand Down Expand Up @@ -46,8 +44,6 @@ func InitAdmiral(ctx context.Context, params common.AdmiralParams) (*RemoteRegis

gtpCache := &globalTrafficCache{}
gtpCache.identityCache = make(map[string]*v1.GlobalTrafficPolicy)
gtpCache.dependencyCache = make(map[string]*v12.Deployment)
gtpCache.dependencyRolloutCache = make(map[string]*argo.Rollout)
gtpCache.mutex = &sync.Mutex{}

w.AdmiralCache = &AdmiralCache{
Expand Down
32 changes: 0 additions & 32 deletions admiral/pkg/clusters/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,38 +312,6 @@ func TestAdded(t *testing.T) {

}

func TestPodHandler(t *testing.T) {

p := common.AdmiralParams{
KubeconfigPath: "testdata/fake.config",
}

rr, _ := InitAdmiral(context.Background(), p)

rc, _ := createMockRemoteController(func(i interface{}) {

})
rr.RemoteControllers["test.cluster"] = rc

ph := PodHandler{
RemoteRegistry: rr,
}

pod := k8sCoreV1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Namespace: "test",
},
Spec: k8sCoreV1.PodSpec{
Hostname: "test.local",
},
}

ph.Added(&pod)

ph.Deleted(&pod)
}

func TestGetServiceForDeployment(t *testing.T) {
baseRc, _ := createMockRemoteController(func(i interface{}) {
//res := i.(istio.Config)
Expand Down
50 changes: 48 additions & 2 deletions admiral/pkg/clusters/serviceentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"math"
"math/rand"
"reflect"
"sort"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -70,6 +71,11 @@ func modifyServiceEntryForNewServiceOrPod(event admiral.EventType, env string, s
var serviceInstance *k8sV1.Service
var weightedServices map[string]*WeightedService
var rollout *admiral.RolloutClusterEntry
var gtps = make(map[string][]*v1.GlobalTrafficPolicy)

var namespace string

var gtpKey = common.ConstructGtpKey(sourceIdentity, env)

start := time.Now()
for _, rc := range remoteRegistry.RemoteControllers {
Expand All @@ -87,7 +93,7 @@ func modifyServiceEntryForNewServiceOrPod(event admiral.EventType, env string, s
if serviceInstance == nil {
continue
}

namespace = deploymentInstance.Namespace
localMeshPorts := GetMeshPorts(rc.ClusterID, serviceInstance, deploymentInstance)

cname = common.GetCname(deploymentInstance, common.GetWorkloadIdentifier(), common.GetHostnameSuffix())
Expand All @@ -106,7 +112,7 @@ func modifyServiceEntryForNewServiceOrPod(event admiral.EventType, env string, s
serviceInstance = sInstance.Service
break
}

namespace = rolloutInstance.Namespace
localMeshPorts := GetMeshPortsForRollout(rc.ClusterID, serviceInstance, rolloutInstance)

cname = common.GetCnameForRollout(rolloutInstance, common.GetWorkloadIdentifier(), common.GetHostnameSuffix())
Expand All @@ -117,6 +123,11 @@ func modifyServiceEntryForNewServiceOrPod(event admiral.EventType, env string, s
continue
}

gtpsInNamespace := rc.GlobalTraffic.Cache.Get(gtpKey, namespace)
if len(gtps) > 0 {
gtps[rc.ClusterID] = gtpsInNamespace
}

remoteRegistry.AdmiralCache.IdentityClusterCache.Put(sourceIdentity, rc.ClusterID, rc.ClusterID)
remoteRegistry.AdmiralCache.CnameClusterCache.Put(cname, rc.ClusterID, rc.ClusterID)
remoteRegistry.AdmiralCache.CnameIdentityCache.Store(cname, sourceIdentity)
Expand All @@ -126,6 +137,9 @@ func modifyServiceEntryForNewServiceOrPod(event admiral.EventType, env string, s

util.LogElapsedTimeSince("BuildServiceEntry", sourceIdentity, env, "", start)

//cache the latest GTP in global cache to be reused during DR creation
updateGlobalGtpCache(remoteRegistry.AdmiralCache, sourceIdentity, env, gtps)

dependents := remoteRegistry.AdmiralCache.IdentityDependencyCache.Get(sourceIdentity).Copy()

//handle local updates (source clusters first)
Expand Down Expand Up @@ -219,6 +233,38 @@ func modifyServiceEntryForNewServiceOrPod(event admiral.EventType, env string, s
return serviceEntries
}

//Does two things;
//i) Picks the GTP that was created most recently from the passed in GTP list (GTPs from all clusters)
//ii) Updates the global GTP cache with the selected GTP in i)
func updateGlobalGtpCache(cache *AdmiralCache, identity, env string, gtps map[string][]*v1.GlobalTrafficPolicy) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comments for this method

defer util.LogElapsedTime("updateGlobalGtpCache", identity, env, "")()
gtpsOrdered := make([]*v1.GlobalTrafficPolicy, 0)
for _, gtpsInCluster := range gtps {
gtpsOrdered = append(gtpsOrdered, gtpsInCluster...)
}
if len(gtpsOrdered) == 0 {
cache.GlobalTrafficCache.Delete(env, identity)
return
} else if len(gtpsOrdered) > 1 {
//sort by creation time with most recent at the beginning
sort.Slice(gtpsOrdered, func(i, j int) bool {
iTime := gtpsOrdered[i].CreationTimestamp.Nanosecond()
jTime := gtpsOrdered[j].CreationTimestamp.Nanosecond()
return iTime > jTime
})
}

mostRecentGtp := gtpsOrdered[0]

err := cache.GlobalTrafficCache.Put(mostRecentGtp)

if err != nil {
log.Errorf("Error in updating GTP with name=%s in namespace=%s as actively used for identity=%s with err=%v", mostRecentGtp.Name, mostRecentGtp.Namespace, common.GetGtpKey(mostRecentGtp), err)
} else {
log.Infof("GTP with name=%s in namespace=%s is actively used for identity=%s", mostRecentGtp.Name, mostRecentGtp.Namespace, common.GetGtpKey(mostRecentGtp))
}
}

func updateEndpointsForBlueGreen(rollout *argo.Rollout, weightedServices map[string]*WeightedService, cnames map[string]string,
ep *networking.ServiceEntry_Endpoint, sourceCluster string, meshHost string) {
activeServiceName := rollout.Spec.Strategy.BlueGreen.ActiveService
Expand Down
76 changes: 75 additions & 1 deletion admiral/pkg/clusters/serviceentry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ func TestAddServiceEntriesWithDr(t *testing.T) {

gtpCache := &globalTrafficCache{}
gtpCache.identityCache = make(map[string]*v13.GlobalTrafficPolicy)
gtpCache.dependencyCache = make(map[string]*v14.Deployment)
gtpCache.mutex = &sync.Mutex{}
admiralCache.GlobalTrafficCache = gtpCache

Expand Down Expand Up @@ -890,6 +889,8 @@ func TestCreateServiceEntryForNewServiceOrPodRolloutsUsecase(t *testing.T) {
}
s, e := admiral.NewServiceController(make(chan struct{}), &test.MockServiceHandler{}, &config, time.Second*time.Duration(300))

gtpc, e := admiral.NewGlobalTrafficController(make(chan struct{}), &test.MockGlobalTrafficHandler{}, &config, time.Second*time.Duration(300))

cacheWithEntry := ServiceEntryAddressStore{
EntryAddresses: map[string]string{"test.test.mesh-se": common.LocalAddressPrefix + ".10.1"},
Addresses: []string{common.LocalAddressPrefix + ".10.1"},
Expand All @@ -912,6 +913,7 @@ func TestCreateServiceEntryForNewServiceOrPodRolloutsUsecase(t *testing.T) {
RolloutController: r,
ServiceController: s,
VirtualServiceController: v,
GlobalTraffic: gtpc,
}
rc.ClusterID = "test.cluster"
rr.RemoteControllers["test.cluster"] = rc
Expand Down Expand Up @@ -1019,6 +1021,7 @@ func TestCreateServiceEntryForBlueGreenRolloutsUsecase(t *testing.T) {
t.Fail()
}
s, e := admiral.NewServiceController(make(chan struct{}), &test.MockServiceHandler{}, &config, time.Second*time.Duration(300))
gtpc, e := admiral.NewGlobalTrafficController(make(chan struct{}), &test.MockGlobalTrafficHandler{}, &config, time.Second*time.Duration(300))

cacheWithEntry := ServiceEntryAddressStore{
EntryAddresses: map[string]string{
Expand All @@ -1045,6 +1048,7 @@ func TestCreateServiceEntryForBlueGreenRolloutsUsecase(t *testing.T) {
RolloutController: r,
ServiceController: s,
VirtualServiceController: v,
GlobalTraffic: gtpc,
}
rc.ClusterID = "test.cluster"
rr.RemoteControllers["test.cluster"] = rc
Expand Down Expand Up @@ -1331,6 +1335,76 @@ func TestUpdateEndpointsForWeightedServices(t *testing.T) {

}

func TestUpdateGlobalGtpCache(t *testing.T) {

var (
admiralCache = &AdmiralCache{GlobalTrafficCache: &globalTrafficCache{identityCache: make(map[string]*v13.GlobalTrafficPolicy), mutex: &sync.Mutex{}}}

identity1 = "identity1"

env_stage = "stage"

gtp = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-30))), Labels: map[string]string{"identity": identity1, "env": env_stage}}, Spec: model.GlobalTrafficPolicy{
Policy: []*model.TrafficPolicy {{DnsPrefix: "hello"}},
},}

gtp2 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp2", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-15))), Labels: map[string]string{"identity": identity1, "env": env_stage}}, Spec: model.GlobalTrafficPolicy{
Policy: []*model.TrafficPolicy {{DnsPrefix: "hellogtp2"}},
},}

gtp3 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp3", Namespace: "namespace2", CreationTimestamp: v12.NewTime(time.Now()), Labels: map[string]string{"identity": identity1, "env": env_stage}}, Spec: model.GlobalTrafficPolicy{
Policy: []*model.TrafficPolicy {{DnsPrefix: "hellogtp3"}},
},}

)

testCases := []struct {
name string
identity string
env string
gtps map[string][]*v13.GlobalTrafficPolicy
expectedGtp *v13.GlobalTrafficPolicy
}{ {
name: "Should return nil when no GTP present",
gtps: map[string][]*v13.GlobalTrafficPolicy{},
identity: identity1,
env: env_stage,
expectedGtp: nil,
},
{
name: "Should return the only existing gtp",
gtps: map[string][]*v13.GlobalTrafficPolicy{"c1": {gtp}},
identity: identity1,
env: env_stage,
expectedGtp: gtp,
},
{
name: "Should return the gtp recently created within the cluster",
gtps: map[string][]*v13.GlobalTrafficPolicy{"c1": {gtp, gtp2}},
identity: identity1,
env: env_stage,
expectedGtp: gtp2,
},
{
name: "Should return the gtp recently created from another cluster",
gtps: map[string][]*v13.GlobalTrafficPolicy{"c1": {gtp, gtp2}, "c2": {gtp3}},
identity: identity1,
env: env_stage,
expectedGtp: gtp3,
},
}

for _, c := range testCases {
t.Run(c.name, func(t *testing.T) {
updateGlobalGtpCache(admiralCache, c.identity, c.env, c.gtps)
gtp := admiralCache.GlobalTrafficCache.GetFromIdentity(c.identity, c.env)
if !reflect.DeepEqual(c.expectedGtp, gtp) {
t.Errorf("Test %s failed expected gtp: %v got %v", c.name, c.expectedGtp, gtp)
}
})
}
}

func isLower(s string) bool {
for _, r := range s {
if !unicode.IsLower(r) && unicode.IsLetter(r) {
Expand Down
Loading