Repository: spidernet-io/spiderpool
Pull request #1418 (2023-03-08 15:16:54)

feat: Use `spec.default` to make the cluster default IPPools effective instead of configuring Comfigmap spiderpool-conf
- API readers are provided for each resource manager to query the latest data from the API Server.
- Modify the unit tests of most resource managers and provide fake tracker to fill data for fake API reader.
- Based on the current ability to query the cache or API Server on demand, adjust some API requests in IPAM and webhook to use the cache as much as possible to speed up the whole process.

Signed-off-by: iiiceoo <ziqian.xue@daocloud.io>

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1418)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1418) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1418&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1418)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1418) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1418&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=spidernet-io_spiderpool&pullRequest=1418)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=spidernet-io_spiderpool&pullRequest=1418&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1418) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=spidernet-io_spiderpool&pullRequest=1418&metric=duplicated_lines_density&view=list) No Duplication information



Patch:
diff --git a/charts/spiderpool/crds/spiderpool.spidernet.io_spiderendpoints.yaml b/charts/spiderpool/crds/spiderpool.spidernet.io_spiderendpoints.yaml
index ea376f85e..45cae75b1 100644
--- a/charts/spiderpool/crds/spiderpool.spidernet.io_spiderendpoints.yaml
+++ b/charts/spiderpool/crds/spiderpool.spidernet.io_spiderendpoints.yaml
@@ -45,7 +45,7 @@ spec:
       name: NODE
       type: string
     - description: creationTime
-      jsonPath: .status.current.creationTime
+      jsonPath: .status.creationTime
       name: CREATETION TIME
       type: date
     name: v1
diff --git a/charts/spiderpool/templates/configmap.yaml b/charts/spiderpool/templates/configmap.yaml
index c9f9077ee..a3b23f90a 100644
--- a/charts/spiderpool/templates/configmap.yaml
+++ b/charts/spiderpool/templates/configmap.yaml
@@ -20,28 +20,3 @@ data:
     enableIPv6: {{ .Values.feature.enableIPv6 }}
     enableStatefulSet: {{ .Values.feature.enableStatefulSet }}
     enableSpiderSubnet: {{ .Values.feature.enableSpiderSubnet }}
-    {{- if ( and .Values.feature.enableIPv4 .Values.clusterDefaultPool.installIPv4IPPool ) }}
-    clusterDefaultIPv4IPPool: [{{ .Values.clusterDefaultPool.ipv4IPPoolName }}]
-    {{- else}}
-    clusterDefaultIPv4IPPool: []
-    {{- end }}
-    {{- if ( and .Values.feature.enableIPv6 .Values.clusterDefaultPool.installIPv6IPPool ) }}
-    clusterDefaultIPv6IPPool: [{{ .Values.clusterDefaultPool.ipv6IPPoolName }}]
-    {{- else}}
-    clusterDefaultIPv6IPPool: []
-    {{- end }}
-    {{- if ( and .Values.feature.enableSpiderSubnet .Values.feature.enableIPv4 ) }}
-    clusterDefaultIPv4Subnet: [{{ .Values.clusterDefaultPool.ipv4SubnetName }}]
-    {{- else}}
-    clusterDefaultIPv4Subnet: []
-    {{- end}}
-    {{- if ( and .Values.feature.enableSpiderSubnet .Values.feature.enableIPv6 )}}
-    clusterDefaultIPv6Subnet: [{{ .Values.clusterDefaultPool.ipv6SubnetName }}]
-    {{- else}}
-    clusterDefaultIPv6Subnet: []
-    {{- end }}
-    {{- if .Values.feature.enableSpiderSubnet }}
-    clusterSubnetDefaultFlexibleIPNumber: {{ .Values.clusterDefaultPool.subnetDefaultFlexibleIPNumber }}
-    {{- else}}
-    clusterSubnetDefaultFlexibleIPNumber: 0
-    {{- end }}
\ No newline at end of file
diff --git a/charts/spiderpool/values.yaml b/charts/spiderpool/values.yaml
index 69ce14cc8..ce4b5aee5 100644
--- a/charts/spiderpool/values.yaml
+++ b/charts/spiderpool/values.yaml
@@ -103,9 +103,6 @@ clusterDefaultPool:
   ## @param clusterDefaultPool.ipv6Gateway the gateway of ipv6 subnet
   ipv6Gateway: ""
 
-  ## @param clusterDefaultPool.subnetDefaultFlexibleIPNumber the default flexible IP number of SpiderSubnet feature auto-created IPPools
-  subnetDefaultFlexibleIPNumber: 1
-
 ## @section spiderpoolAgent parameters
 ##
 spiderpoolAgent:
diff --git a/cmd/spiderpool-agent/cmd/crd_manager.go b/cmd/spiderpool-agent/cmd/crd_manager.go
index ead35e7c4..c06004b58 100644
--- a/cmd/spiderpool-agent/cmd/crd_manager.go
+++ b/cmd/spiderpool-agent/cmd/crd_manager.go
@@ -6,7 +6,6 @@ package cmd
 import (
 	"strconv"
 
-	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
@@ -32,17 +31,25 @@ func newCRDManager() (ctrl.Manager, error) {
 		Scheme:                 scheme,
 		MetricsBindAddress:     "0",
 		HealthProbeBindAddress: "0",
-		ClientDisableCacheFor: []client.Object{
-			&spiderpoolv1.SpiderSubnet{},
-			&spiderpoolv1.SpiderIPPool{},
-			&spiderpoolv1.SpiderEndpoint{},
-			&corev1.Pod{},
-		},
 	})
 	if err != nil {
 		return nil, err
 	}
 
+	if err := mgr.GetFieldIndexer().IndexField(agentContext.InnerCtx, &spiderpoolv1.SpiderSubnet{}, "spec.default", func(raw client.Object) []string {
+		subnet := raw.(*spiderpoolv1.SpiderSubnet)
+		return []string{strconv.FormatBool(*subnet.Spec.Default)}
+	}); err != nil {
+		return nil, err
+	}
+
+	if err := mgr.GetFieldIndexer().IndexField(agentContext.InnerCtx, &spiderpoolv1.SpiderIPPool{}, "spec.default", func(raw client.Object) []string {
+		ipPool := raw.(*spiderpoolv1.SpiderIPPool)
+		return []string{strconv.FormatBool(*ipPool.Spec.Default)}
+	}); err != nil {
+		return nil, err
+	}
+
 	if err := mgr.GetFieldIndexer().IndexField(agentContext.InnerCtx, &spiderpoolv1.SpiderReservedIP{}, "spec.ipVersion", func(raw client.Object) []string {
 		reservedIP := raw.(*spiderpoolv1.SpiderReservedIP)
 		return []string{strconv.FormatInt(*reservedIP.Spec.IPVersion, 10)}
diff --git a/cmd/spiderpool-agent/cmd/daemon.go b/cmd/spiderpool-agent/cmd/daemon.go
index d5237ef16..c255c952f 100644
--- a/cmd/spiderpool-agent/cmd/daemon.go
+++ b/cmd/spiderpool-agent/cmd/daemon.go
@@ -245,14 +245,20 @@ func WatchSignal(sigCh chan os.Signal) {
 
 func initAgentServiceManagers(ctx context.Context) {
 	logger.Debug("Begin to initialize Node manager")
-	nodeManager, err := nodemanager.NewNodeManager(agentContext.CRDManager.GetClient())
+	nodeManager, err := nodemanager.NewNodeManager(
+		agentContext.CRDManager.GetClient(),
+		agentContext.CRDManager.GetAPIReader(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
 	agentContext.NodeManager = nodeManager
 
 	logger.Debug("Begin to initialize Namespace manager")
-	nsManager, err := namespacemanager.NewNamespaceManager(agentContext.CRDManager.GetClient())
+	nsManager, err := namespacemanager.NewNamespaceManager(
+		agentContext.CRDManager.GetClient(),
+		agentContext.CRDManager.GetAPIReader(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
@@ -260,11 +266,8 @@ func initAgentServiceManagers(ctx context.Context) {
 
 	logger.Debug("Begin to initialize Pod manager")
 	podManager, err := podmanager.NewPodManager(
-		podmanager.PodManagerConfig{
-			MaxConflictRetries:    agentContext.Cfg.UpdateCRMaxRetries,
-			ConflictRetryUnitTime: time.Duration(agentContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
-		},
 		agentContext.CRDManager.GetClient(),
+		agentContext.CRDManager.GetAPIReader(),
 	)
 	if err != nil {
 		logger.Fatal(err.Error())
@@ -272,7 +275,10 @@ func initAgentServiceManagers(ctx context.Context) {
 	agentContext.PodManager = podManager
 
 	logger.Debug("Begin to initialize StatefulSet manager")
-	statefulSetManager, err := statefulsetmanager.NewStatefulSetManager(agentContext.CRDManager.GetClient())
+	statefulSetManager, err := statefulsetmanager.NewStatefulSetManager(
+		agentContext.CRDManager.GetClient(),
+		agentContext.CRDManager.GetAPIReader(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
@@ -285,6 +291,7 @@ func initAgentServiceManagers(ctx context.Context) {
 			ConflictRetryUnitTime: time.Duration(agentContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
 		},
 		agentContext.CRDManager.GetClient(),
+		agentContext.CRDManager.GetAPIReader(),
 	)
 	if err != nil {
 		logger.Fatal(err.Error())
@@ -292,7 +299,10 @@ func initAgentServiceManagers(ctx context.Context) {
 	agentContext.EndpointManager = endpointManager
 
 	logger.Debug("Begin to initialize ReservedIP manager")
-	rIPManager, err := reservedipmanager.NewReservedIPManager(agentContext.CRDManager.GetClient())
+	rIPManager, err := reservedipmanager.NewReservedIPManager(
+		agentContext.CRDManager.GetClient(),
+		agentContext.CRDManager.GetAPIReader(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
@@ -306,6 +316,7 @@ func initAgentServiceManagers(ctx context.Context) {
 			MaxAllocatedIPs:       &agentContext.Cfg.IPPoolMaxAllocatedIPs,
 		},
 		agentContext.CRDManager.GetClient(),
+		agentContext.CRDManager.GetAPIReader(),
 		agentContext.RIPManager,
 	)
 	if err != nil {
@@ -321,8 +332,8 @@ func initAgentServiceManagers(ctx context.Context) {
 				ConflictRetryUnitTime: time.Duration(agentContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
 			},
 			agentContext.CRDManager.GetClient(),
+			agentContext.CRDManager.GetAPIReader(),
 			agentContext.IPPoolManager,
-			agentContext.CRDManager.GetScheme(),
 		)
 		if err != nil {
 			logger.Fatal(err.Error())
diff --git a/cmd/spiderpool-controller/cmd/crd_manager.go b/cmd/spiderpool-controller/cmd/crd_manager.go
index 04ca948ba..82d3a8556 100644
--- a/cmd/spiderpool-controller/cmd/crd_manager.go
+++ b/cmd/spiderpool-controller/cmd/crd_manager.go
@@ -10,7 +10,6 @@ import (
 	"path"
 	"strconv"
 
-	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
@@ -43,17 +42,25 @@ func newCRDManager() (ctrl.Manager, error) {
 		CertDir:                path.Dir(controllerContext.Cfg.TlsServerCertPath),
 		MetricsBindAddress:     "0",
 		HealthProbeBindAddress: "0",
-		ClientDisableCacheFor: []client.Object{
-			&spiderpoolv1.SpiderSubnet{},
-			&spiderpoolv1.SpiderIPPool{},
-			&spiderpoolv1.SpiderEndpoint{},
-			&corev1.Pod{},
-		},
 	})
 	if err != nil {
 		return nil, err
 	}
 
+	if err := mgr.GetFieldIndexer().IndexField(controllerContext.InnerCtx, &spiderpoolv1.SpiderSubnet{}, "spec.default", func(raw client.Object) []string {
+		subnet := raw.(*spiderpoolv1.SpiderSubnet)
+		return []string{strconv.FormatBool(*subnet.Spec.Default)}
+	}); err != nil {
+		return nil, err
+	}
+
+	if err := mgr.GetFieldIndexer().IndexField(controllerContext.InnerCtx, &spiderpoolv1.SpiderIPPool{}, "spec.default", func(raw client.Object) []string {
+		ipPool := raw.(*spiderpoolv1.SpiderIPPool)
+		return []string{strconv.FormatBool(*ipPool.Spec.Default)}
+	}); err != nil {
+		return nil, err
+	}
+
 	if err := mgr.GetFieldIndexer().IndexField(controllerContext.InnerCtx, &spiderpoolv1.SpiderReservedIP{}, "spec.ipVersion", func(raw client.Object) []string {
 		reservedIP := raw.(*spiderpoolv1.SpiderReservedIP)
 		return []string{strconv.FormatInt(*reservedIP.Spec.IPVersion, 10)}
diff --git a/cmd/spiderpool-controller/cmd/daemon.go b/cmd/spiderpool-controller/cmd/daemon.go
index 5717885f7..094bb045d 100644
--- a/cmd/spiderpool-controller/cmd/daemon.go
+++ b/cmd/spiderpool-controller/cmd/daemon.go
@@ -206,14 +206,20 @@ func initControllerServiceManagers(ctx context.Context) {
 	initSpiderControllerLeaderElect(controllerContext.InnerCtx)
 
 	logger.Debug("Begin to initialize Node manager")
-	nodeManager, err := nodemanager.NewNodeManager(controllerContext.CRDManager.GetClient())
+	nodeManager, err := nodemanager.NewNodeManager(
+		controllerContext.CRDManager.GetClient(),
+		controllerContext.CRDManager.GetAPIReader(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
 	controllerContext.NodeManager = nodeManager
 
 	logger.Debug("Begin to initialize Namespace manager")
-	nsManager, err := namespacemanager.NewNamespaceManager(controllerContext.CRDManager.GetClient())
+	nsManager, err := namespacemanager.NewNamespaceManager(
+		controllerContext.CRDManager.GetClient(),
+		controllerContext.CRDManager.GetAPIReader(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
@@ -221,11 +227,8 @@ func initControllerServiceManagers(ctx context.Context) {
 
 	logger.Debug("Begin to initialize Pod manager")
 	podManager, err := podmanager.NewPodManager(
-		podmanager.PodManagerConfig{
-			MaxConflictRetries:    controllerContext.Cfg.UpdateCRMaxRetries,
-			ConflictRetryUnitTime: time.Duration(controllerContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
-		},
 		controllerContext.CRDManager.GetClient(),
+		controllerContext.CRDManager.GetAPIReader(),
 	)
 	if err != nil {
 		logger.Fatal(err.Error())
@@ -233,7 +236,10 @@ func initControllerServiceManagers(ctx context.Context) {
 	controllerContext.PodManager = podManager
 
 	logger.Info("Begin to initialize StatefulSet manager")
-	statefulSetManager, err := statefulsetmanager.NewStatefulSetManager(controllerContext.CRDManager.GetClient())
+	statefulSetManager, err := statefulsetmanager.NewStatefulSetManager(
+		controllerContext.CRDManager.GetClient(),
+		controllerContext.CRDManager.GetAPIReader(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
@@ -246,6 +252,7 @@ func initControllerServiceManagers(ctx context.Context) {
 			ConflictRetryUnitTime: time.Duration(controllerContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
 		},
 		controllerContext.CRDManager.GetClient(),
+		controllerContext.CRDManager.GetAPIReader(),
 	)
 	if err != nil {
 		logger.Fatal(err.Error())
@@ -253,7 +260,10 @@ func initControllerServiceManagers(ctx context.Context) {
 	controllerContext.EndpointManager = endpointManager
 
 	logger.Debug("Begin to initialize ReservedIP manager")
-	rIPManager, err := reservedipmanager.NewReservedIPManager(controllerContext.CRDManager.GetClient())
+	rIPManager, err := reservedipmanager.NewReservedIPManager(
+		controllerContext.CRDManager.GetClient(),
+		controllerContext.CRDManager.GetAPIReader(),
+	)
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
@@ -261,7 +271,6 @@ func initControllerServiceManagers(ctx context.Context) {
 
 	logger.Debug("Begin to set up ReservedIP webhook")
 	if err := (&reservedipmanager.ReservedIPWebhook{
-		Client:     controllerContext.CRDManager.GetClient(),
 		EnableIPv4: controllerContext.Cfg.EnableIPv4,
 		EnableIPv6: controllerContext.Cfg.EnableIPv6,
 	}).SetupWebhookWithManager(controllerContext.CRDManager); err != nil {
@@ -276,6 +285,7 @@ func initControllerServiceManagers(ctx context.Context) {
 			MaxAllocatedIPs:       &controllerContext.Cfg.IPPoolMaxAllocatedIPs,
 		},
 		controllerContext.CRDManager.GetClient(),
+		controllerContext.CRDManager.GetAPIReader(),
 		controllerContext.RIPManager,
 	)
 	if err != nil {
@@ -286,7 +296,7 @@ func initControllerServiceManagers(ctx context.Context) {
 	logger.Debug("Begin to set up IPPool webhook")
 	if err := (&ippoolmanager.IPPoolWebhook{
 		Client:             controllerContext.CRDManager.GetClient(),
-		Scheme:             controllerContext.CRDManager.GetScheme(),
+		APIReader:          controllerContext.CRDManager.GetAPIReader(),
 		EnableIPv4:         controllerContext.Cfg.EnableIPv4,
 		EnableIPv6:         controllerContext.Cfg.EnableIPv6,
 		EnableSpiderSubnet: controllerContext.Cfg.EnableSpiderSubnet,
@@ -302,8 +312,8 @@ func initControllerServiceManagers(ctx context.Context) {
 				ConflictRetryUnitTime: time.Duration(controllerContext.Cfg.UpdateCRRetryUnitTime) * time.Millisecond,
 			},
 			controllerContext.CRDManager.GetClient(),
+			controllerContext.CRDManager.GetAPIReader(),
 			controllerContext.IPPoolManager,
-			controllerContext.CRDManager.GetScheme(),
 		)
 		if err != nil {
 			logger.Fatal(err.Error())
@@ -313,6 +323,7 @@ func initControllerServiceManagers(ctx context.Context) {
 		logger.Debug("Begin to set up Subnet webhook")
 		if err := (&subnetmanager.SubnetWebhook{
 			Client:     controllerContext.CRDManager.GetClient(),
+			APIReader:  controllerContext.CRDManager.GetAPIReader(),
 			EnableIPv4: controllerContext.Cfg.EnableIPv4,
 			EnableIPv6: controllerContext.Cfg.EnableIPv6,
 		}).SetupWebhookWithManager(controllerContext.CRDManager); err != nil {
@@ -416,7 +427,7 @@ func setupInformers() {
 		logger.Info("Begin to set up Subnet informer")
 		if err := (&subnetmanager.SubnetController{
 			Client:                  controllerContext.CRDManager.GetClient(),
-			Scheme:                  controllerContext.CRDManager.GetScheme(),
+			APIReader:               controllerContext.CRDManager.GetAPIReader(),
 			LeaderRetryElectGap:     time.Duration(controllerContext.Cfg.LeaseRetryGap) * time.Second,
 			ResyncPeriod:            time.Duration(controllerContext.Cfg.SubnetResyncPeriod) * time.Second,
 			SubnetControllerWorkers: controllerContext.Cfg.SubnetInformerWorkers,
diff --git a/cmd/spiderpool-init/cmd/root.go b/cmd/spiderpool-init/cmd/root.go
index a1a914e88..b3161e774 100644
--- a/cmd/spiderpool-init/cmd/root.go
+++ b/cmd/spiderpool-init/cmd/root.go
@@ -22,7 +22,7 @@ func Execute() {
 	logger = logutils.Logger.Named("Spiderpool-Init")
 
 	config := NewInitDefaultConfig()
-	clinet, err := NewCoreClient()
+	client, err := NewCoreClient()
 	if err != nil {
 		logger.Fatal(err.Error())
 	}
@@ -30,7 +30,7 @@ func Execute() {
 	ctx, cancel := context.WithTimeout(context.Background(), 300*time.Second)
 	defer cancel()
 
-	if err := clinet.WaitForEndpointReady(ctx, config.Namespace, config.ControllerName); err != nil {
+	if err := client.WaitForEndpointReady(ctx, config.Namespace, config.ControllerName); err != nil {
 		logger.Fatal(err.Error())
 	}
 
@@ -52,7 +52,7 @@ func Execute() {
 			subnet.Spec.Gateway = pointer.String(config.V4Gateway)
 		}
 
-		if err := clinet.WaitForSubnetCreated(ctx, subnet); err != nil {
+		if err := client.WaitForSubnetCreated(ctx, subnet); err != nil {
 			logger.Fatal(err.Error())
 		}
 	}
@@ -75,7 +75,7 @@ func Execute() {
 			subnet.Spec.Gateway = pointer.String(config.V6Gateway)
 		}
 
-		if err := clinet.WaitForSubnetCreated(ctx, subnet); err != nil {
+		if err := client.WaitForSubnetCreated(ctx, subnet); err != nil {
 			logger.Fatal(err.Error())
 		}
 	}
@@ -98,7 +98,7 @@ func Execute() {
 			ipPool.Spec.Gateway = pointer.String(config.V4Gateway)
 		}
 
-		if err := clinet.WaitForIPPoolCreated(ctx, ipPool); err != nil {
+		if err := client.WaitForIPPoolCreated(ctx, ipPool); err != nil {
 			logger.Fatal(err.Error())
 		}
 	}
@@ -121,7 +121,7 @@ func Execute() {
 			ipPool.Spec.Gateway = pointer.String(config.V6Gateway)
 		}
 
-		if err := clinet.WaitForIPPoolCreated(ctx, ipPool); err != nil {
+		if err := client.WaitForIPPoolCreated(ctx, ipPool); err != nil {
 			logger.Fatal(err.Error())
 		}
 	}
diff --git a/cmd/spiderpool/cmd/command_add.go b/cmd/spiderpool/cmd/command_add.go
index 804d7d80e..e59058b87 100644
--- a/cmd/spiderpool/cmd/command_add.go
+++ b/cmd/spiderpool/cmd/command_add.go
@@ -80,7 +80,7 @@ func CmdAdd(args *skel.CmdArgs) (err error) {
 
 	spiderpoolAgentAPI, err := cmd.NewAgentOpenAPIUnixClient(conf.IPAM.IPAMUnixSocketPath)
 	if nil != err {
-		err := fmt.Errorf("failed to create spiderpool-agent clinet: %v", err)
+		err := fmt.Errorf("failed to create spiderpool-agent client: %v", err)
 		logger.Error(err.Error())
 		return err
 	}
diff --git a/cmd/spiderpool/cmd/command_delete.go b/cmd/spiderpool/cmd/command_delete.go
index f581f149d..ec3487da4 100644
--- a/cmd/spiderpool/cmd/command_delete.go
+++ b/cmd/spiderpool/cmd/command_delete.go
@@ -76,7 +76,7 @@ func CmdDel(args *skel.CmdArgs) (err error) {
 
 	spiderpoolAgentAPI, err := cmd.NewAgentOpenAPIUnixClient(conf.IPAM.IPAMUnixSocketPath)
 	if nil != err {
-		err := fmt.Errorf("failed to create spiderpool-agent clinet: %v", err)
+		err := fmt.Errorf("failed to create spiderpool-agent client: %v", err)
 		logger.Error(err.Error())
 		return err
 	}
diff --git a/pkg/constant/k8s.go b/pkg/constant/k8s.go
index db41a7e73..cc6203f59 100644
--- a/pkg/constant/k8s.go
+++ b/pkg/constant/k8s.go
@@ -86,6 +86,11 @@ const (
 	KindSpiderReservedIP   = "SpiderReservedIP"
 )
 
+const (
+	UseCache    = true
+	IgnoreCache = false
+)
+
 const (
 	SpiderControllerElectorLockName = SpiderpoolController + "-" + resourcelock.LeasesResourceLock
 	QualifiedK8sObjNameFmt          = "[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*"
diff --git a/pkg/ipam/allocate.go b/pkg/ipam/allocate.go
index 83cc5759d..8c6477dce 100644
--- a/pkg/ipam/allocate.go
+++ b/pkg/ipam/allocate.go
@@ -31,7 +31,7 @@ func (i *ipam) Allocate(ctx context.Context, addArgs *models.IpamAddArgs) (*mode
 	logger := logutils.FromContext(ctx)
 	logger.Info("Start to allocate")
 
-	pod, err := i.podManager.GetPodByName(ctx, *addArgs.PodNamespace, *addArgs.PodName)
+	pod, err := i.podManager.GetPodByName(ctx, *addArgs.PodNamespace, *addArgs.PodName, constant.IgnoreCache)
 	if err != nil {
 		return nil, fmt.Errorf("failed to get Pod %s/%s: %v", *addArgs.PodNamespace, *addArgs.PodName, err)
 	}
@@ -47,12 +47,12 @@ func (i *ipam) Allocate(ctx context.Context, addArgs *models.IpamAddArgs) (*mode
 	}
 	logger.Sugar().Debugf("%s %s/%s is the top controller of the Pod", podTopController.Kind, podTopController.Namespace, podTopController.Name)
 
-	endpoint, err := i.endpointManager.GetEndpointByName(ctx, pod.Namespace, pod.Name)
+	endpoint, err := i.endpointManager.GetEndpointByName(ctx, pod.Namespace, pod.Name, constant.IgnoreCache)
 	if client.IgnoreNotFound(err) != nil {
 		return nil, fmt.Errorf("failed to get Endpoint %s/%s: %v", pod.Namespace, pod.Name, err)
 	}
 
-	if endpoint == nil {
+	if endpoint != nil {
 		logger.Sugar().Debugf("Get Endpoint %s/%s", pod.Namespace, pod.Name)
 	} else {
 		logger.Debug("No Endpoint")
@@ -68,10 +68,10 @@ func (i *ipam) Allocate(ctx context.Context, addArgs *models.IpamAddArgs) (*mode
 			return addResp, nil
 		}
 	} else {
-		logger.Debug("Try to retrieve the existing IP allocation in multi-NIC mode")
+		logger.Debug("Try to retrieve the existing IP allocation")
 		addResp, err := i.retrieveMultiNICIPAllocation(ctx, string(pod.UID), *addArgs.IfName, endpoint)
 		if err != nil {
-			return nil, fmt.Errorf("failed to retrieve the IP allocation in multi-NIC mode: %w", err)
+			return nil, fmt.Errorf("failed to retrieve the IP allocation: %w", err)
 		}
 		if addResp != nil {
 			return addResp, nil
@@ -175,7 +175,7 @@ func (i *ipam) retrieveMultiNICIPAllocation(ctx context.Context, uid, nic string
 		Ips:    ips,
 		Routes: routes,
 	}
-	logger.Sugar().Infof("Succeed to retrieve the IP allocation in multi-NIC mode: %+v", *addResp)
+	logger.Sugar().Infof("Succeed to retrieve the IP allocation: %+v", *addResp)
 
 	return addResp, nil
 }
@@ -199,11 +199,11 @@ func (i *ipam) allocateInStandardMode(ctx context.Context, addArgs *models.IpamA
 	defer func() {
 		if err != nil {
 			if len(results) != 0 {
-				i.cache.addFailureIPs(string(pod.UID), results)
+				i.failure.addFailureIPs(string(pod.UID), results)
 			}
 			return
 		}
-		i.cache.rmFailureIPs(string(pod.UID))
+		i.failure.rmFailureIPs(string(pod.UID))
 	}()
 
 	logger.Debug("Concurrently allocate IP addresses from all IPPool candidates")
@@ -333,7 +333,7 @@ func (i *ipam) allocateIPsFromAllCandidates(ctx context.Context, tt ToBeAllocate
 func (i *ipam) allocateIPFromCandidate(ctx context.Context, c *PoolCandidate, nic string, cleanGateway bool, pod *corev1.Pod) (*types.AllocationResult, error) {
 	logger := logutils.FromContext(ctx)
 
-	for _, oldRes := range i.cache.getFailureIPs(string(pod.UID)) {
+	for _, oldRes := range i.failure.getFailureIPs(string(pod.UID)) {
 		for _, ipPool := range c.PToIPPool {
 			if oldRes.IP.IPPool == ipPool.Name && *oldRes.IP.Nic == nic {
 				logger.Sugar().Infof("Reuse allocated IPv%d IP %s for NIC %s from IPPool %s", c.IPVersion, *oldRes.IP.Address, nic, ipPool.Name)
@@ -374,7 +374,6 @@ func (i *ipam) allocateIPFromCandidate(ctx context.Context, c *PoolCandidate, ni
 func (i *ipam) precheckPoolCandidates(ctx context.Context, t *ToBeAllocated) error {
 	logger := logutils.FromContext(ctx)
 
-	// TODO(iiiceoo): Use gorouting.
 	for _, c := range t.PoolCandidates {
 		if c.PToIPPool == nil {
 			c.PToIPPool = PoolNameToIPPool{}
@@ -393,7 +392,7 @@ func (i *ipam) precheckPoolCandidates(ctx context.Context, t *ToBeAllocated) err
 			}
 
 			logger.Sugar().Debugf("Get original IPPool %s", pool)
-			ipPool, err := i.ipPoolManager.GetIPPoolByName(ctx, pool)
+			ipPool, err := i.ipPoolManager.GetIPPoolByName(ctx, pool, constant.IgnoreCache)
 			if err != nil {
 				return fmt.Errorf("failed to get original IPPool %s: %v", pool, err)
 			}
@@ -408,6 +407,9 @@ func (i *ipam) filterPoolCandidates(ctx context.Context, t *ToBeAllocated, pod *
 	logger := logutils.FromContext(ctx)
 
 	for _, c := range t.PoolCandidates {
+		cp := make([]string, len(c.Pools))
+		copy(cp, c.Pools)
+
 		var errs []error
 		for j := 0; j < len(c.Pools); j++ {
 			pool := c.Pools[j]
@@ -422,7 +424,7 @@ func (i *ipam) filterPoolCandidates(ctx context.Context, t *ToBeAllocated, pod *
 		}
 
 		if len(c.Pools) == 0 {
-			return fmt.Errorf("%w, all IPv%d IPPools %v of %s filtered out: %v", constant.ErrNoAvailablePool, c.IPVersion, c.Pools, t.NIC, utilerrors.NewAggregate(errs))
+			return fmt.Errorf("%w, all IPv%d IPPools %v of %s filtered out: %v", constant.ErrNoAvailablePool, c.IPVersion, cp, t.NIC, utilerrors.NewAggregate(errs))
 		}
 	}
 
@@ -443,7 +445,7 @@ func (i *ipam) selectByPod(ctx context.Context, version types.IPVersion, ipPool
 	}
 
 	if ipPool.Spec.NodeAffinity != nil {
-		node, err := i.nodeManager.GetNodeByName(ctx, pod.Spec.NodeName)
+		node, err := i.nodeManager.GetNodeByName(ctx, pod.Spec.NodeName, constant.UseCache)
 		if err != nil {
 			return err
 		}
@@ -457,7 +459,7 @@ func (i *ipam) selectByPod(ctx context.Context, version types.IPVersion, ipPool
 	}
 
 	if ipPool.Spec.NamespaceAffinity != nil {
-		namespace, err := i.nsManager.GetNamespaceByName(ctx, pod.Namespace)
+		namespace, err := i.nsManager.GetNamespaceByName(ctx, pod.Namespace, constant.UseCache)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/ipam/config.go b/pkg/ipam/config.go
index 838d8e312..a305f4754 100644
--- a/pkg/ipam/config.go
+++ b/pkg/ipam/config.go
@@ -31,34 +31,6 @@ func setDefaultsForIPAMConfig(config IPAMConfig) IPAMConfig {
 	return config
 }
 
-func (c *IPAMConfig) getClusterDefaultPool(ctx context.Context, nic string, cleanGateway bool) (*ToBeAllocated, error) {
-	if len(c.ClusterDefaultIPv4IPPool) == 0 && len(c.ClusterDefaultIPv6IPPool) == 0 {
-		return nil, fmt.Errorf("%w, no pool selection rules of any type are specified", constant.ErrNoAvailablePool)
-	}
-
-	logger := logutils.FromContext(ctx)
-	logger.Info("Use IPPools from cluster default pools")
-
-	t := &ToBeAllocated{
-		NIC:          nic,
-		CleanGateway: cleanGateway,
-	}
-	if len(c.ClusterDefaultIPv4IPPool) != 0 {
-		t.PoolCandidates = append(t.PoolCandidates, &PoolCandidate{
-			IPVersion: constant.IPv4,
-			Pools:     c.ClusterDefaultIPv4IPPool,
-		})
-	}
-	if len(c.ClusterDefaultIPv6IPPool) != 0 {
-		t.PoolCandidates = append(t.PoolCandidates, &PoolCandidate{
-			IPVersion: constant.IPv6,
-			Pools:     c.ClusterDefaultIPv6IPPool,
-		})
-	}
-
-	return t, nil
-}
-
 func (c *IPAMConfig) checkIPVersionEnable(ctx context.Context, tt ToBeAllocateds) error {
 	logger := logutils.FromContext(ctx)
 
diff --git a/pkg/ipam/ipam.go b/pkg/ipam/ipam.go
index 745538402..2aa016d61 100644
--- a/pkg/ipam/ipam.go
+++ b/pkg/ipam/ipam.go
@@ -30,7 +30,7 @@ type IPAM interface {
 type ipam struct {
 	config      IPAMConfig
 	ipamLimiter limiter.Limiter
-	cache       *failureCache
+	failure     *failureCache
 
 	ipPoolManager   ippoolmanager.IPPoolManager
 	endpointManager workloadendpointmanager.WorkloadEndpointManager
@@ -76,7 +76,7 @@ func NewIPAM(
 	return &ipam{
 		config:          setDefaultsForIPAMConfig(config),
 		ipamLimiter:     limiter.NewLimiter(limiter.LimiterConfig{}),
-		cache:           newFailureCache(),
+		failure:         newFailureCache(),
 		ipPoolManager:   ipPoolManager,
 		endpointManager: endpointManager,
 		nodeManager:     nodeManager,
@@ -88,7 +88,19 @@ func NewIPAM(
 }
 
 func (i *ipam) Start(ctx context.Context) error {
-	return i.ipamLimiter.Start(ctx)
+	errCh := make(chan error)
+	go func() {
+		if err := i.ipamLimiter.Start(ctx); err != nil {
+			errCh <- err
+		}
+	}()
+
+	select {
+	case <-ctx.Done():
+		return nil
+	case err := <-errCh:
+		return err
+	}
 }
 
 type failureCache struct {
diff --git a/pkg/ipam/pool_selections.go b/pkg/ipam/pool_selections.go
index 8a7ed86c0..6449aeeeb 100644
--- a/pkg/ipam/pool_selections.go
+++ b/pkg/ipam/pool_selections.go
@@ -7,6 +7,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"strconv"
 	"sync"
 	"time"
 
@@ -81,8 +82,8 @@ func (i *ipam) getPoolCandidates(ctx context.Context, addArgs *models.IpamAddArg
 		return ToBeAllocateds{t}, nil
 	}
 
-	// Select IPPool candidates through Configmap spiderpool-conf.
-	t, err = i.config.getClusterDefaultPool(ctx, *addArgs.IfName, addArgs.CleanGateway)
+	// Select IPPools whose spec.default is true.
+	t, err = i.getClusterDefaultPools(ctx, *addArgs.IfName, addArgs.CleanGateway)
 	if err != nil {
 		return nil, err
 	}
@@ -163,7 +164,7 @@ func (i *ipam) getPoolFromSubnetAnno(ctx context.Context, pod *corev1.Pod, nic s
 			if j > 1 {
 				isRetried = true
 			}
-			poolList, err := i.ipPoolManager.ListIPPools(ctx, matchLabels)
+			poolList, err := i.ipPoolManager.ListIPPools(ctx, constant.UseCache, matchLabels)
 			if nil != err {
 				return nil, fmt.Errorf("failed to get IPPoolList with labels '%v', error: %v", matchLabels, err)
 			}
@@ -366,7 +367,7 @@ func (i *ipam) findOrApplyClusterDefaultSubnetIPPool(ctx context.Context, podCon
 				isRetried = true
 			}
 
-			poolList, err := i.ipPoolManager.ListIPPools(ctx, matchLabel)
+			poolList, err := i.ipPoolManager.ListIPPools(ctx, constant.UseCache, matchLabel)
 			if nil != err {
 				return nil, fmt.Errorf("failed to get IPPoolList with labels '%v', error: %v", matchLabel, err)
 			}
@@ -543,7 +544,7 @@ func getPoolFromPodAnnoPool(ctx context.Context, anno, nic string, cleanGateway
 }
 
 func (i *ipam) getPoolFromNS(ctx context.Context, namespace, nic string, cleanGateway bool) (*ToBeAllocated, error) {
-	ns, err := i.nsManager.GetNamespaceByName(ctx, namespace)
+	ns, err := i.nsManager.GetNamespaceByName(ctx, namespace, constant.UseCache)
 	if err != nil {
 		return nil, err
 	}
@@ -606,3 +607,58 @@ func getPoolFromNetConf(ctx context.Context, nic string, netConfV4Pool, netConfV
 
 	return t
 }
+
+func (i *ipam) getClusterDefaultPools(ctx context.Context, nic string, cleanGateway bool) (*ToBeAllocated, error) {
+	ipPoolList, err := i.ipPoolManager.ListIPPools(
+		ctx,
+		constant.UseCache,
+		client.MatchingFields{"spec.default": strconv.FormatBool(true)},
+	)
+	if err != nil {
+		return nil, err
+	}
+
+	if len(ipPoolList.Items) == 0 {
+		return nil, fmt.Errorf("%w, no pool selection rules of any type are specified", constant.ErrNoAvailablePool)
+	}
+
+	logger := logutils.FromContext(ctx)
+	logger.Info("Use cluster default IPPools")
+
+	t := &ToBeAllocated{
+		NIC:          nic,
+		CleanGateway: cleanGateway,
+	}
+
+	var v4Pools, v6Pools []string
+	v4PToIPPool := PoolNameToIPPool{}
+	v6PToIPPool := PoolNameToIPPool{}
+	for _, ipPool := range ipPoolList.Items {
+		if *ipPool.Spec.IPVersion == constant.IPv4 {
+			v4Pools = append(v4Pools, ipPool.Name)
+			p := ipPool
+			v4PToIPPool[ipPool.Name] = &p
+		} else {
+			v6Pools = append(v6Pools, ipPool.Name)
+			p := ipPool
+			v6PToIPPool[ipPool.Name] = &p
+		}
+	}
+
+	if len(v4Pools) != 0 {
+		t.PoolCandidates = append(t.PoolCandidates, &PoolCandidate{
+			IPVersion: constant.IPv4,
+			Pools:     v4Pools,
+			PToIPPool: v4PToIPPool,
+		})
+	}
+	if len(v6Pools) != 0 {
+		t.PoolCandidates = append(t.PoolCandidates, &PoolCandidate{
+			IPVersion: constant.IPv6,
+			Pools:     v6Pools,
+			PToIPPool: v6PToIPPool,
+		})
+	}
+
+	return t, nil
+}
diff --git a/pkg/ipam/release.go b/pkg/ipam/release.go
index 3fe79791e..b7734faf8 100644
--- a/pkg/ipam/release.go
+++ b/pkg/ipam/release.go
@@ -28,7 +28,7 @@ func (i *ipam) Release(ctx context.Context, delArgs *models.IpamDelArgs) error {
 	logger := logutils.FromContext(ctx)
 	logger.Info("Start to release")
 
-	pod, err := i.podManager.GetPodByName(ctx, *delArgs.PodNamespace, *delArgs.PodName)
+	pod, err := i.podManager.GetPodByName(ctx, *delArgs.PodNamespace, *delArgs.PodName, constant.IgnoreCache)
 	if client.IgnoreNotFound(err) != nil {
 		return fmt.Errorf("failed to get Pod %s/%s: %v", *delArgs.PodNamespace, *delArgs.PodName, err)
 	}
@@ -68,8 +68,8 @@ func (i *ipam) Release(ctx context.Context, delArgs *models.IpamDelArgs) error {
 		return nil
 	}
 
-	defer i.cache.rmFailureIPs(*delArgs.PodUID)
-	endpoint, err := i.endpointManager.GetEndpointByName(ctx, *delArgs.PodNamespace, *delArgs.PodName)
+	defer i.failure.rmFailureIPs(*delArgs.PodUID)
+	endpoint, err := i.endpointManager.GetEndpointByName(ctx, *delArgs.PodNamespace, *delArgs.PodName, constant.IgnoreCache)
 	if err != nil {
 		if apierrors.IsNotFound(err) {
 			logger.Info("Endpoint does not exist, ignore release")
diff --git a/pkg/ipam/types.go b/pkg/ipam/types.go
index 4ca17a1d2..86ca545d0 100644
--- a/pkg/ipam/types.go
+++ b/pkg/ipam/types.go
@@ -71,5 +71,5 @@ func (ptp *PoolNameToIPPool) IPPools() []*spiderpoolv1.SpiderIPPool {
 }
 
 func (pp PoolNameToIPPool) String() string {
-	return ""
+	return "*"
 }
diff --git a/pkg/ippoolmanager/ippool_manager.go b/pkg/ippoolmanager/ippool_manager.go
index 85f1a4404..c494ba359 100644
--- a/pkg/ippoolmanager/ippool_manager.go
+++ b/pkg/ippoolmanager/ippool_manager.go
@@ -28,8 +28,8 @@ import (
 )
 
 type IPPoolManager interface {
-	GetIPPoolByName(ctx context.Context, poolName string) (*spiderpoolv1.SpiderIPPool, error)
-	ListIPPools(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderIPPoolList, error)
+	GetIPPoolByName(ctx context.Context, poolName string, cached bool) (*spiderpoolv1.SpiderIPPool, error)
+	ListIPPools(ctx context.Context, cached bool, opts ...client.ListOption) (*spiderpoolv1.SpiderIPPoolList, error)
 	AllocateIP(ctx context.Context, poolName, nic string, pod *corev1.Pod) (*models.IPConfig, error)
 	ReleaseIP(ctx context.Context, poolName string, ipAndUIDs []types.IPAndUID) error
 	UpdateAllocatedIPs(ctx context.Context, poolName string, ipAndCIDs []types.IPAndUID) error
@@ -39,13 +39,17 @@ type IPPoolManager interface {
 type ipPoolManager struct {
 	config     IPPoolManagerConfig
 	client     client.Client
+	apiReader  client.Reader
 	rIPManager reservedipmanager.ReservedIPManager
 }
 
-func NewIPPoolManager(config IPPoolManagerConfig, client client.Client, rIPManager reservedipmanager.ReservedIPManager) (IPPoolManager, error) {
+func NewIPPoolManager(config IPPoolManagerConfig, client client.Client, apiReader client.Reader, rIPManager reservedipmanager.ReservedIPManager) (IPPoolManager, error) {
 	if client == nil {
 		return nil, fmt.Errorf("k8s client %w", constant.ErrMissingRequiredParam)
 	}
+	if apiReader == nil {
+		return nil, fmt.Errorf("api reader %w", constant.ErrMissingRequiredParam)
+	}
 	if rIPManager == nil {
 		return nil, fmt.Errorf("reserved-IP manager %w", constant.ErrMissingRequiredParam)
 	}
@@ -53,22 +57,33 @@ func NewIPPoolManager(config IPPoolManagerConfig, client client.Client, rIPManag
 	return &ipPoolManager{
 		config:     setDefaultsForIPPoolManagerConfig(config),
 		client:     client,
+		apiReader:  apiReader,
 		rIPManager: rIPManager,
 	}, nil
 }
 
-func (im *ipPoolManager) GetIPPoolByName(ctx context.Context, poolName string) (*spiderpoolv1.SpiderIPPool, error) {
+func (im *ipPoolManager) GetIPPoolByName(ctx context.Context, poolName string, cached bool) (*spiderpoolv1.SpiderIPPool, error) {
+	reader := im.apiReader
+	if cached == constant.UseCache {
+		reader = im.client
+	}
+
 	var ipPool spiderpoolv1.SpiderIPPool
-	if err := im.client.Get(ctx, apitypes.NamespacedName{Name: poolName}, &ipPool); err != nil {
+	if err := reader.Get(ctx, apitypes.NamespacedName{Name: poolName}, &ipPool); err != nil {
 		return nil, err
 	}
 
 	return &ipPool, nil
 }
 
-func (im *ipPoolManager) ListIPPools(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderIPPoolList, error) {
+func (im *ipPoolManager) ListIPPools(ctx context.Context, cached bool, opts ...client.ListOption) (*spiderpoolv1.SpiderIPPoolList, error) {
+	reader := im.apiReader
+	if cached == constant.UseCache {
+		reader = im.client
+	}
+
 	var ipPoolList spiderpoolv1.SpiderIPPoolList
-	if err := im.client.List(ctx, &ipPoolList, opts...); err != nil {
+	if err := reader.List(ctx, &ipPoolList, opts...); err != nil {
 		return nil, err
 	}
 
@@ -83,7 +98,7 @@ func (im *ipPoolManager) AllocateIP(ctx context.Context, poolName, nic string, p
 	for i := 0; i <= im.config.MaxConflictRetries; i++ {
 		logger := logger.With(zap.Int("times", i+1))
 		logger.Sugar().Debugf("Re-get IPPool %s for IP allocation", poolName)
-		ipPool, err := im.GetIPPoolByName(ctx, poolName)
+		ipPool, err := im.GetIPPoolByName(ctx, poolName, constant.IgnoreCache)
 		if err != nil {
 			return nil, err
 		}
@@ -181,7 +196,7 @@ func (im *ipPoolManager) ReleaseIP(ctx context.Context, poolName string, ipAndUI
 	for i := 0; i <= im.config.MaxConflictRetries; i++ {
 		logger := logger.With(zap.Int("times", i+1))
 		logger.Sugar().Debugf("Re-get IPPool %s for IP release", poolName)
-		ipPool, err := im.GetIPPoolByName(ctx, poolName)
+		ipPool, err := im.GetIPPoolByName(ctx, poolName, constant.IgnoreCache)
 		if err != nil {
 			return err
 		}
@@ -242,7 +257,7 @@ func (im *ipPoolManager) ReleaseIP(ctx context.Context, poolName string, ipAndUI
 func (im *ipPoolManager) UpdateAllocatedIPs(ctx context.Context, poolName string, ipAndUIDs []types.IPAndUID) error {
 	r := rand.New(rand.NewSource(time.Now().UnixNano()))
 	for i := 0; i <= im.config.MaxConflictRetries; i++ {
-		ipPool, err := im.GetIPPoolByName(ctx, poolName)
+		ipPool, err := im.GetIPPoolByName(ctx, poolName, constant.IgnoreCache)
 		if err != nil {
 			return err
 		}
diff --git a/pkg/ippoolmanager/ippool_mutate.go b/pkg/ippoolmanager/ippool_mutate.go
index a12325d4e..75c058769 100644
--- a/pkg/ippoolmanager/ippool_mutate.go
+++ b/pkg/ippoolmanager/ippool_mutate.go
@@ -120,7 +120,7 @@ func (iw *IPPoolWebhook) setControllerSubnet(ctx context.Context, ipPool *spider
 
 	subnet := subnetList.Items[0]
 	if !metav1.IsControlledBy(ipPool, &subnet) {
-		if err := ctrl.SetControllerReference(&subnet, ipPool, iw.Scheme); err != nil {
+		if err := ctrl.SetControllerReference(&subnet, ipPool, iw.Client.Scheme()); err != nil {
 			return fmt.Errorf("failed to set owner reference: %v", err)
 		}
 		logger.Sugar().Infof("Set owner reference as Subnet %s", subnet.Name)
diff --git a/pkg/ippoolmanager/ippool_subnet_validate.go b/pkg/ippoolmanager/ippool_subnet_validate.go
index 2295be401..33b92d15d 100644
--- a/pkg/ippoolmanager/ippool_subnet_validate.go
+++ b/pkg/ippoolmanager/ippool_subnet_validate.go
@@ -61,7 +61,7 @@ func (iw *IPPoolWebhook) validateSubnetTotalIPsContainsIPPoolTotalIPs(ctx contex
 	}
 
 	var subnet spiderpoolv1.SpiderSubnet
-	if err := iw.Client.Get(ctx, apitypes.NamespacedName{Name: owner.Name}, &subnet); err != nil {
+	if err := iw.APIReader.Get(ctx, apitypes.NamespacedName{Name: owner.Name}, &subnet); err != nil {
 		return field.InternalError(subnetField, fmt.Errorf("failed to get controller Subnet %s: %v", owner.Name, err))
 	}
 
diff --git a/pkg/ippoolmanager/ippool_validate.go b/pkg/ippoolmanager/ippool_validate.go
index 170e8cfc8..a9165ecd4 100644
--- a/pkg/ippoolmanager/ippool_validate.go
+++ b/pkg/ippoolmanager/ippool_validate.go
@@ -182,7 +182,7 @@ func (iw *IPPoolWebhook) validateIPPoolCIDR(ctx context.Context, ipPool *spiderp
 
 	// TODO(iiiceoo): Use label selector.
 	var ipPoolList spiderpoolv1.SpiderIPPoolList
-	if err := iw.Client.List(ctx, &ipPoolList); err != nil {
+	if err := iw.APIReader.List(ctx, &ipPoolList); err != nil {
 		return field.InternalError(subnetField, fmt.Errorf("failed to list IPPools: %v", err))
 	}
 
@@ -237,7 +237,7 @@ func (iw *IPPoolWebhook) validateIPPoolAvailableIPs(ctx context.Context, ipPool
 
 	// TODO(iiiceoo): The list in validateIPPoolCIDR should be reused.
 	var ipPoolList spiderpoolv1.SpiderIPPoolList
-	if err := iw.Client.List(
+	if err := iw.APIReader.List(
 		ctx,
 		&ipPoolList,
 		client.MatchingLabels{constant.LabelIPPoolCIDR: cidr},
diff --git a/pkg/ippoolmanager/ippool_webhook.go b/pkg/ippoolmanager/ippool_webhook.go
index 6cf87e85e..097ef161f 100644
--- a/pkg/ippoolmanager/ippool_webhook.go
+++ b/pkg/ippoolmanager/ippool_webhook.go
@@ -24,8 +24,8 @@ import (
 var WebhookLogger *zap.Logger
 
 type IPPoolWebhook struct {
-	client.Client
-	Scheme *runtime.Scheme
+	Client    client.Client
+	APIReader client.Reader
 
 	EnableIPv4         bool
 	EnableIPv6         bool
diff --git a/pkg/k8s/apis/spiderpool.spidernet.io/v1/spiderendpoint_types.go b/pkg/k8s/apis/spiderpool.spidernet.io/v1/spiderendpoint_types.go
index 8a5b26dca..fe683d017 100644
--- a/pkg/k8s/apis/spiderpool.spidernet.io/v1/spiderendpoint_types.go
+++ b/pkg/k8s/apis/spiderpool.spidernet.io/v1/spiderendpoint_types.go
@@ -78,7 +78,7 @@ type IPAllocationDetail struct {
 // +kubebuilder:printcolumn:JSONPath=".status.current.ips[0].ipv6Pool",description="ipv6Pool",name="IPV6POOL",type=string
 // +kubebuilder:printcolumn:JSONPath=".status.current.ips[0].ipv6",description="ipv6",name="IPV6",type=string
 // +kubebuilder:printcolumn:JSONPath=".status.current.node",description="node",name="NODE",type=string
-// +kubebuilder:printcolumn:JSONPath=".status.current.creationTime",description="creationTime",name="CREATETION TIME",type=date
+// +kubebuilder:printcolumn:JSONPath=".status.creationTime",description="creationTime",name="CREATETION TIME",type=date
 // +kubebuilder:object:root=true
 
 // Spiderndpoint is the Schema for the spiderendpoints API.
diff --git a/pkg/namespacemanager/namespace_manager.go b/pkg/namespacemanager/namespace_manager.go
index ecb854681..a6639addc 100644
--- a/pkg/namespacemanager/namespace_manager.go
+++ b/pkg/namespacemanager/namespace_manager.go
@@ -15,36 +15,51 @@ import (
 )
 
 type NamespaceManager interface {
-	GetNamespaceByName(ctx context.Context, nsName string) (*corev1.Namespace, error)
-	ListNamespaces(ctx context.Context, opts ...client.ListOption) (*corev1.NamespaceList, error)
+	GetNamespaceByName(ctx context.Context, nsName string, cached bool) (*corev1.Namespace, error)
+	ListNamespaces(ctx context.Context, cached bool, opts ...client.ListOption) (*corev1.NamespaceList, error)
 }
 
 type namespaceManager struct {
-	client client.Client
+	client    client.Client
+	apiReader client.Reader
 }
 
-func NewNamespaceManager(client client.Client) (NamespaceManager, error) {
+func NewNamespaceManager(client client.Client, apiReader client.Reader) (NamespaceManager, error) {
 	if client == nil {
 		return nil, fmt.Errorf("k8s client %w", constant.ErrMissingRequiredParam)
 	}
+	if apiReader == nil {
+		return nil, fmt.Errorf("api reader %w", constant.ErrMissingRequiredParam)
+	}
 
 	return &namespaceManager{
-		client: client,
+		client:    client,
+		apiReader: apiReader,
 	}, nil
 }
 
-func (nm *namespaceManager) GetNamespaceByName(ctx context.Context, nsName string) (*corev1.Namespace, error) {
+func (nm *namespaceManager) GetNamespaceByName(ctx context.Context, nsName string, cached bool) (*corev1.Namespace, error) {
+	reader := nm.apiReader
+	if cached == constant.UseCache {
+		reader = nm.client
+	}
+
 	var ns corev1.Namespace
-	if err := nm.client.Get(ctx, apitypes.NamespacedName{Name: nsName}, &ns); err != nil {
+	if err := reader.Get(ctx, apitypes.NamespacedName{Name: nsName}, &ns); err != nil {
 		return nil, err
 	}
 
 	return &ns, nil
 }
 
-func (nm *namespaceManager) ListNamespaces(ctx context.Context, opts ...client.ListOption) (*corev1.NamespaceList, error) {
+func (nm *namespaceManager) ListNamespaces(ctx context.Context, cached bool, opts ...client.ListOption) (*corev1.NamespaceList, error) {
+	reader := nm.apiReader
+	if cached == constant.UseCache {
+		reader = nm.client
+	}
+
 	var nsList corev1.NamespaceList
-	if err := nm.client.List(ctx, &nsList, opts...); err != nil {
+	if err := reader.List(ctx, &nsList, opts...); err != nil {
 		return nil, err
 	}
 
diff --git a/pkg/nodemanager/node_manager.go b/pkg/nodemanager/node_manager.go
index c16338de7..c34a5d850 100644
--- a/pkg/nodemanager/node_manager.go
+++ b/pkg/nodemanager/node_manager.go
@@ -15,36 +15,51 @@ import (
 )
 
 type NodeManager interface {
-	GetNodeByName(ctx context.Context, nodeName string) (*corev1.Node, error)
-	ListNodes(ctx context.Context, opts ...client.ListOption) (*corev1.NodeList, error)
+	GetNodeByName(ctx context.Context, nodeName string, cached bool) (*corev1.Node, error)
+	ListNodes(ctx context.Context, cached bool, opts ...client.ListOption) (*corev1.NodeList, error)
 }
 
 type nodeManager struct {
-	client client.Client
+	client    client.Client
+	apiReader client.Reader
 }
 
-func NewNodeManager(client client.Client) (NodeManager, error) {
+func NewNodeManager(client client.Client, apiReader client.Reader) (NodeManager, error) {
 	if client == nil {
 		return nil, fmt.Errorf("k8s client %w", constant.ErrMissingRequiredParam)
 	}
+	if apiReader == nil {
+		return nil, fmt.Errorf("api reader %w", constant.ErrMissingRequiredParam)
+	}
 
 	return &nodeManager{
-		client: client,
+		client:    client,
+		apiReader: apiReader,
 	}, nil
 }
 
-func (nm *nodeManager) GetNodeByName(ctx context.Context, nodeName string) (*corev1.Node, error) {
+func (nm *nodeManager) GetNodeByName(ctx context.Context, nodeName string, cached bool) (*corev1.Node, error) {
+	reader := nm.apiReader
+	if cached == constant.UseCache {
+		reader = nm.client
+	}
+
 	var node corev1.Node
-	if err := nm.client.Get(ctx, apitypes.NamespacedName{Name: nodeName}, &node); err != nil {
+	if err := reader.Get(ctx, apitypes.NamespacedName{Name: nodeName}, &node); err != nil {
 		return nil, err
 	}
 
 	return &node, nil
 }
 
-func (nm *nodeManager) ListNodes(ctx context.Context, opts ...client.ListOption) (*corev1.NodeList, error) {
+func (nm *nodeManager) ListNodes(ctx context.Context, cached bool, opts ...client.ListOption) (*corev1.NodeList, error) {
+	reader := nm.apiReader
+	if cached == constant.UseCache {
+		reader = nm.client
+	}
+
 	var nodeList corev1.NodeList
-	if err := nm.client.List(ctx, &nodeList, opts...); err != nil {
+	if err := reader.List(ctx, &nodeList, opts...); err != nil {
 		return nil, err
 	}
 
diff --git a/pkg/podmanager/config.go b/pkg/podmanager/config.go
deleted file mode 100644
index bda487f41..000000000
--- a/pkg/podmanager/config.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 Authors of spidernet-io
-// SPDX-License-Identifier: Apache-2.0
-
-package podmanager
-
-import (
-	"time"
-)
-
-type PodManagerConfig struct {
-	MaxConflictRetries    int
-	ConflictRetryUnitTime time.Duration
-}
-
-func setDefaultsForPodManagerConfig(config PodManagerConfig) PodManagerConfig {
-	return config
-}
diff --git a/pkg/podmanager/pod_manager.go b/pkg/podmanager/pod_manager.go
index 6ef9d1e5d..8e09c99a6 100644
--- a/pkg/podmanager/pod_manager.go
+++ b/pkg/podmanager/pod_manager.go
@@ -20,39 +20,52 @@ import (
 )
 
 type PodManager interface {
-	GetPodByName(ctx context.Context, namespace, podName string) (*corev1.Pod, error)
-	ListPods(ctx context.Context, opts ...client.ListOption) (*corev1.PodList, error)
+	GetPodByName(ctx context.Context, namespace, podName string, cached bool) (*corev1.Pod, error)
+	ListPods(ctx context.Context, cached bool, opts ...client.ListOption) (*corev1.PodList, error)
 	GetPodTopController(ctx context.Context, pod *corev1.Pod) (types.PodTopController, error)
 }
 
 type podManager struct {
-	config PodManagerConfig
-	client client.Client
+	client    client.Client
+	apiReader client.Reader
 }
 
-func NewPodManager(config PodManagerConfig, client client.Client) (PodManager, error) {
+func NewPodManager(client client.Client, apiReader client.Reader) (PodManager, error) {
 	if client == nil {
 		return nil, fmt.Errorf("k8s client %w", constant.ErrMissingRequiredParam)
 	}
+	if apiReader == nil {
+		return nil, fmt.Errorf("api reader %w", constant.ErrMissingRequiredParam)
+	}
 
 	return &podManager{
-		config: setDefaultsForPodManagerConfig(config),
-		client: client,
+		client:    client,
+		apiReader: apiReader,
 	}, nil
 }
 
-func (pm *podManager) GetPodByName(ctx context.Context, namespace, podName string) (*corev1.Pod, error) {
+func (pm *podManager) GetPodByName(ctx context.Context, namespace, podName string, cached bool) (*corev1.Pod, error) {
+	reader := pm.apiReader
+	if cached == constant.UseCache {
+		reader = pm.client
+	}
+
 	var pod corev1.Pod
-	if err := pm.client.Get(ctx, apitypes.NamespacedName{Namespace: namespace, Name: podName}, &pod); err != nil {
+	if err := reader.Get(ctx, apitypes.NamespacedName{Namespace: namespace, Name: podName}, &pod); err != nil {
 		return nil, err
 	}
 
 	return &pod, nil
 }
 
-func (pm *podManager) ListPods(ctx context.Context, opts ...client.ListOption) (*corev1.PodList, error) {
+func (pm *podManager) ListPods(ctx context.Context, cached bool, opts ...client.ListOption) (*corev1.PodList, error) {
+	reader := pm.apiReader
+	if cached == constant.UseCache {
+		reader = pm.client
+	}
+
 	var podList corev1.PodList
-	if err := pm.client.List(ctx, &podList, opts...); err != nil {
+	if err := reader.List(ctx, &podList, opts...); err != nil {
 		return nil, err
 	}
 
diff --git a/pkg/reservedipmanager/reservedip_manager.go b/pkg/reservedipmanager/reservedip_manager.go
index 3fdb33fdf..08b0ce5a2 100644
--- a/pkg/reservedipmanager/reservedip_manager.go
+++ b/pkg/reservedipmanager/reservedip_manager.go
@@ -19,37 +19,52 @@ import (
 )
 
 type ReservedIPManager interface {
-	GetReservedIPByName(ctx context.Context, rIPName string) (*spiderpoolv1.SpiderReservedIP, error)
-	ListReservedIPs(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderReservedIPList, error)
+	GetReservedIPByName(ctx context.Context, rIPName string, cached bool) (*spiderpoolv1.SpiderReservedIP, error)
+	ListReservedIPs(ctx context.Context, cached bool, opts ...client.ListOption) (*spiderpoolv1.SpiderReservedIPList, error)
 	AssembleReservedIPs(ctx context.Context, version types.IPVersion) ([]net.IP, error)
 }
 
 type reservedIPManager struct {
-	client client.Client
+	client    client.Client
+	apiReader client.Reader
 }
 
-func NewReservedIPManager(client client.Client) (ReservedIPManager, error) {
+func NewReservedIPManager(client client.Client, apiReader client.Reader) (ReservedIPManager, error) {
 	if client == nil {
 		return nil, fmt.Errorf("k8s client %w", constant.ErrMissingRequiredParam)
 	}
+	if apiReader == nil {
+		return nil, fmt.Errorf("api reader %w", constant.ErrMissingRequiredParam)
+	}
 
 	return &reservedIPManager{
-		client: client,
+		client:    client,
+		apiReader: apiReader,
 	}, nil
 }
 
-func (rm *reservedIPManager) GetReservedIPByName(ctx context.Context, rIPName string) (*spiderpoolv1.SpiderReservedIP, error) {
+func (rm *reservedIPManager) GetReservedIPByName(ctx context.Context, rIPName string, cached bool) (*spiderpoolv1.SpiderReservedIP, error) {
+	reader := rm.apiReader
+	if cached == constant.UseCache {
+		reader = rm.client
+	}
+
 	var rIP spiderpoolv1.SpiderReservedIP
-	if err := rm.client.Get(ctx, apitypes.NamespacedName{Name: rIPName}, &rIP); err != nil {
+	if err := reader.Get(ctx, apitypes.NamespacedName{Name: rIPName}, &rIP); err != nil {
 		return nil, err
 	}
 
 	return &rIP, nil
 }
 
-func (rm *reservedIPManager) ListReservedIPs(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderReservedIPList, error) {
+func (rm *reservedIPManager) ListReservedIPs(ctx context.Context, cached bool, opts ...client.ListOption) (*spiderpoolv1.SpiderReservedIPList, error) {
+	reader := rm.apiReader
+	if cached == constant.UseCache {
+		reader = rm.client
+	}
+
 	var rIPList spiderpoolv1.SpiderReservedIPList
-	if err := rm.client.List(ctx, &rIPList, opts...); err != nil {
+	if err := reader.List(ctx, &rIPList, opts...); err != nil {
 		return nil, err
 	}
 
@@ -61,7 +76,7 @@ func (rm *reservedIPManager) AssembleReservedIPs(ctx context.Context, version ty
 		return nil, err
 	}
 
-	rIPList, err := rm.ListReservedIPs(ctx, client.MatchingFields{"spec.ipVersion": strconv.FormatInt(version, 10)})
+	rIPList, err := rm.ListReservedIPs(ctx, constant.UseCache, client.MatchingFields{"spec.ipVersion": strconv.FormatInt(version, 10)})
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/reservedipmanager/reservedip_webhook.go b/pkg/reservedipmanager/reservedip_webhook.go
index 3a55d2d19..ecdfe6972 100644
--- a/pkg/reservedipmanager/reservedip_webhook.go
+++ b/pkg/reservedipmanager/reservedip_webhook.go
@@ -12,7 +12,6 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook"
 
 	"github.com/spidernet-io/spiderpool/pkg/constant"
@@ -23,8 +22,6 @@ import (
 var WebhookLogger *zap.Logger
 
 type ReservedIPWebhook struct {
-	client.Client
-
 	EnableIPv4 bool
 	EnableIPv6 bool
 }
diff --git a/pkg/statefulsetmanager/sts_manager.go b/pkg/statefulsetmanager/sts_manager.go
index ea732d082..67d39ee20 100644
--- a/pkg/statefulsetmanager/sts_manager.go
+++ b/pkg/statefulsetmanager/sts_manager.go
@@ -16,37 +16,52 @@ import (
 )
 
 type StatefulSetManager interface {
-	GetStatefulSetByName(ctx context.Context, namespace, name string) (*appsv1.StatefulSet, error)
-	ListStatefulSets(ctx context.Context, opts ...client.ListOption) (*appsv1.StatefulSetList, error)
+	GetStatefulSetByName(ctx context.Context, namespace, name string, cached bool) (*appsv1.StatefulSet, error)
+	ListStatefulSets(ctx context.Context, cached bool, opts ...client.ListOption) (*appsv1.StatefulSetList, error)
 	IsValidStatefulSetPod(ctx context.Context, namespace, podName string) bool
 }
 
 type statefulSetManager struct {
-	client client.Client
+	client    client.Client
+	apiReader client.Reader
 }
 
-func NewStatefulSetManager(client client.Client) (StatefulSetManager, error) {
+func NewStatefulSetManager(client client.Client, apiReader client.Reader) (StatefulSetManager, error) {
 	if client == nil {
-		return nil, fmt.Errorf("k8s clinet %w", constant.ErrMissingRequiredParam)
+		return nil, fmt.Errorf("k8s client %w", constant.ErrMissingRequiredParam)
+	}
+	if apiReader == nil {
+		return nil, fmt.Errorf("api reader %w", constant.ErrMissingRequiredParam)
 	}
 
 	return &statefulSetManager{
-		client: client,
+		client:    client,
+		apiReader: apiReader,
 	}, nil
 }
 
-func (sm *statefulSetManager) GetStatefulSetByName(ctx context.Context, namespace, name string) (*appsv1.StatefulSet, error) {
+func (sm *statefulSetManager) GetStatefulSetByName(ctx context.Context, namespace, name string, cached bool) (*appsv1.StatefulSet, error) {
+	reader := sm.apiReader
+	if cached == constant.UseCache {
+		reader = sm.client
+	}
+
 	var sts appsv1.StatefulSet
-	if err := sm.client.Get(ctx, apitypes.NamespacedName{Namespace: namespace, Name: name}, &sts); err != nil {
+	if err := reader.Get(ctx, apitypes.NamespacedName{Namespace: namespace, Name: name}, &sts); err != nil {
 		return nil, err
 	}
 
 	return &sts, nil
 }
 
-func (sm *statefulSetManager) ListStatefulSets(ctx context.Context, opts ...client.ListOption) (*appsv1.StatefulSetList, error) {
+func (sm *statefulSetManager) ListStatefulSets(ctx context.Context, cached bool, opts ...client.ListOption) (*appsv1.StatefulSetList, error) {
+	reader := sm.apiReader
+	if cached == constant.UseCache {
+		reader = sm.client
+	}
+
 	var stsList appsv1.StatefulSetList
-	if err := sm.client.List(ctx, &stsList, opts...); err != nil {
+	if err := reader.List(ctx, &stsList, opts...); err != nil {
 		return nil, err
 	}
 
@@ -62,7 +77,7 @@ func (sm *statefulSetManager) IsValidStatefulSetPod(ctx context.Context, namespa
 		return false
 	}
 
-	sts, err := sm.GetStatefulSetByName(ctx, namespace, stsName)
+	sts, err := sm.GetStatefulSetByName(ctx, namespace, stsName, constant.IgnoreCache)
 	if err != nil {
 		return !apierrors.IsNotFound(err)
 	}
diff --git a/pkg/subnetmanager/subnet_informer.go b/pkg/subnetmanager/subnet_informer.go
index 50dbc3782..194e28de8 100644
--- a/pkg/subnetmanager/subnet_informer.go
+++ b/pkg/subnetmanager/subnet_informer.go
@@ -13,7 +13,6 @@ import (
 	"go.uber.org/zap"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
-	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 	"k8s.io/apimachinery/pkg/util/wait"
@@ -43,8 +42,8 @@ const (
 var InformerLogger *zap.Logger
 
 type SubnetController struct {
-	client.Client
-	Scheme *runtime.Scheme
+	Client    client.Client
+	APIReader client.Reader
 
 	SubnetsLister listers.SpiderSubnetLister
 	IPPoolsLister listers.SpiderIPPoolLister
@@ -298,7 +297,7 @@ func (sc *SubnetController) syncMetadata(ctx context.Context, subnet *spiderpool
 	}
 
 	if sync {
-		if err := sc.Update(ctx, subnet); err != nil {
+		if err := sc.Client.Update(ctx, subnet); err != nil {
 			return err
 		}
 	}
@@ -320,7 +319,7 @@ func (sc *SubnetController) syncControllerSubnet(ctx context.Context, subnet *sp
 		orphan := false
 		poolCopy := pool.DeepCopy()
 		if !metav1.IsControlledBy(poolCopy, subnet) {
-			if err := ctrl.SetControllerReference(subnet, poolCopy, sc.Scheme); err != nil {
+			if err := ctrl.SetControllerReference(subnet, poolCopy, sc.Client.Scheme()); err != nil {
 				return err
 			}
 			orphan = true
@@ -335,7 +334,7 @@ func (sc *SubnetController) syncControllerSubnet(ctx context.Context, subnet *sp
 		}
 
 		if orphan {
-			if err := sc.Update(ctx, poolCopy); err != nil {
+			if err := sc.Client.Update(ctx, poolCopy); err != nil {
 				return err
 			}
 		}
@@ -394,7 +393,7 @@ func (sc *SubnetController) syncControlledIPPoolIPs(ctx context.Context, subnet
 	}
 
 	if sync {
-		if err := sc.Status().Update(ctx, subnet); err != nil {
+		if err := sc.Client.Status().Update(ctx, subnet); err != nil {
 			return err
 		}
 
@@ -409,7 +408,7 @@ func (sc *SubnetController) removeFinalizer(ctx context.Context, subnet *spiderp
 	logger := logutils.FromContext(ctx)
 
 	if !controllerutil.ContainsFinalizer(subnet, metav1.FinalizerDeleteDependents) {
-		if err := sc.Delete(
+		if err := sc.Client.Delete(
 			ctx,
 			subnet,
 			client.PropagationPolicy(metav1.DeletePropagationForeground),
@@ -417,7 +416,7 @@ func (sc *SubnetController) removeFinalizer(ctx context.Context, subnet *spiderp
 			return err
 		}
 
-		if err := sc.Get(ctx, types.NamespacedName{Name: subnet.Name}, subnet); err != nil {
+		if err := sc.APIReader.Get(ctx, types.NamespacedName{Name: subnet.Name}, subnet); err != nil {
 			return err
 		}
 	}
@@ -433,7 +432,7 @@ func (sc *SubnetController) removeFinalizer(ctx context.Context, subnet *spiderp
 	}
 
 	controllerutil.RemoveFinalizer(subnet, constant.SpiderFinalizer)
-	if err := sc.Update(ctx, subnet); err != nil {
+	if err := sc.Client.Update(ctx, subnet); err != nil {
 		return err
 	}
 	logger.Sugar().Infof("Remove finalizer %s", constant.SpiderFinalizer)
diff --git a/pkg/subnetmanager/subnet_manager.go b/pkg/subnetmanager/subnet_manager.go
index c3c33b869..5a4e0fb87 100644
--- a/pkg/subnetmanager/subnet_manager.go
+++ b/pkg/subnetmanager/subnet_manager.go
@@ -8,7 +8,6 @@ import (
 	"fmt"
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
 	apitypes "k8s.io/apimachinery/pkg/types"
 	"k8s.io/utils/pointer"
 	ctrl "sigs.k8s.io/controller-runtime"
@@ -25,50 +24,61 @@ import (
 )
 
 type SubnetManager interface {
-	GetSubnetByName(ctx context.Context, subnetName string) (*spiderpoolv1.SpiderSubnet, error)
-	ListSubnets(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderSubnetList, error)
+	GetSubnetByName(ctx context.Context, subnetName string, cached bool) (*spiderpoolv1.SpiderSubnet, error)
+	ListSubnets(ctx context.Context, cached bool, opts ...client.ListOption) (*spiderpoolv1.SpiderSubnetList, error)
 	AllocateEmptyIPPool(ctx context.Context, subnetMgrName string, podController types.PodTopController, podSelector *metav1.LabelSelector, ipNum int, ipVersion types.IPVersion, reclaimIPPool bool, ifName string) (*spiderpoolv1.SpiderIPPool, error)
 	CheckScaleIPPool(ctx context.Context, pool *spiderpoolv1.SpiderIPPool, subnetManagerName string, ipNum int) error
 }
 
 type subnetManager struct {
-	config        SubnetManagerConfig
-	client        client.Client
+	config    SubnetManagerConfig
+	client    client.Client
+	apiReader client.Reader
+
 	ipPoolManager ippoolmanager.IPPoolManager
-	Scheme        *runtime.Scheme
 }
 
-func NewSubnetManager(config SubnetManagerConfig, client client.Client, ipPoolManager ippoolmanager.IPPoolManager, scheme *runtime.Scheme) (SubnetManager, error) {
+func NewSubnetManager(config SubnetManagerConfig, client client.Client, apiReader client.Reader, ipPoolManager ippoolmanager.IPPoolManager) (SubnetManager, error) {
 	if client == nil {
 		return nil, fmt.Errorf("k8s client %w", constant.ErrMissingRequiredParam)
 	}
+	if apiReader == nil {
+		return nil, fmt.Errorf("api reader %w", constant.ErrMissingRequiredParam)
+	}
 	if ipPoolManager == nil {
 		return nil, fmt.Errorf("ippool manager %w", constant.ErrMissingRequiredParam)
 	}
-	if scheme == nil {
-		return nil, fmt.Errorf("scheme %w", constant.ErrMissingRequiredParam)
-	}
 
 	return &subnetManager{
 		config:        setDefaultsForSubnetManagerConfig(config),
 		client:        client,
+		apiReader:     apiReader,
 		ipPoolManager: ipPoolManager,
-		Scheme:        scheme,
 	}, nil
 }
 
-func (sm *subnetManager) GetSubnetByName(ctx context.Context, subnetName string) (*spiderpoolv1.SpiderSubnet, error) {
+func (sm *subnetManager) GetSubnetByName(ctx context.Context, subnetName string, cached bool) (*spiderpoolv1.SpiderSubnet, error) {
+	reader := sm.apiReader
+	if cached == constant.UseCache {
+		reader = sm.client
+	}
+
 	var subnet spiderpoolv1.SpiderSubnet
-	if err := sm.client.Get(ctx, apitypes.NamespacedName{Name: subnetName}, &subnet); err != nil {
+	if err := reader.Get(ctx, apitypes.NamespacedName{Name: subnetName}, &subnet); err != nil {
 		return nil, err
 	}
 
 	return &subnet, nil
 }
 
-func (sm *subnetManager) ListSubnets(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderSubnetList, error) {
+func (sm *subnetManager) ListSubnets(ctx context.Context, cached bool, opts ...client.ListOption) (*spiderpoolv1.SpiderSubnetList, error) {
+	reader := sm.apiReader
+	if cached == constant.UseCache {
+		reader = sm.client
+	}
+
 	var subnetList spiderpoolv1.SpiderSubnetList
-	if err := sm.client.List(ctx, &subnetList, opts...); err != nil {
+	if err := reader.List(ctx, &subnetList, opts...); err != nil {
 		return nil, err
 	}
 
@@ -87,7 +97,7 @@ func (sm *subnetManager) AllocateEmptyIPPool(ctx context.Context, subnetName str
 	}
 
 	log := logutils.FromContext(ctx)
-	subnet, err := sm.GetSubnetByName(ctx, subnetName)
+	subnet, err := sm.GetSubnetByName(ctx, subnetName, constant.IgnoreCache)
 	if nil != err {
 		return nil, err
 	}
@@ -136,7 +146,7 @@ func (sm *subnetManager) AllocateEmptyIPPool(ctx context.Context, subnetName str
 	}
 	sp.Labels = poolLabels
 
-	err = ctrl.SetControllerReference(subnet, sp, sm.Scheme)
+	err = ctrl.SetControllerReference(subnet, sp, sm.client.Scheme())
 	if nil != err {
 		return nil, fmt.Errorf("failed to set SpiderIPPool %s owner reference with SpiderSubnet %s: %v", sp.Name, subnetName, err)
 	}
diff --git a/pkg/subnetmanager/subnet_validate.go b/pkg/subnetmanager/subnet_validate.go
index f41534adc..1851e7979 100644
--- a/pkg/subnetmanager/subnet_validate.go
+++ b/pkg/subnetmanager/subnet_validate.go
@@ -177,7 +177,7 @@ func (sw *SubnetWebhook) validateSubnetCIDR(ctx context.Context, subnet *spiderp
 
 	// TODO(iiiceoo): Use label selector.
 	subnetList := spiderpoolv1.SpiderSubnetList{}
-	if err := sw.List(ctx, &subnetList); err != nil {
+	if err := sw.APIReader.List(ctx, &subnetList); err != nil {
 		return field.InternalError(subnetField, fmt.Errorf("failed to list Subnets: %v", err))
 	}
 
diff --git a/pkg/subnetmanager/subnet_webhook.go b/pkg/subnetmanager/subnet_webhook.go
index abd6d86b9..d52dd9617 100644
--- a/pkg/subnetmanager/subnet_webhook.go
+++ b/pkg/subnetmanager/subnet_webhook.go
@@ -24,7 +24,8 @@ import (
 var WebhookLogger *zap.Logger
 
 type SubnetWebhook struct {
-	client.Client
+	Client    client.Client
+	APIReader client.Reader
 
 	EnableIPv4 bool
 	EnableIPv6 bool
diff --git a/pkg/workloadendpointmanager/config.go b/pkg/workloadendpointmanager/config.go
index 58b90fa8d..e1f6336cf 100644
--- a/pkg/workloadendpointmanager/config.go
+++ b/pkg/workloadendpointmanager/config.go
@@ -5,23 +5,13 @@ package workloadendpointmanager
 
 import (
 	"time"
-
-	corev1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 )
 
 type EndpointManagerConfig struct {
 	MaxConflictRetries    int
 	ConflictRetryUnitTime time.Duration
-	scheme                *runtime.Scheme
 }
 
 func setDefaultsForEndpointManagerConfig(config EndpointManagerConfig) EndpointManagerConfig {
-	if config.scheme == nil {
-		config.scheme = runtime.NewScheme()
-		utilruntime.Must(corev1.AddToScheme(config.scheme))
-	}
-
 	return config
 }
diff --git a/pkg/workloadendpointmanager/workloadendpoint_manager.go b/pkg/workloadendpointmanager/workloadendpoint_manager.go
index ab6981076..e0ebe6a64 100644
--- a/pkg/workloadendpointmanager/workloadendpoint_manager.go
+++ b/pkg/workloadendpointmanager/workloadendpoint_manager.go
@@ -23,8 +23,8 @@ import (
 )
 
 type WorkloadEndpointManager interface {
-	GetEndpointByName(ctx context.Context, namespace, podName string) (*spiderpoolv1.SpiderEndpoint, error)
-	ListEndpoints(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderEndpointList, error)
+	GetEndpointByName(ctx context.Context, namespace, podName string, cached bool) (*spiderpoolv1.SpiderEndpoint, error)
+	ListEndpoints(ctx context.Context, cached bool, opts ...client.ListOption) (*spiderpoolv1.SpiderEndpointList, error)
 	DeleteEndpoint(ctx context.Context, endpoint *spiderpoolv1.SpiderEndpoint) error
 	RemoveFinalizer(ctx context.Context, namespace, podName string) error
 	PatchIPAllocationResults(ctx context.Context, containerID string, results []*types.AllocationResult, endpoint *spiderpoolv1.SpiderEndpoint, pod *corev1.Pod, podController types.PodTopController) error
@@ -32,33 +32,48 @@ type WorkloadEndpointManager interface {
 }
 
 type workloadEndpointManager struct {
-	config EndpointManagerConfig
-	client client.Client
+	config    EndpointManagerConfig
+	client    client.Client
+	apiReader client.Reader
 }
 
-func NewWorkloadEndpointManager(config EndpointManagerConfig, client client.Client) (WorkloadEndpointManager, error) {
+func NewWorkloadEndpointManager(config EndpointManagerConfig, client client.Client, apiReader client.Reader) (WorkloadEndpointManager, error) {
 	if client == nil {
 		return nil, fmt.Errorf("k8s client %w", constant.ErrMissingRequiredParam)
 	}
+	if apiReader == nil {
+		return nil, fmt.Errorf("api reader %w", constant.ErrMissingRequiredParam)
+	}
 
 	return &workloadEndpointManager{
-		config: setDefaultsForEndpointManagerConfig(config),
-		client: client,
+		config:    setDefaultsForEndpointManagerConfig(config),
+		client:    client,
+		apiReader: apiReader,
 	}, nil
 }
 
-func (em *workloadEndpointManager) GetEndpointByName(ctx context.Context, namespace, podName string) (*spiderpoolv1.SpiderEndpoint, error) {
+func (em *workloadEndpointManager) GetEndpointByName(ctx context.Context, namespace, podName string, cached bool) (*spiderpoolv1.SpiderEndpoint, error) {
+	reader := em.apiReader
+	if cached == constant.UseCache {
+		reader = em.client
+	}
+
 	var endpoint spiderpoolv1.SpiderEndpoint
-	if err := em.client.Get(ctx, apitypes.NamespacedName{Namespace: namespace, Name: podName}, &endpoint); nil != err {
+	if err := reader.Get(ctx, apitypes.NamespacedName{Namespace: namespace, Name: podName}, &endpoint); nil != err {
 		return nil, err
 	}
 
 	return &endpoint, nil
 }
 
-func (em *workloadEndpointManager) ListEndpoints(ctx context.Context, opts ...client.ListOption) (*spiderpoolv1.SpiderEndpointList, error) {
+func (em *workloadEndpointManager) ListEndpoints(ctx context.Context, cached bool, opts ...client.ListOption) (*spiderpoolv1.SpiderEndpointList, error) {
+	reader := em.apiReader
+	if cached == constant.UseCache {
+		reader = em.client
+	}
+
 	var endpointList spiderpoolv1.SpiderEndpointList
-	if err := em.client.List(ctx, &endpointList, opts...); err != nil {
+	if err := reader.List(ctx, &endpointList, opts...); err != nil {
 		return nil, err
 	}
 
@@ -76,7 +91,7 @@ func (em *workloadEndpointManager) DeleteEndpoint(ctx context.Context, endpoint
 func (em *workloadEndpointManager) RemoveFinalizer(ctx context.Context, namespace, podName string) error {
 	r := rand.New(rand.NewSource(time.Now().UnixNano()))
 	for i := 0; i <= em.config.MaxConflictRetries; i++ {
-		endpoint, err := em.GetEndpointByName(ctx, namespace, podName)
+		endpoint, err := em.GetEndpointByName(ctx, namespace, podName, constant.IgnoreCache)
 		if err != nil {
 			return client.IgnoreNotFound(err)
 		}
@@ -133,7 +148,7 @@ func (em *workloadEndpointManager) PatchIPAllocationResults(ctx context.Context,
 		// we can immediately retrieve the old IP allocation results from the
 		// Endpoint without worrying about the cascading deletion of the Endpoint.
 		if podController.Kind != constant.KindStatefulSet {
-			if err := controllerutil.SetOwnerReference(pod, endpoint, em.config.scheme); err != nil {
+			if err := controllerutil.SetOwnerReference(pod, endpoint, em.client.Scheme()); err != nil {
 				return err
 			}
 		}


Test patch:
diff --git a/pkg/ippoolmanager/ippool_manager_suite_test.go b/pkg/ippoolmanager/ippool_manager_suite_test.go
index 8187b7d1e..89508072c 100644
--- a/pkg/ippoolmanager/ippool_manager_suite_test.go
+++ b/pkg/ippoolmanager/ippool_manager_suite_test.go
@@ -9,6 +9,8 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	"k8s.io/apimachinery/pkg/runtime"
+	k8sscheme "k8s.io/client-go/kubernetes/scheme"
+	k8stesting "k8s.io/client-go/testing"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
@@ -18,6 +20,8 @@ import (
 
 var scheme *runtime.Scheme
 var fakeClient client.Client
+var tracker k8stesting.ObjectTracker
+var fakeAPIReader client.Reader
 var ipPoolWebhook *ippoolmanager.IPPoolWebhook
 
 func TestIPPoolManager(t *testing.T) {
@@ -34,9 +38,15 @@ var _ = BeforeSuite(func() {
 		WithScheme(scheme).
 		Build()
 
+	tracker = k8stesting.NewObjectTracker(scheme, k8sscheme.Codecs.UniversalDecoder())
+	fakeAPIReader = fake.NewClientBuilder().
+		WithScheme(scheme).
+		WithObjectTracker(tracker).
+		Build()
+
 	ipPoolWebhook = &ippoolmanager.IPPoolWebhook{
 		Client:             fakeClient,
-		Scheme:             scheme,
+		APIReader:          fakeAPIReader,
 		EnableIPv4:         true,
 		EnableIPv6:         true,
 		EnableSpiderSubnet: true,
diff --git a/pkg/ippoolmanager/ippool_webhook_test.go b/pkg/ippoolmanager/ippool_webhook_test.go
index 6f1e60530..2aeed0257 100644
--- a/pkg/ippoolmanager/ippool_webhook_test.go
+++ b/pkg/ippoolmanager/ippool_webhook_test.go
@@ -13,6 +13,7 @@ import (
 	. "github.com/onsi/gomega"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/util/uuid"
 	"k8s.io/utils/pointer"
 	ctrl "sigs.k8s.io/controller-runtime"
@@ -115,6 +116,39 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 
 			err = fakeClient.Delete(ctx, subnetT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    constant.SpiderpoolAPIGroup,
+					Version:  constant.SpiderpoolAPIVersionV1,
+					Resource: "spiderippools",
+				},
+				ipPoolT.Namespace,
+				ipPoolT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    constant.SpiderpoolAPIGroup,
+					Version:  constant.SpiderpoolAPIVersionV1,
+					Resource: "spiderippools",
+				},
+				existIPPoolT.Namespace,
+				existIPPoolT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    constant.SpiderpoolAPIGroup,
+					Version:  constant.SpiderpoolAPIVersionV1,
+					Resource: "spidersubnets",
+				},
+				subnetT.Namespace,
+				subnetT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 		})
 
 		Describe("Default", func() {
@@ -611,7 +645,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					)
 
 					ctx := context.TODO()
-					err := fakeClient.Create(ctx, ipPoolT)
+					err := tracker.Add(ipPoolT)
 					Expect(err).NotTo(HaveOccurred())
 
 					err = ipPoolWebhook.ValidateCreate(ctx, ipPoolT)
@@ -641,7 +675,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					existIPPoolT.Spec.IPs = append(existIPPoolT.Spec.IPs, "172.18.41.1-172.18.41.2")
 
 					ctx := context.TODO()
-					err := fakeClient.Create(ctx, existIPPoolT)
+					err := tracker.Add(existIPPoolT)
 					Expect(err).NotTo(HaveOccurred())
 
 					ipPoolT.Spec.IPVersion = pointer.Int64(constant.IPv4)
@@ -663,7 +697,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					existIPPoolT.Spec.IPs = append(existIPPoolT.Spec.IPs, "172.18.40.40")
 
 					ctx := context.TODO()
-					err := fakeClient.Create(ctx, existIPPoolT)
+					err := tracker.Add(existIPPoolT)
 					Expect(err).NotTo(HaveOccurred())
 
 					ipPoolT.Spec.IPVersion = pointer.Int64(constant.IPv4)
@@ -728,7 +762,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					existIPPoolT.Spec.IPs = append(existIPPoolT.Spec.IPs, constant.InvalidIPRange)
 
 					ctx := context.TODO()
-					err = fakeClient.Create(ctx, existIPPoolT)
+					err = tracker.Add(existIPPoolT)
 					Expect(err).NotTo(HaveOccurred())
 
 					ipPoolT.Spec.IPVersion = pointer.Int64(ipVersion)
@@ -757,7 +791,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					existIPPoolT.Spec.IPs = append(existIPPoolT.Spec.IPs, "172.18.40.10")
 
 					ctx := context.TODO()
-					err = fakeClient.Create(ctx, existIPPoolT)
+					err = tracker.Add(existIPPoolT)
 					Expect(err).NotTo(HaveOccurred())
 
 					ipPoolT.Spec.IPVersion = pointer.Int64(ipVersion)
@@ -1012,7 +1046,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 				})
 			})
 
-			It("creates IPv4 Subnet with all fields valid", func() {
+			It("creates IPv4 IPPool with all fields valid", func() {
 				ipPoolWebhook.EnableSpiderSubnet = true
 				subnetT.SetUID(uuid.NewUUID())
 				subnetT.Spec.IPVersion = pointer.Int64(constant.IPv4)
@@ -1025,7 +1059,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 				)
 
 				ctx := context.TODO()
-				err := fakeClient.Create(ctx, subnetT)
+				err := tracker.Add(subnetT)
 				Expect(err).NotTo(HaveOccurred())
 
 				err = controllerutil.SetControllerReference(subnetT, ipPoolT, scheme)
@@ -1053,7 +1087,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 				Expect(err).NotTo(HaveOccurred())
 			})
 
-			It("creates IPv6 Subnet with all fields valid", func() {
+			It("creates IPv6 IPPool with all fields valid", func() {
 				ipPoolWebhook.EnableSpiderSubnet = true
 				subnetT.SetUID(uuid.NewUUID())
 				subnetT.Spec.IPVersion = pointer.Int64(constant.IPv6)
@@ -1066,7 +1100,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 				)
 
 				ctx := context.TODO()
-				err := fakeClient.Create(ctx, subnetT)
+				err := tracker.Add(subnetT)
 				Expect(err).NotTo(HaveOccurred())
 
 				err = controllerutil.SetControllerReference(subnetT, ipPoolT, scheme)
@@ -1240,7 +1274,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					existIPPoolT.Spec.IPs = append(existIPPoolT.Spec.IPs, constant.InvalidIPRange)
 
 					ctx := context.TODO()
-					err = fakeClient.Create(ctx, existIPPoolT)
+					err = tracker.Add(existIPPoolT)
 					Expect(err).NotTo(HaveOccurred())
 
 					ipPoolT.Spec.IPVersion = pointer.Int64(ipVersion)
@@ -1267,7 +1301,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 					existIPPoolT.Spec.IPs = append(existIPPoolT.Spec.IPs, "172.18.40.10")
 
 					ctx := context.TODO()
-					err = fakeClient.Create(ctx, existIPPoolT)
+					err = tracker.Add(existIPPoolT)
 					Expect(err).NotTo(HaveOccurred())
 
 					ipPoolT.Spec.IPVersion = pointer.Int64(ipVersion)
@@ -1584,7 +1618,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 				Expect(apierrors.IsForbidden(err)).To(BeTrue())
 			})
 
-			It("updates IPv4 Subnet with all fields valid", func() {
+			It("updates IPv4 IPPool with all fields valid", func() {
 				ipPoolWebhook.EnableSpiderSubnet = true
 				subnetT.SetUID(uuid.NewUUID())
 				subnetT.Spec.IPVersion = pointer.Int64(constant.IPv4)
@@ -1597,7 +1631,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 				)
 
 				ctx := context.TODO()
-				err := fakeClient.Create(ctx, subnetT)
+				err := tracker.Add(subnetT)
 				Expect(err).NotTo(HaveOccurred())
 
 				err = controllerutil.SetControllerReference(subnetT, ipPoolT, scheme)
@@ -1623,7 +1657,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 				Expect(err).NotTo(HaveOccurred())
 			})
 
-			It("updates IPv6 Subnet with all fields valid", func() {
+			It("updates IPv6 IPPool with all fields valid", func() {
 				ipPoolWebhook.EnableSpiderSubnet = true
 				subnetT.SetUID(uuid.NewUUID())
 				subnetT.Spec.IPVersion = pointer.Int64(constant.IPv6)
@@ -1636,7 +1670,7 @@ var _ = Describe("IPPoolWebhook", Label("ippool_webhook_test"), func() {
 				)
 
 				ctx := context.TODO()
-				err := fakeClient.Create(ctx, subnetT)
+				err := tracker.Add(subnetT)
 				Expect(err).NotTo(HaveOccurred())
 
 				err = controllerutil.SetControllerReference(subnetT, ipPoolT, scheme)
diff --git a/pkg/namespacemanager/namespace_manager_suite_test.go b/pkg/namespacemanager/namespace_manager_suite_test.go
index cb4002a77..f4f5f836b 100644
--- a/pkg/namespacemanager/namespace_manager_suite_test.go
+++ b/pkg/namespacemanager/namespace_manager_suite_test.go
@@ -10,6 +10,8 @@ import (
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	k8sscheme "k8s.io/client-go/kubernetes/scheme"
+	k8stesting "k8s.io/client-go/testing"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
@@ -18,6 +20,8 @@ import (
 
 var scheme *runtime.Scheme
 var fakeClient client.Client
+var tracker k8stesting.ObjectTracker
+var fakeAPIReader client.Reader
 var nsManager namespacemanager.NamespaceManager
 
 func TestNamespaceManager(t *testing.T) {
@@ -34,6 +38,15 @@ var _ = BeforeSuite(func() {
 		WithScheme(scheme).
 		Build()
 
-	nsManager, err = namespacemanager.NewNamespaceManager(fakeClient)
+	tracker = k8stesting.NewObjectTracker(scheme, k8sscheme.Codecs.UniversalDecoder())
+	fakeAPIReader = fake.NewClientBuilder().
+		WithScheme(scheme).
+		WithObjectTracker(tracker).
+		Build()
+
+	nsManager, err = namespacemanager.NewNamespaceManager(
+		fakeClient,
+		fakeAPIReader,
+	)
 	Expect(err).NotTo(HaveOccurred())
 })
diff --git a/pkg/namespacemanager/namespace_manager_test.go b/pkg/namespacemanager/namespace_manager_test.go
index 8b29ded68..8fec367b1 100644
--- a/pkg/namespacemanager/namespace_manager_test.go
+++ b/pkg/namespacemanager/namespace_manager_test.go
@@ -14,6 +14,7 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/utils/pointer"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -24,19 +25,29 @@ import (
 var _ = Describe("NamespaceManager", Label("namespace_manager_test"), func() {
 	Describe("New NamespaceManager", func() {
 		It("inputs nil client", func() {
-			manager, err := namespacemanager.NewNamespaceManager(nil)
+			manager, err := namespacemanager.NewNamespaceManager(nil, fakeAPIReader)
+			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			Expect(manager).To(BeNil())
+		})
+
+		It("inputs nil API reader", func() {
+			manager, err := namespacemanager.NewNamespaceManager(fakeClient, nil)
 			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
 			Expect(manager).To(BeNil())
 		})
 	})
 
 	Describe("Test NamespaceManager's method", func() {
+		var ctx context.Context
+
 		var count uint64
 		var nsName string
 		var labels map[string]string
 		var nsT *corev1.Namespace
 
 		BeforeEach(func() {
+			ctx = context.TODO()
+
 			atomic.AddUint64(&count, 1)
 			nsName = fmt.Sprintf("namespace-%v", count)
 			labels = map[string]string{"foo": fmt.Sprintf("bar-%v", count)}
@@ -62,52 +73,85 @@ var _ = Describe("NamespaceManager", Label("namespace_manager_test"), func() {
 				PropagationPolicy:  &policy,
 			}
 
-			ctx := context.TODO()
 			err := fakeClient.Delete(ctx, nsT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    corev1.GroupName,
+					Version:  corev1.SchemeGroupVersion.Version,
+					Resource: "namespaces",
+				},
+				nsT.Namespace,
+				nsT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 		})
 
 		Describe("GetNamespaceByName", func() {
 			It("gets non-existent Namespace", func() {
-				ctx := context.TODO()
-				ns, err := nsManager.GetNamespaceByName(ctx, nsName)
+				ns, err := nsManager.GetNamespaceByName(ctx, nsName, constant.IgnoreCache)
 				Expect(apierrors.IsNotFound(err)).To(BeTrue())
 				Expect(ns).To(BeNil())
 			})
 
-			It("gets an existing Namespace", func() {
-				ctx := context.TODO()
+			It("gets an existing Namespace through cache", func() {
 				err := fakeClient.Create(ctx, nsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				ns, err := nsManager.GetNamespaceByName(ctx, nsName)
+				ns, err := nsManager.GetNamespaceByName(ctx, nsName, constant.UseCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(ns).NotTo(BeNil())
+				Expect(ns).To(Equal(nsT))
+			})
+
+			It("gets an existing Namespace through API Server", func() {
+				err := tracker.Add(nsT)
+				Expect(err).NotTo(HaveOccurred())
 
+				ns, err := nsManager.GetNamespaceByName(ctx, nsName, constant.IgnoreCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(ns).NotTo(BeNil())
 				Expect(ns).To(Equal(nsT))
 			})
 		})
 
 		Describe("ListNamespaces", func() {
 			It("failed to list Namespaces due to some unknown errors", func() {
-				patches := gomonkey.ApplyMethodReturn(fakeClient, "List", constant.ErrUnknown)
+				patches := gomonkey.ApplyMethodReturn(fakeAPIReader, "List", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, nsT)
+				err := tracker.Add(nsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				nsList, err := nsManager.ListNamespaces(ctx)
+				nsList, err := nsManager.ListNamespaces(ctx, constant.IgnoreCache)
 				Expect(err).To(MatchError(constant.ErrUnknown))
 				Expect(nsList).To(BeNil())
 			})
 
-			It("lists all Namespaces", func() {
-				ctx := context.TODO()
+			It("lists all Namespaces through cache", func() {
 				err := fakeClient.Create(ctx, nsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				nsList, err := nsManager.ListNamespaces(ctx)
+				nsList, err := nsManager.ListNamespaces(ctx, constant.UseCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(nsList.Items).NotTo(BeEmpty())
+
+				hasNS := false
+				for _, ns := range nsList.Items {
+					if ns.Name == nsName {
+						hasNS = true
+						break
+					}
+				}
+				Expect(hasNS).To(BeTrue())
+			})
+
+			It("lists all Namespaces through API Server", func() {
+				err := tracker.Add(nsT)
+				Expect(err).NotTo(HaveOccurred())
+
+				nsList, err := nsManager.ListNamespaces(ctx, constant.IgnoreCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(nsList.Items).NotTo(BeEmpty())
 
@@ -122,11 +166,10 @@ var _ = Describe("NamespaceManager", Label("namespace_manager_test"), func() {
 			})
 
 			It("filters results by label selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, nsT)
+				err := tracker.Add(nsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				nsList, err := nsManager.ListNamespaces(ctx, client.MatchingLabels(labels))
+				nsList, err := nsManager.ListNamespaces(ctx, constant.IgnoreCache, client.MatchingLabels(labels))
 				Expect(err).NotTo(HaveOccurred())
 				Expect(nsList.Items).NotTo(BeEmpty())
 
@@ -141,11 +184,10 @@ var _ = Describe("NamespaceManager", Label("namespace_manager_test"), func() {
 			})
 
 			It("filters results by field selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, nsT)
+				err := tracker.Add(nsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				nsList, err := nsManager.ListNamespaces(ctx, client.MatchingFields{metav1.ObjectNameField: nsName})
+				nsList, err := nsManager.ListNamespaces(ctx, constant.IgnoreCache, client.MatchingFields{metav1.ObjectNameField: nsName})
 				Expect(err).NotTo(HaveOccurred())
 				Expect(nsList.Items).NotTo(BeEmpty())
 
diff --git a/pkg/nodemanager/node_manager_suite_test.go b/pkg/nodemanager/node_manager_suite_test.go
index a0c443b19..336adbc06 100644
--- a/pkg/nodemanager/node_manager_suite_test.go
+++ b/pkg/nodemanager/node_manager_suite_test.go
@@ -10,6 +10,8 @@ import (
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	k8sscheme "k8s.io/client-go/kubernetes/scheme"
+	k8stesting "k8s.io/client-go/testing"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
@@ -18,6 +20,8 @@ import (
 
 var scheme *runtime.Scheme
 var fakeClient client.Client
+var tracker k8stesting.ObjectTracker
+var fakeAPIReader client.Reader
 var nodeManager nodemanager.NodeManager
 
 func TestNodeManager(t *testing.T) {
@@ -34,6 +38,15 @@ var _ = BeforeSuite(func() {
 		WithScheme(scheme).
 		Build()
 
-	nodeManager, err = nodemanager.NewNodeManager(fakeClient)
+	tracker = k8stesting.NewObjectTracker(scheme, k8sscheme.Codecs.UniversalDecoder())
+	fakeAPIReader = fake.NewClientBuilder().
+		WithScheme(scheme).
+		WithObjectTracker(tracker).
+		Build()
+
+	nodeManager, err = nodemanager.NewNodeManager(
+		fakeClient,
+		fakeAPIReader,
+	)
 	Expect(err).NotTo(HaveOccurred())
 })
diff --git a/pkg/nodemanager/node_manager_test.go b/pkg/nodemanager/node_manager_test.go
index e46c10660..89be5635b 100644
--- a/pkg/nodemanager/node_manager_test.go
+++ b/pkg/nodemanager/node_manager_test.go
@@ -14,6 +14,7 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/utils/pointer"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -24,19 +25,29 @@ import (
 var _ = Describe("NodeManager", Label("node_manager_test"), func() {
 	Describe("New NodeManager", func() {
 		It("inputs nil client", func() {
-			manager, err := nodemanager.NewNodeManager(nil)
+			manager, err := nodemanager.NewNodeManager(nil, fakeAPIReader)
+			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			Expect(manager).To(BeNil())
+		})
+
+		It("inputs nil API reader", func() {
+			manager, err := nodemanager.NewNodeManager(fakeClient, nil)
 			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
 			Expect(manager).To(BeNil())
 		})
 	})
 
 	Describe("Test NodeManager's method", func() {
+		var ctx context.Context
+
 		var count uint64
 		var nodeName string
 		var labels map[string]string
 		var nodeT *corev1.Node
 
 		BeforeEach(func() {
+			ctx = context.TODO()
+
 			atomic.AddUint64(&count, 1)
 			nodeName = fmt.Sprintf("node-%v", count)
 			labels = map[string]string{"foo": fmt.Sprintf("bar-%v", count)}
@@ -62,52 +73,85 @@ var _ = Describe("NodeManager", Label("node_manager_test"), func() {
 				PropagationPolicy:  &policy,
 			}
 
-			ctx := context.TODO()
 			err := fakeClient.Delete(ctx, nodeT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    corev1.GroupName,
+					Version:  corev1.SchemeGroupVersion.Version,
+					Resource: "nodes",
+				},
+				nodeT.Namespace,
+				nodeT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 		})
 
 		Describe("GetNodeByName", func() {
 			It("gets non-existent Node", func() {
-				ctx := context.TODO()
-				node, err := nodeManager.GetNodeByName(ctx, nodeName)
+				node, err := nodeManager.GetNodeByName(ctx, nodeName, constant.IgnoreCache)
 				Expect(apierrors.IsNotFound(err)).To(BeTrue())
 				Expect(node).To(BeNil())
 			})
 
-			It("gets an existing Node", func() {
-				ctx := context.TODO()
+			It("gets an existing Node through cache", func() {
 				err := fakeClient.Create(ctx, nodeT)
 				Expect(err).NotTo(HaveOccurred())
 
-				node, err := nodeManager.GetNodeByName(ctx, nodeName)
+				node, err := nodeManager.GetNodeByName(ctx, nodeName, constant.UseCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(node).NotTo(BeNil())
+				Expect(node).To(Equal(nodeT))
+			})
+
+			It("gets an existing Node through API Server", func() {
+				err := tracker.Add(nodeT)
+				Expect(err).NotTo(HaveOccurred())
 
+				node, err := nodeManager.GetNodeByName(ctx, nodeName, constant.IgnoreCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(node).NotTo(BeNil())
 				Expect(node).To(Equal(nodeT))
 			})
 		})
 
 		Describe("ListNodes", func() {
 			It("failed to list Nodes due to some unknown errors", func() {
-				patches := gomonkey.ApplyMethodReturn(fakeClient, "List", constant.ErrUnknown)
+				patches := gomonkey.ApplyMethodReturn(fakeAPIReader, "List", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, nodeT)
+				err := tracker.Add(nodeT)
 				Expect(err).NotTo(HaveOccurred())
 
-				nodeList, err := nodeManager.ListNodes(ctx)
+				nodeList, err := nodeManager.ListNodes(ctx, constant.IgnoreCache)
 				Expect(err).To(MatchError(constant.ErrUnknown))
 				Expect(nodeList).To(BeNil())
 			})
 
-			It("lists all Nodes", func() {
-				ctx := context.TODO()
+			It("lists all Nodes through cache", func() {
 				err := fakeClient.Create(ctx, nodeT)
 				Expect(err).NotTo(HaveOccurred())
 
-				nodeList, err := nodeManager.ListNodes(ctx)
+				nodeList, err := nodeManager.ListNodes(ctx, constant.UseCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(nodeList.Items).NotTo(BeEmpty())
+
+				hasNode := false
+				for _, node := range nodeList.Items {
+					if node.Name == nodeName {
+						hasNode = true
+						break
+					}
+				}
+				Expect(hasNode).To(BeTrue())
+			})
+
+			It("lists all Nodes through API Server", func() {
+				err := tracker.Add(nodeT)
+				Expect(err).NotTo(HaveOccurred())
+
+				nodeList, err := nodeManager.ListNodes(ctx, constant.IgnoreCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(nodeList.Items).NotTo(BeEmpty())
 
@@ -122,11 +166,10 @@ var _ = Describe("NodeManager", Label("node_manager_test"), func() {
 			})
 
 			It("filters results by label selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, nodeT)
+				err := tracker.Add(nodeT)
 				Expect(err).NotTo(HaveOccurred())
 
-				nodeList, err := nodeManager.ListNodes(ctx, client.MatchingLabels(labels))
+				nodeList, err := nodeManager.ListNodes(ctx, constant.IgnoreCache, client.MatchingLabels(labels))
 				Expect(err).NotTo(HaveOccurred())
 				Expect(nodeList.Items).NotTo(BeEmpty())
 
@@ -141,11 +184,10 @@ var _ = Describe("NodeManager", Label("node_manager_test"), func() {
 			})
 
 			It("filters results by field selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, nodeT)
+				err := tracker.Add(nodeT)
 				Expect(err).NotTo(HaveOccurred())
 
-				nodeList, err := nodeManager.ListNodes(ctx, client.MatchingFields{metav1.ObjectNameField: nodeName})
+				nodeList, err := nodeManager.ListNodes(ctx, constant.IgnoreCache, client.MatchingFields{metav1.ObjectNameField: nodeName})
 				Expect(err).NotTo(HaveOccurred())
 				Expect(nodeList.Items).NotTo(BeEmpty())
 
diff --git a/pkg/podmanager/pod_manager_suite_test.go b/pkg/podmanager/pod_manager_suite_test.go
index 63c43baab..aa3f63a4b 100644
--- a/pkg/podmanager/pod_manager_suite_test.go
+++ b/pkg/podmanager/pod_manager_suite_test.go
@@ -10,6 +10,8 @@ import (
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	k8sscheme "k8s.io/client-go/kubernetes/scheme"
+	k8stesting "k8s.io/client-go/testing"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
@@ -18,6 +20,8 @@ import (
 
 var scheme *runtime.Scheme
 var fakeClient client.Client
+var tracker k8stesting.ObjectTracker
+var fakeAPIReader client.Reader
 var podManager podmanager.PodManager
 
 func TestPodManager(t *testing.T) {
@@ -34,9 +38,15 @@ var _ = BeforeSuite(func() {
 		WithScheme(scheme).
 		Build()
 
+	tracker = k8stesting.NewObjectTracker(scheme, k8sscheme.Codecs.UniversalDecoder())
+	fakeAPIReader = fake.NewClientBuilder().
+		WithScheme(scheme).
+		WithObjectTracker(tracker).
+		Build()
+
 	podManager, err = podmanager.NewPodManager(
-		podmanager.PodManagerConfig{MaxConflictRetries: 1},
 		fakeClient,
+		fakeAPIReader,
 	)
 	Expect(err).NotTo(HaveOccurred())
 })
diff --git a/pkg/podmanager/pod_manager_test.go b/pkg/podmanager/pod_manager_test.go
index 3446d79f4..ec735a941 100644
--- a/pkg/podmanager/pod_manager_test.go
+++ b/pkg/podmanager/pod_manager_test.go
@@ -18,6 +18,7 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/utils/pointer"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -28,26 +29,27 @@ import (
 
 var _ = Describe("PodManager", Label("pod_manager_test"), func() {
 	Describe("New PodManager", func() {
-		It("sets default config", func() {
-			manager, err := podmanager.NewPodManager(podmanager.PodManagerConfig{}, fakeClient)
-			Expect(err).NotTo(HaveOccurred())
-			Expect(manager).NotTo(BeNil())
+		It("inputs nil client", func() {
+			manager, err := podmanager.NewPodManager(nil, fakeAPIReader)
+			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			Expect(manager).To(BeNil())
 		})
 
-		It("inputs nil client", func() {
-			manager, err := podmanager.NewPodManager(podmanager.PodManagerConfig{}, nil)
+		It("inputs nil API reader", func() {
+			manager, err := podmanager.NewPodManager(fakeClient, nil)
 			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
 			Expect(manager).To(BeNil())
 		})
 	})
 
 	Describe("Test PodManager's method", func() {
+		var ctx context.Context
+
 		var count uint64
 		var namespace string
 		var podName string
 		var labels map[string]string
 		var podT *corev1.Pod
-		var ctx context.Context
 
 		BeforeEach(func() {
 			ctx = context.TODO()
@@ -79,52 +81,85 @@ var _ = Describe("PodManager", Label("pod_manager_test"), func() {
 				PropagationPolicy:  &policy,
 			}
 
-			ctx := context.TODO()
 			err := fakeClient.Delete(ctx, podT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    corev1.GroupName,
+					Version:  corev1.SchemeGroupVersion.Version,
+					Resource: "pods",
+				},
+				podT.Namespace,
+				podT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 		})
 
 		Describe("GetPodByName", func() {
 			It("gets non-existent Pod", func() {
-				ctx := context.TODO()
-				pod, err := podManager.GetPodByName(ctx, namespace, podName)
+				pod, err := podManager.GetPodByName(ctx, namespace, podName, constant.IgnoreCache)
 				Expect(apierrors.IsNotFound(err)).To(BeTrue())
 				Expect(pod).To(BeNil())
 			})
 
-			It("gets an existing Pod", func() {
-				ctx := context.TODO()
+			It("gets an existing Pod through cache", func() {
 				err := fakeClient.Create(ctx, podT)
 				Expect(err).NotTo(HaveOccurred())
 
-				pod, err := podManager.GetPodByName(ctx, namespace, podName)
+				pod, err := podManager.GetPodByName(ctx, namespace, podName, constant.UseCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(pod).NotTo(BeNil())
+				Expect(pod).To(Equal(podT))
+			})
+
+			It("gets an existing Pod through API Server", func() {
+				err := tracker.Add(podT)
+				Expect(err).NotTo(HaveOccurred())
 
+				pod, err := podManager.GetPodByName(ctx, namespace, podName, constant.IgnoreCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(pod).NotTo(BeNil())
 				Expect(pod).To(Equal(podT))
 			})
 		})
 
 		Describe("ListPods", func() {
 			It("failed to list Pods due to some unknown errors", func() {
-				patches := gomonkey.ApplyMethodReturn(fakeClient, "List", constant.ErrUnknown)
+				patches := gomonkey.ApplyMethodReturn(fakeAPIReader, "List", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, podT)
+				err := tracker.Add(podT)
 				Expect(err).NotTo(HaveOccurred())
 
-				podList, err := podManager.ListPods(ctx)
+				podList, err := podManager.ListPods(ctx, constant.IgnoreCache)
 				Expect(err).To(MatchError(constant.ErrUnknown))
 				Expect(podList).To(BeNil())
 			})
 
-			It("lists all Pods", func() {
-				ctx := context.TODO()
+			It("lists all Pods through cache", func() {
 				err := fakeClient.Create(ctx, podT)
 				Expect(err).NotTo(HaveOccurred())
 
-				podList, err := podManager.ListPods(ctx)
+				podList, err := podManager.ListPods(ctx, constant.UseCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(podList.Items).NotTo(BeEmpty())
+
+				hasPod := false
+				for _, pod := range podList.Items {
+					if pod.Name == podName {
+						hasPod = true
+						break
+					}
+				}
+				Expect(hasPod).To(BeTrue())
+			})
+
+			It("lists all Pods through API Server", func() {
+				err := tracker.Add(podT)
+				Expect(err).NotTo(HaveOccurred())
+
+				podList, err := podManager.ListPods(ctx, constant.IgnoreCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(podList.Items).NotTo(BeEmpty())
 
@@ -139,11 +174,10 @@ var _ = Describe("PodManager", Label("pod_manager_test"), func() {
 			})
 
 			It("filters results by Namespace", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, podT)
+				err := tracker.Add(podT)
 				Expect(err).NotTo(HaveOccurred())
 
-				podList, err := podManager.ListPods(ctx, client.InNamespace(namespace))
+				podList, err := podManager.ListPods(ctx, constant.IgnoreCache, client.InNamespace(namespace))
 				Expect(err).NotTo(HaveOccurred())
 				Expect(podList.Items).NotTo(BeEmpty())
 
@@ -158,11 +192,10 @@ var _ = Describe("PodManager", Label("pod_manager_test"), func() {
 			})
 
 			It("filters results by label selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, podT)
+				err := tracker.Add(podT)
 				Expect(err).NotTo(HaveOccurred())
 
-				podList, err := podManager.ListPods(ctx, client.MatchingLabels(labels))
+				podList, err := podManager.ListPods(ctx, constant.IgnoreCache, client.MatchingLabels(labels))
 				Expect(err).NotTo(HaveOccurred())
 				Expect(podList.Items).NotTo(BeEmpty())
 
@@ -177,11 +210,10 @@ var _ = Describe("PodManager", Label("pod_manager_test"), func() {
 			})
 
 			It("filters results by field selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, podT)
+				err := tracker.Add(podT)
 				Expect(err).NotTo(HaveOccurred())
 
-				podList, err := podManager.ListPods(ctx, client.MatchingFields{metav1.ObjectNameField: podName})
+				podList, err := podManager.ListPods(ctx, constant.IgnoreCache, client.MatchingFields{metav1.ObjectNameField: podName})
 				Expect(err).NotTo(HaveOccurred())
 				Expect(podList.Items).NotTo(BeEmpty())
 
diff --git a/pkg/reservedipmanager/reservedip_manager_suite_test.go b/pkg/reservedipmanager/reservedip_manager_suite_test.go
index 8cd163591..54893826a 100644
--- a/pkg/reservedipmanager/reservedip_manager_suite_test.go
+++ b/pkg/reservedipmanager/reservedip_manager_suite_test.go
@@ -9,6 +9,9 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	"k8s.io/apimachinery/pkg/runtime"
+
+	k8sscheme "k8s.io/client-go/kubernetes/scheme"
+	k8stesting "k8s.io/client-go/testing"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
@@ -18,6 +21,8 @@ import (
 
 var scheme *runtime.Scheme
 var fakeClient client.Client
+var tracker k8stesting.ObjectTracker
+var fakeAPIReader client.Reader
 var rIPManager reservedipmanager.ReservedIPManager
 var rIPWebhook *reservedipmanager.ReservedIPWebhook
 
@@ -35,10 +40,17 @@ var _ = BeforeSuite(func() {
 		WithScheme(scheme).
 		Build()
 
-	rIPManager, err = reservedipmanager.NewReservedIPManager(fakeClient)
+	tracker = k8stesting.NewObjectTracker(scheme, k8sscheme.Codecs.UniversalDecoder())
+	fakeAPIReader = fake.NewClientBuilder().
+		WithScheme(scheme).
+		WithObjectTracker(tracker).
+		Build()
+
+	rIPManager, err = reservedipmanager.NewReservedIPManager(
+		fakeClient,
+		fakeAPIReader,
+	)
 	Expect(err).NotTo(HaveOccurred())
 
-	rIPWebhook = &reservedipmanager.ReservedIPWebhook{
-		Client: fakeClient,
-	}
+	rIPWebhook = &reservedipmanager.ReservedIPWebhook{}
 })
diff --git a/pkg/reservedipmanager/reservedip_manager_test.go b/pkg/reservedipmanager/reservedip_manager_test.go
index 64c7c9d27..251ba2fb5 100644
--- a/pkg/reservedipmanager/reservedip_manager_test.go
+++ b/pkg/reservedipmanager/reservedip_manager_test.go
@@ -14,6 +14,7 @@ import (
 	. "github.com/onsi/gomega"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/utils/pointer"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -26,19 +27,29 @@ import (
 var _ = Describe("ReservedIPManager", Label("reservedip_manager_test"), func() {
 	Describe("New ReservedIPManager", func() {
 		It("inputs nil client", func() {
-			manager, err := reservedipmanager.NewReservedIPManager(nil)
+			manager, err := reservedipmanager.NewReservedIPManager(nil, fakeAPIReader)
+			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			Expect(manager).To(BeNil())
+		})
+
+		It("inputs nil API reader", func() {
+			manager, err := reservedipmanager.NewReservedIPManager(fakeClient, nil)
 			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
 			Expect(manager).To(BeNil())
 		})
 	})
 
 	Describe("Test ReservedIPManager's method", func() {
+		var ctx context.Context
+
 		var count uint64
 		var rIPName string
 		var labels map[string]string
 		var rIPT, terminatingV4RIPT *spiderpoolv1.SpiderReservedIP
 
 		BeforeEach(func() {
+			ctx = context.TODO()
+
 			atomic.AddUint64(&count, 1)
 			rIPName = fmt.Sprintf("reservedip-%v", count)
 			labels = map[string]string{"foo": fmt.Sprintf("bar-%v", count)}
@@ -83,55 +94,99 @@ var _ = Describe("ReservedIPManager", Label("reservedip_manager_test"), func() {
 				PropagationPolicy:  &policy,
 			}
 
-			ctx := context.TODO()
 			err := fakeClient.Delete(ctx, rIPT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 
 			err = fakeClient.Delete(ctx, terminatingV4RIPT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    constant.SpiderpoolAPIGroup,
+					Version:  constant.SpiderpoolAPIVersionV1,
+					Resource: "spiderreservedips",
+				},
+				rIPT.Namespace,
+				rIPT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    constant.SpiderpoolAPIGroup,
+					Version:  constant.SpiderpoolAPIVersionV1,
+					Resource: "spiderendpoints",
+				},
+				terminatingV4RIPT.Namespace,
+				terminatingV4RIPT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 		})
 
 		Describe("GetReservedIPByName", func() {
 			It("gets non-existent ReservedIP", func() {
-				ctx := context.TODO()
-				rIP, err := rIPManager.GetReservedIPByName(ctx, rIPName)
+				rIP, err := rIPManager.GetReservedIPByName(ctx, rIPName, constant.IgnoreCache)
 				Expect(apierrors.IsNotFound(err)).To(BeTrue())
 				Expect(rIP).To(BeNil())
 			})
 
-			It("gets an existing ReservedIP", func() {
-				ctx := context.TODO()
+			It("gets an existing ReservedIP through cache", func() {
 				err := fakeClient.Create(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 
-				rIP, err := rIPManager.GetReservedIPByName(ctx, rIPName)
+				rIP, err := rIPManager.GetReservedIPByName(ctx, rIPName, constant.UseCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(rIP).NotTo(BeNil())
+				Expect(rIP).To(Equal(rIPT))
+			})
 
+			It("gets an existing ReservedIP through API Server", func() {
+				err := tracker.Add(rIPT)
+				Expect(err).NotTo(HaveOccurred())
+
+				rIP, err := rIPManager.GetReservedIPByName(ctx, rIPName, constant.IgnoreCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(rIP).NotTo(BeNil())
 				Expect(rIP).To(Equal(rIPT))
 			})
 		})
 
 		Describe("ListReservedIPs", func() {
 			It("failed to list ReservedIPs due to some unknown errors", func() {
-				patches := gomonkey.ApplyMethodReturn(fakeClient, "List", constant.ErrUnknown)
+				patches := gomonkey.ApplyMethodReturn(fakeAPIReader, "List", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, rIPT)
+				err := tracker.Add(rIPT)
 				Expect(err).NotTo(HaveOccurred())
 
-				rIPList, err := rIPManager.ListReservedIPs(ctx)
+				rIPList, err := rIPManager.ListReservedIPs(ctx, constant.IgnoreCache)
 				Expect(err).To(MatchError(constant.ErrUnknown))
 				Expect(rIPList).To(BeNil())
 			})
 
-			It("lists all ReservedIPs", func() {
-				ctx := context.TODO()
+			It("lists all ReservedIPs through cache", func() {
 				err := fakeClient.Create(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 
-				rIPList, err := rIPManager.ListReservedIPs(ctx)
+				rIPList, err := rIPManager.ListReservedIPs(ctx, constant.UseCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(rIPList.Items).NotTo(BeEmpty())
+
+				hasRIP := false
+				for _, rIP := range rIPList.Items {
+					if rIP.Name == rIPName {
+						hasRIP = true
+						break
+					}
+				}
+				Expect(hasRIP).To(BeTrue())
+			})
+
+			It("lists all ReservedIPs through API Server", func() {
+				err := tracker.Add(rIPT)
+				Expect(err).NotTo(HaveOccurred())
+
+				rIPList, err := rIPManager.ListReservedIPs(ctx, constant.IgnoreCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(rIPList.Items).NotTo(BeEmpty())
 
@@ -146,11 +201,10 @@ var _ = Describe("ReservedIPManager", Label("reservedip_manager_test"), func() {
 			})
 
 			It("filters results by label selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, rIPT)
+				err := tracker.Add(rIPT)
 				Expect(err).NotTo(HaveOccurred())
 
-				rIPList, err := rIPManager.ListReservedIPs(ctx, client.MatchingLabels(labels))
+				rIPList, err := rIPManager.ListReservedIPs(ctx, constant.IgnoreCache, client.MatchingLabels(labels))
 				Expect(err).NotTo(HaveOccurred())
 				Expect(rIPList.Items).NotTo(BeEmpty())
 
@@ -165,11 +219,10 @@ var _ = Describe("ReservedIPManager", Label("reservedip_manager_test"), func() {
 			})
 
 			It("filters results by field selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, rIPT)
+				err := tracker.Add(rIPT)
 				Expect(err).NotTo(HaveOccurred())
 
-				rIPList, err := rIPManager.ListReservedIPs(ctx, client.MatchingFields{metav1.ObjectNameField: rIPName})
+				rIPList, err := rIPManager.ListReservedIPs(ctx, constant.IgnoreCache, client.MatchingFields{metav1.ObjectNameField: rIPName})
 				Expect(err).NotTo(HaveOccurred())
 				Expect(rIPList.Items).NotTo(BeEmpty())
 
@@ -186,7 +239,6 @@ var _ = Describe("ReservedIPManager", Label("reservedip_manager_test"), func() {
 
 		Describe("AssembleReservedIPs", func() {
 			It("inputs invalid IP version", func() {
-				ctx := context.TODO()
 				ips, err := rIPManager.AssembleReservedIPs(ctx, constant.InvalidIPVersion)
 				Expect(err).To(MatchError(spiderpoolip.ErrInvalidIPVersion))
 				Expect(ips).To(BeEmpty())
@@ -196,7 +248,6 @@ var _ = Describe("ReservedIPManager", Label("reservedip_manager_test"), func() {
 				patches := gomonkey.ApplyMethodReturn(fakeClient, "List", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
 				ips, err := rIPManager.AssembleReservedIPs(ctx, constant.IPv4)
 				Expect(err).To(MatchError(constant.ErrUnknown))
 				Expect(ips).To(BeEmpty())
@@ -209,7 +260,6 @@ var _ = Describe("ReservedIPManager", Label("reservedip_manager_test"), func() {
 					"172.18.40.10",
 				}
 
-				ctx := context.TODO()
 				err := fakeClient.Create(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 
@@ -231,7 +281,6 @@ var _ = Describe("ReservedIPManager", Label("reservedip_manager_test"), func() {
 				rIPT.Spec.IPVersion = pointer.Int64(constant.IPv4)
 				rIPT.Spec.IPs = append(rIPT.Spec.IPs, constant.InvalidIPRange)
 
-				ctx := context.TODO()
 				err := fakeClient.Create(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 
diff --git a/pkg/reservedipmanager/reservedip_webhook_test.go b/pkg/reservedipmanager/reservedip_webhook_test.go
index 7710bc675..6210ea7c9 100644
--- a/pkg/reservedipmanager/reservedip_webhook_test.go
+++ b/pkg/reservedipmanager/reservedip_webhook_test.go
@@ -40,6 +40,8 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 	})
 
 	Describe("Test ReservedIPWebhook's method", func() {
+		var ctx context.Context
+
 		var count uint64
 		var rIPName string
 		var rIPT *spiderpoolv1.SpiderReservedIP
@@ -49,6 +51,8 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 			rIPWebhook.EnableIPv4 = true
 			rIPWebhook.EnableIPv6 = true
 
+			ctx = context.TODO()
+
 			atomic.AddUint64(&count, 1)
 			rIPName = fmt.Sprintf("reservedip-%v", count)
 			rIPT = &spiderpoolv1.SpiderReservedIP{
@@ -72,7 +76,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 				PropagationPolicy:  &policy,
 			}
 
-			ctx := context.TODO()
 			err := fakeClient.Delete(ctx, rIPT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 		})
@@ -82,13 +85,11 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 				now := metav1.Now()
 				rIPT.SetDeletionTimestamp(&now)
 
-				ctx := context.TODO()
 				err := rIPWebhook.Default(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 			})
 
 			It("avoids modifying the ReservedIP whose 'spec.ips' is empty", func() {
-				ctx := context.TODO()
 				err := rIPWebhook.Default(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -96,7 +97,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 			It("failed to set 'spec.ipVersion' due to the first IP range of 'spec.ips' is invalid", func() {
 				rIPT.Spec.IPs = append(rIPT.Spec.IPs, constant.InvalidIPRange)
 
-				ctx := context.TODO()
 				err := rIPWebhook.Default(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(rIPT.Spec.IPVersion).To(BeNil())
@@ -105,7 +105,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 			It("sets 'spec.ipVersion' to 4", func() {
 				rIPT.Spec.IPs = append(rIPT.Spec.IPs, "172.18.40.1-172.18.40.2")
 
-				ctx := context.TODO()
 				err := rIPWebhook.Default(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(*rIPT.Spec.IPVersion).To(Equal(constant.IPv4))
@@ -114,7 +113,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 			It("sets 'spec.ipVersion' to 6", func() {
 				rIPT.Spec.IPs = append(rIPT.Spec.IPs, "abcd:1234::1-abcd:1234::2")
 
-				ctx := context.TODO()
 				err := rIPWebhook.Default(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(*rIPT.Spec.IPVersion).To(Equal(constant.IPv6))
@@ -130,7 +128,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := rIPWebhook.Default(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(rIPT.Spec.IPs).To(Equal(
@@ -153,7 +150,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := rIPWebhook.Default(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(rIPT.Spec.IPs).To(Equal(
@@ -176,7 +172,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := rIPWebhook.Default(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(rIPT.Spec.IPs).To(Equal(
@@ -197,7 +192,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := rIPWebhook.Default(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(rIPT.Spec.IPs).To(Equal(
@@ -212,7 +206,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 		Describe("ValidateCreate", func() {
 			When("Validating 'spec.ipVersion'", func() {
 				It("inputs nil 'spec.ipVersion'", func() {
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateCreate(ctx, rIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -220,7 +213,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 				It("inputs invalid 'spec.ipVersion'", func() {
 					rIPT.Spec.IPVersion = pointer.Int64(constant.InvalidIPVersion)
 
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateCreate(ctx, rIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -229,7 +221,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					rIPWebhook.EnableIPv4 = false
 					rIPT.Spec.IPVersion = pointer.Int64(constant.IPv4)
 
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateCreate(ctx, rIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -238,7 +229,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					rIPWebhook.EnableIPv6 = false
 					rIPT.Spec.IPVersion = pointer.Int64(constant.IPv6)
 
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateCreate(ctx, rIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -249,7 +239,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					rIPT.Spec.IPVersion = pointer.Int64(constant.IPv4)
 					rIPT.Spec.IPs = append(rIPT.Spec.IPs, constant.InvalidIPRange)
 
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateCreate(ctx, rIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -264,7 +253,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := rIPWebhook.ValidateCreate(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -278,7 +266,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := rIPWebhook.ValidateCreate(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -292,7 +279,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					newRIPT := rIPT.DeepCopy()
 					newRIPT.Spec.IPVersion = nil
 
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateUpdate(ctx, rIPT, newRIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -303,7 +289,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					newRIPT := rIPT.DeepCopy()
 					newRIPT.Spec.IPVersion = pointer.Int64(constant.IPv6)
 
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateUpdate(ctx, rIPT, newRIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -315,7 +300,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					newRIPT := rIPT.DeepCopy()
 					newRIPT.Spec.IPs = append(newRIPT.Spec.IPs, "172.18.40.10")
 
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateUpdate(ctx, rIPT, newRIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -327,7 +311,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					newRIPT := rIPT.DeepCopy()
 					newRIPT.Spec.IPs = append(newRIPT.Spec.IPs, "adbc:1234::a")
 
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateUpdate(ctx, rIPT, newRIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -340,7 +323,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 					newRIPT := rIPT.DeepCopy()
 					newRIPT.Spec.IPs = append(newRIPT.Spec.IPs, constant.InvalidIPRange)
 
-					ctx := context.TODO()
 					err := rIPWebhook.ValidateUpdate(ctx, rIPT, newRIPT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -352,7 +334,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 				newRIPT.SetDeletionTimestamp(&now)
 				newRIPT.SetDeletionGracePeriodSeconds(pointer.Int64(0))
 
-				ctx := context.TODO()
 				err := rIPWebhook.ValidateUpdate(ctx, rIPT, newRIPT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -363,7 +344,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 				rIPT.SetDeletionGracePeriodSeconds(pointer.Int64(30))
 				newRIPT := rIPT.DeepCopy()
 
-				ctx := context.TODO()
 				err := rIPWebhook.ValidateUpdate(ctx, rIPT, newRIPT)
 				Expect(apierrors.IsForbidden(err)).To(BeTrue())
 			})
@@ -375,7 +355,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 				newRIPT := rIPT.DeepCopy()
 				newRIPT.Spec.IPs = append(newRIPT.Spec.IPs, "172.18.40.10")
 
-				ctx := context.TODO()
 				err := rIPWebhook.ValidateUpdate(ctx, rIPT, newRIPT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -387,7 +366,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 				newRIPT := rIPT.DeepCopy()
 				newRIPT.Spec.IPs = append(newRIPT.Spec.IPs, "abcd:1234::a")
 
-				ctx := context.TODO()
 				err := rIPWebhook.ValidateUpdate(ctx, rIPT, newRIPT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -395,7 +373,6 @@ var _ = Describe("ReservedIPWebhook", Label("reservedip_webhook_test"), func() {
 
 		Describe("ValidateDelete", func() {
 			It("passes", func() {
-				ctx := context.TODO()
 				err := rIPWebhook.ValidateDelete(ctx, rIPT)
 				Expect(err).NotTo(HaveOccurred())
 			})
diff --git a/pkg/statefulsetmanager/sts_manager_suite_test.go b/pkg/statefulsetmanager/sts_manager_suite_test.go
index a4e1f7715..758770154 100644
--- a/pkg/statefulsetmanager/sts_manager_suite_test.go
+++ b/pkg/statefulsetmanager/sts_manager_suite_test.go
@@ -10,6 +10,8 @@ import (
 	. "github.com/onsi/gomega"
 	appsv1 "k8s.io/api/apps/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	k8sscheme "k8s.io/client-go/kubernetes/scheme"
+	k8stesting "k8s.io/client-go/testing"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
@@ -18,6 +20,8 @@ import (
 
 var scheme *runtime.Scheme
 var fakeClient client.Client
+var tracker k8stesting.ObjectTracker
+var fakeAPIReader client.Reader
 var stsManager statefulsetmanager.StatefulSetManager
 
 func TestStatefulSetManager(t *testing.T) {
@@ -34,6 +38,15 @@ var _ = BeforeSuite(func() {
 		WithScheme(scheme).
 		Build()
 
-	stsManager, err = statefulsetmanager.NewStatefulSetManager(fakeClient)
+	tracker = k8stesting.NewObjectTracker(scheme, k8sscheme.Codecs.UniversalDecoder())
+	fakeAPIReader = fake.NewClientBuilder().
+		WithScheme(scheme).
+		WithObjectTracker(tracker).
+		Build()
+
+	stsManager, err = statefulsetmanager.NewStatefulSetManager(
+		fakeClient,
+		fakeAPIReader,
+	)
 	Expect(err).NotTo(HaveOccurred())
 })
diff --git a/pkg/statefulsetmanager/sts_manager_test.go b/pkg/statefulsetmanager/sts_manager_test.go
index df1ab95b1..d19c79891 100644
--- a/pkg/statefulsetmanager/sts_manager_test.go
+++ b/pkg/statefulsetmanager/sts_manager_test.go
@@ -15,6 +15,7 @@ import (
 	appsv1 "k8s.io/api/apps/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/utils/pointer"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -25,13 +26,21 @@ import (
 var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 	Describe("New StatefulSetManager", func() {
 		It("inputs nil client", func() {
-			manager, err := statefulsetmanager.NewStatefulSetManager(nil)
+			manager, err := statefulsetmanager.NewStatefulSetManager(nil, fakeAPIReader)
+			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			Expect(manager).To(BeNil())
+		})
+
+		It("inputs nil API reader", func() {
+			manager, err := statefulsetmanager.NewStatefulSetManager(fakeClient, nil)
 			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
 			Expect(manager).To(BeNil())
 		})
 	})
 
 	Describe("Test StatefulSetManager's method", func() {
+		var ctx context.Context
+
 		var count uint64
 		var namespace string
 		var stsName string
@@ -39,6 +48,8 @@ var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 		var stsT *appsv1.StatefulSet
 
 		BeforeEach(func() {
+			ctx = context.TODO()
+
 			atomic.AddUint64(&count, 1)
 			namespace = "default"
 			stsName = fmt.Sprintf("sts-%v", count)
@@ -66,52 +77,85 @@ var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 				PropagationPolicy:  &policy,
 			}
 
-			ctx := context.TODO()
 			err := fakeClient.Delete(ctx, stsT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    appsv1.GroupName,
+					Version:  appsv1.SchemeGroupVersion.Version,
+					Resource: "statefulsets",
+				},
+				stsT.Namespace,
+				stsT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 		})
 
 		Describe("GetStatefulSetByName", func() {
 			It("gets non-existent StatefulSet", func() {
-				ctx := context.TODO()
-				sts, err := stsManager.GetStatefulSetByName(ctx, namespace, stsName)
+				sts, err := stsManager.GetStatefulSetByName(ctx, namespace, stsName, constant.IgnoreCache)
 				Expect(apierrors.IsNotFound(err)).To(BeTrue())
 				Expect(sts).To(BeNil())
 			})
 
-			It("gets an existing StatefulSet", func() {
-				ctx := context.TODO()
+			It("gets an existing StatefulSet through cache", func() {
 				err := fakeClient.Create(ctx, stsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				sts, err := stsManager.GetStatefulSetByName(ctx, namespace, stsName)
+				sts, err := stsManager.GetStatefulSetByName(ctx, namespace, stsName, constant.UseCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(sts).NotTo(BeNil())
+				Expect(sts).To(Equal(stsT))
+			})
 
+			It("gets an existing StatefulSet through API Server", func() {
+				err := tracker.Add(stsT)
+				Expect(err).NotTo(HaveOccurred())
+
+				sts, err := stsManager.GetStatefulSetByName(ctx, namespace, stsName, constant.IgnoreCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(sts).NotTo(BeNil())
 				Expect(sts).To(Equal(stsT))
 			})
 		})
 
 		Describe("ListStatefulSets", func() {
 			It("failed to list StatefulSets due to some unknown errors", func() {
-				patches := gomonkey.ApplyMethodReturn(fakeClient, "List", constant.ErrUnknown)
+				patches := gomonkey.ApplyMethodReturn(fakeAPIReader, "List", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, stsT)
+				err := tracker.Add(stsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				stsList, err := stsManager.ListStatefulSets(ctx)
+				stsList, err := stsManager.ListStatefulSets(ctx, constant.IgnoreCache)
 				Expect(err).To(MatchError(constant.ErrUnknown))
 				Expect(stsList).To(BeNil())
 			})
 
-			It("lists all StatefulSets", func() {
-				ctx := context.TODO()
+			It("lists all StatefulSets through cache", func() {
 				err := fakeClient.Create(ctx, stsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				stsList, err := stsManager.ListStatefulSets(ctx)
+				stsList, err := stsManager.ListStatefulSets(ctx, constant.UseCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(stsList.Items).NotTo(BeEmpty())
+
+				hasSts := false
+				for _, sts := range stsList.Items {
+					if sts.Name == stsName {
+						hasSts = true
+						break
+					}
+				}
+				Expect(hasSts).To(BeTrue())
+			})
+
+			It("lists all StatefulSets through API Server", func() {
+				err := tracker.Add(stsT)
+				Expect(err).NotTo(HaveOccurred())
+
+				stsList, err := stsManager.ListStatefulSets(ctx, constant.IgnoreCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(stsList.Items).NotTo(BeEmpty())
 
@@ -126,11 +170,10 @@ var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 			})
 
 			It("filters results by Namespace", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, stsT)
+				err := tracker.Add(stsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				stsList, err := stsManager.ListStatefulSets(ctx, client.InNamespace(namespace))
+				stsList, err := stsManager.ListStatefulSets(ctx, constant.IgnoreCache, client.InNamespace(namespace))
 				Expect(err).NotTo(HaveOccurred())
 				Expect(stsList.Items).NotTo(BeEmpty())
 
@@ -145,11 +188,10 @@ var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 			})
 
 			It("filters results by label selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, stsT)
+				err := tracker.Add(stsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				stsList, err := stsManager.ListStatefulSets(ctx, client.MatchingLabels(labels))
+				stsList, err := stsManager.ListStatefulSets(ctx, constant.IgnoreCache, client.MatchingLabels(labels))
 				Expect(err).NotTo(HaveOccurred())
 				Expect(stsList.Items).NotTo(BeEmpty())
 
@@ -164,11 +206,10 @@ var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 			})
 
 			It("filters results by field selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, stsT)
+				err := tracker.Add(stsT)
 				Expect(err).NotTo(HaveOccurred())
 
-				stsList, err := stsManager.ListStatefulSets(ctx, client.MatchingFields{metav1.ObjectNameField: stsName})
+				stsList, err := stsManager.ListStatefulSets(ctx, constant.IgnoreCache, client.MatchingFields{metav1.ObjectNameField: stsName})
 				Expect(err).NotTo(HaveOccurred())
 				Expect(stsList.Items).NotTo(BeEmpty())
 
@@ -185,7 +226,6 @@ var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 
 		Describe("IsValidStatefulSetPod", func() {
 			It("is not a Pod of StatefulSet", func() {
-				ctx := context.TODO()
 				valid := stsManager.IsValidStatefulSetPod(ctx, stsT.Namespace, "invalid")
 				Expect(valid).To(BeFalse())
 			})
@@ -194,22 +234,19 @@ var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 				patches := gomonkey.ApplyFuncReturn(strconv.ParseInt, int64(0), constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
 				valid := stsManager.IsValidStatefulSetPod(ctx, stsT.Namespace, fmt.Sprintf("%s-%d", stsName, 0))
 				Expect(valid).To(BeFalse())
 			})
 
 			It("is a valid Pod controlled by StatefulSet, but the StatefulSet no longer exists", func() {
-				ctx := context.TODO()
 				valid := stsManager.IsValidStatefulSetPod(ctx, stsT.Namespace, fmt.Sprintf("%s-%d", stsName, 0))
 				Expect(valid).To(BeFalse())
 			})
 
 			It("failed to get StatefulSets due to some unknown errors", func() {
-				patches := gomonkey.ApplyMethodReturn(fakeClient, "Get", constant.ErrUnknown)
+				patches := gomonkey.ApplyMethodReturn(fakeAPIReader, "Get", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
 				valid := stsManager.IsValidStatefulSetPod(ctx, stsT.Namespace, fmt.Sprintf("%s-%d", stsName, 0))
 				Expect(valid).To(BeTrue())
 			})
@@ -218,8 +255,7 @@ var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 				replicas := int32(1)
 				stsT.Spec.Replicas = &replicas
 
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, stsT)
+				err := tracker.Add(stsT)
 				Expect(err).NotTo(HaveOccurred())
 
 				valid := stsManager.IsValidStatefulSetPod(ctx, stsT.Namespace, fmt.Sprintf("%s-%d", stsName, replicas))
@@ -230,8 +266,7 @@ var _ = Describe("StatefulSetManager", Label("sts_manager_test"), func() {
 				replicas := int32(1)
 				stsT.Spec.Replicas = &replicas
 
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, stsT)
+				err := tracker.Add(stsT)
 				Expect(err).NotTo(HaveOccurred())
 
 				valid := stsManager.IsValidStatefulSetPod(ctx, stsT.Namespace, fmt.Sprintf("%s-%d", stsName, replicas-1))
diff --git a/pkg/subnetmanager/subnet_informer_test.go b/pkg/subnetmanager/subnet_informer_test.go
index 64beb5161..4427b79b4 100644
--- a/pkg/subnetmanager/subnet_informer_test.go
+++ b/pkg/subnetmanager/subnet_informer_test.go
@@ -33,6 +33,8 @@ import (
 
 var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 	Describe("SYNC", func() {
+		var ctx context.Context
+
 		var count uint64
 		var subnetName string
 		var subnetT *spiderpoolv1.SpiderSubnet
@@ -46,6 +48,8 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 		BeforeEach(func() {
 			subnetmanager.InformerLogger = logutils.Logger.Named("Subnet-Informer")
 
+			ctx = context.TODO()
+
 			atomic.AddUint64(&count, 1)
 			subnetName = fmt.Sprintf("subnet-%v", count)
 			subnetT = &spiderpoolv1.SpiderSubnet{
@@ -74,7 +78,7 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 
 			subnetController = &subnetmanager.SubnetController{
 				Client:                  fakeClient,
-				Scheme:                  scheme,
+				APIReader:               fakeClient,
 				LeaderRetryElectGap:     time.Second,
 				SubnetControllerWorkers: 1,
 				MaxWorkqueueLength:      1,
@@ -88,7 +92,7 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 				Return(true).
 				AnyTimes()
 
-			ctx, cancel := context.WithCancel(context.Background())
+			bCtx, cancel := context.WithCancel(context.Background())
 			DeferCleanup(cancel)
 
 			fakeSubnetWatch = watch.NewFake()
@@ -97,7 +101,7 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 			fakeClientset.PrependWatchReactor("spidersubnets", testing.DefaultWatchReactor(fakeSubnetWatch, nil))
 			fakeClientset.PrependWatchReactor("spiderippools", testing.DefaultWatchReactor(fakeIPPoolWatch, nil))
 
-			err := subnetController.SetupInformer(ctx, fakeClientset, mockLeaderElector)
+			err := subnetController.SetupInformer(bCtx, fakeClientset, mockLeaderElector)
 			Expect(err).NotTo(HaveOccurred())
 			Eventually(func(g Gomega) {
 				g.Expect(subnetController.SubnetIndexer).NotTo(BeNil())
@@ -105,7 +109,6 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 				subnetIndexer = subnetController.SubnetIndexer
 				ipPoolIndexer = subnetController.IPPoolIndexer
 			}).Should(Succeed())
-
 		})
 
 		var deleteOption *client.DeleteOptions
@@ -117,7 +120,6 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 				PropagationPolicy:  &policy,
 			}
 
-			ctx := context.TODO()
 			err := fakeClient.Delete(ctx, ipPoolT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 
@@ -135,7 +137,6 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 			subnetT.Spec.IPVersion = &ipVersion
 			subnetT.Spec.Subnet = subnet
 
-			ctx := context.TODO()
 			err = fakeClient.Create(ctx, subnetT)
 			Expect(err).NotTo(HaveOccurred())
 
@@ -159,7 +160,6 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 			subnetT.Spec.IPVersion = pointer.Int64(constant.IPv4)
 			subnetT.Spec.Subnet = "172.18.40.0/24"
 
-			ctx := context.TODO()
 			err := fakeClient.Create(ctx, subnetT)
 			Expect(err).NotTo(HaveOccurred())
 
@@ -200,7 +200,6 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 			subnetT.Spec.Subnet = "172.18.40.0/24"
 			subnetT.Spec.IPs = append(subnetT.Spec.IPs, "172.18.40.10")
 
-			ctx := context.TODO()
 			err := fakeClient.Create(ctx, subnetT)
 			Expect(err).NotTo(HaveOccurred())
 
@@ -244,7 +243,6 @@ var _ = Describe("SubnetController", Label("subnet_controller_test"), func() {
 			subnetT.Spec.IPVersion = pointer.Int64(constant.IPv4)
 			subnetT.Spec.Subnet = "172.18.40.0/24"
 
-			ctx := context.TODO()
 			err := fakeClient.Create(ctx, subnetT)
 			Expect(err).NotTo(HaveOccurred())
 
diff --git a/pkg/subnetmanager/subnet_manager_suite_test.go b/pkg/subnetmanager/subnet_manager_suite_test.go
index d1fff13ac..d078a06b0 100644
--- a/pkg/subnetmanager/subnet_manager_suite_test.go
+++ b/pkg/subnetmanager/subnet_manager_suite_test.go
@@ -10,6 +10,8 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	"k8s.io/apimachinery/pkg/runtime"
+	k8sscheme "k8s.io/client-go/kubernetes/scheme"
+	k8stesting "k8s.io/client-go/testing"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
@@ -23,6 +25,8 @@ var mockLeaderElector *electionmock.MockSpiderLeaseElector
 
 var scheme *runtime.Scheme
 var fakeClient client.Client
+var tracker k8stesting.ObjectTracker
+var fakeAPIReader client.Reader
 var subnetWebhook *subnetmanager.SubnetWebhook
 
 func TestSubnetManager(t *testing.T) {
@@ -42,8 +46,15 @@ var _ = BeforeSuite(func() {
 		WithScheme(scheme).
 		Build()
 
+	tracker = k8stesting.NewObjectTracker(scheme, k8sscheme.Codecs.UniversalDecoder())
+	fakeAPIReader = fake.NewClientBuilder().
+		WithScheme(scheme).
+		WithObjectTracker(tracker).
+		Build()
+
 	subnetWebhook = &subnetmanager.SubnetWebhook{
-		Client: fakeClient,
+		Client:    fakeClient,
+		APIReader: fakeAPIReader,
 	}
 
 	mockLeaderElector = electionmock.NewMockSpiderLeaseElector(mockCtrl)
diff --git a/pkg/subnetmanager/subnet_webhook_test.go b/pkg/subnetmanager/subnet_webhook_test.go
index 01fd0dcc2..448b85956 100644
--- a/pkg/subnetmanager/subnet_webhook_test.go
+++ b/pkg/subnetmanager/subnet_webhook_test.go
@@ -13,6 +13,7 @@ import (
 	. "github.com/onsi/gomega"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/utils/pointer"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -43,6 +44,8 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 	})
 
 	Describe("Test SubnetWebhook's method", func() {
+		var ctx context.Context
+
 		var count uint64
 		var subnetName, existSubnetName string
 		var subnetT, existSubnetT *spiderpoolv1.SpiderSubnet
@@ -52,6 +55,8 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 			subnetWebhook.EnableIPv4 = true
 			subnetWebhook.EnableIPv6 = true
 
+			ctx = context.TODO()
+
 			atomic.AddUint64(&count, 1)
 			subnetName = fmt.Sprintf("subnet-%v", count)
 			subnetT = &spiderpoolv1.SpiderSubnet{
@@ -87,12 +92,33 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 				PropagationPolicy:  &policy,
 			}
 
-			ctx := context.TODO()
 			err := fakeClient.Delete(ctx, subnetT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 
 			err = fakeClient.Delete(ctx, existSubnetT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    constant.SpiderpoolAPIGroup,
+					Version:  constant.SpiderpoolAPIVersionV1,
+					Resource: "spidersubnets",
+				},
+				subnetT.Namespace,
+				subnetT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    constant.SpiderpoolAPIGroup,
+					Version:  constant.SpiderpoolAPIVersionV1,
+					Resource: "spidersubnets",
+				},
+				existSubnetT.Namespace,
+				existSubnetT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 		})
 
 		Describe("Default", func() {
@@ -100,7 +126,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 				now := metav1.Now()
 				subnetT.SetDeletionTimestamp(&now)
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -108,7 +133,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 			It("adds finalizer", func() {
 				subnetT.Spec.Subnet = "172.18.40.0/24"
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 
@@ -120,7 +144,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 				subnetT.Spec.IPVersion = pointer.Int64(constant.InvalidIPVersion)
 				subnetT.Spec.Subnet = "172.18.40.0/24"
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 
@@ -133,7 +156,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 				subnet := "172.18.40.0/24"
 				subnetT.Spec.Subnet = subnet
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 
@@ -149,7 +171,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 			It("failed to set 'spec.ipVersion' due to the invalid 'spec.subnet'", func() {
 				subnetT.Spec.Subnet = constant.InvalidCIDR
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(subnetT.Spec.IPVersion).To(BeNil())
@@ -158,7 +179,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 			It("sets 'spec.ipVersion' to 4", func() {
 				subnetT.Spec.Subnet = "172.18.40.0/24"
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(*subnetT.Spec.IPVersion).To(Equal(constant.IPv4))
@@ -167,7 +187,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 			It("sets 'spec.ipVersion' to 6", func() {
 				subnetT.Spec.Subnet = "abcd:1234::/120"
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(*subnetT.Spec.IPVersion).To(Equal(constant.IPv6))
@@ -184,7 +203,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(subnetT.Spec.IPs).To(Equal(
@@ -208,7 +226,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(subnetT.Spec.IPs).To(Equal(
@@ -231,7 +248,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(subnetT.Spec.IPs).To(Equal(
@@ -252,7 +268,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(subnetT.Spec.IPs).To(Equal(
@@ -274,7 +289,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(subnetT.Spec.ExcludeIPs).To(Equal(
@@ -298,7 +312,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(subnetT.Spec.ExcludeIPs).To(Equal(
@@ -321,7 +334,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(subnetT.Spec.ExcludeIPs).To(Equal(
@@ -342,7 +354,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					}...,
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.Default(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(subnetT.Spec.ExcludeIPs).To(Equal(
@@ -365,7 +376,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						}...,
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -380,7 +390,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						}...,
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -396,7 +405,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						}...,
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -412,7 +420,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						}...,
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -429,13 +436,12 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						}...,
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
 
 				It("failed to list Subnets due to some unknown errors", func() {
-					patches := gomonkey.ApplyMethodReturn(fakeClient, "List", constant.ErrUnknown)
+					patches := gomonkey.ApplyMethodReturn(fakeAPIReader, "List", constant.ErrUnknown)
 					defer patches.Reset()
 
 					subnetT.Spec.IPVersion = pointer.Int64(constant.IPv4)
@@ -447,7 +453,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						}...,
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -462,8 +467,7 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						}...,
 					)
 
-					ctx := context.TODO()
-					err := fakeClient.Create(ctx, subnetT)
+					err := tracker.Add(subnetT)
 					Expect(err).NotTo(HaveOccurred())
 
 					err = subnetWebhook.ValidateCreate(ctx, subnetT)
@@ -475,8 +479,7 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					existSubnetT.Spec.Subnet = constant.InvalidCIDR
 					existSubnetT.Spec.IPs = append(existSubnetT.Spec.IPs, "172.18.41.1-172.18.41.2")
 
-					ctx := context.TODO()
-					err := fakeClient.Create(ctx, existSubnetT)
+					err := tracker.Add(existSubnetT)
 					Expect(err).NotTo(HaveOccurred())
 
 					subnetT.Spec.IPVersion = pointer.Int64(constant.IPv4)
@@ -497,8 +500,7 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					existSubnetT.Spec.Subnet = "172.18.40.0/25"
 					existSubnetT.Spec.IPs = append(existSubnetT.Spec.IPs, "172.18.40.40")
 
-					ctx := context.TODO()
-					err := fakeClient.Create(ctx, existSubnetT)
+					err := tracker.Add(existSubnetT)
 					Expect(err).NotTo(HaveOccurred())
 
 					subnetT.Spec.IPVersion = pointer.Int64(constant.IPv4)
@@ -521,7 +523,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					subnetT.Spec.Subnet = "172.18.40.0/24"
 					subnetT.Spec.IPs = append(subnetT.Spec.IPs, constant.InvalidIPRange)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -536,7 +537,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						}...,
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -554,7 +554,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					)
 					subnetT.Spec.ExcludeIPs = append(subnetT.Spec.ExcludeIPs, constant.InvalidIPRange)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -570,7 +569,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					)
 					subnetT.Spec.ExcludeIPs = append(subnetT.Spec.ExcludeIPs, "172.18.41.10")
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -588,7 +586,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					)
 					subnetT.Spec.Gateway = pointer.String(constant.InvalidIP)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -604,7 +601,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					)
 					subnetT.Spec.Gateway = pointer.String("172.18.41.1")
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -627,7 +623,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						},
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -648,7 +643,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						},
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -669,7 +663,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						},
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateCreate(ctx, subnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -694,7 +687,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					},
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.ValidateCreate(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -718,7 +710,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					},
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.ValidateCreate(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -739,7 +730,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.IPVersion = nil
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -757,7 +747,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.IPVersion = pointer.Int64(constant.IPv6)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -771,7 +760,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.IPs = append(newSubnetT.Spec.IPs, "172.18.40.10")
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -785,7 +773,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.IPs = append(newSubnetT.Spec.IPs, "adbc:1234::a")
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -805,7 +792,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.Subnet = "172.18.40.0/25"
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -825,7 +811,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.IPs = append(newSubnetT.Spec.IPs, constant.InvalidIPRange)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -838,7 +823,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.IPs = append(newSubnetT.Spec.IPs, "172.18.41.10")
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -858,7 +842,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.ExcludeIPs = append(newSubnetT.Spec.ExcludeIPs, constant.InvalidIPRange)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -876,7 +859,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.ExcludeIPs = append(newSubnetT.Spec.ExcludeIPs, "172.18.41.10")
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -897,7 +879,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.Gateway = pointer.String(constant.InvalidIP)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -916,7 +897,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.Gateway = pointer.String("172.18.41.1")
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -941,7 +921,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						},
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -964,7 +943,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						},
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -987,7 +965,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 						},
 					)
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -1018,7 +995,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.IPs = newSubnetT.Spec.IPs[:1]
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -1040,7 +1016,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.IPs = newSubnetT.Spec.IPs[:1]
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -1066,7 +1041,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					newSubnetT := subnetT.DeepCopy()
 					newSubnetT.Spec.IPs = newSubnetT.Spec.IPs[:1]
 
-					ctx := context.TODO()
 					err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 					Expect(apierrors.IsInvalid(err)).To(BeTrue())
 				})
@@ -1081,7 +1055,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 				newSubnetT := subnetT.DeepCopy()
 				controllerutil.RemoveFinalizer(newSubnetT, constant.SpiderFinalizer)
 
-				ctx := context.TODO()
 				err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -1094,7 +1067,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 
 				newSubnetT := subnetT.DeepCopy()
 
-				ctx := context.TODO()
 				err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 				Expect(apierrors.IsForbidden(err)).To(BeTrue())
 			})
@@ -1116,7 +1088,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					},
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -1138,7 +1109,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 					},
 				)
 
-				ctx := context.TODO()
 				err := subnetWebhook.ValidateUpdate(ctx, subnetT, newSubnetT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -1146,7 +1116,6 @@ var _ = Describe("SubnetWebhook", Label("subnet_webhook_test"), func() {
 
 		Describe("ValidateDelete", func() {
 			It("passes", func() {
-				ctx := context.TODO()
 				err := subnetWebhook.ValidateDelete(ctx, subnetT)
 				Expect(err).NotTo(HaveOccurred())
 			})
diff --git a/pkg/workloadendpointmanager/workloadendpoint_manager_suite_test.go b/pkg/workloadendpointmanager/workloadendpoint_manager_suite_test.go
index 47d271eaa..404756951 100644
--- a/pkg/workloadendpointmanager/workloadendpoint_manager_suite_test.go
+++ b/pkg/workloadendpointmanager/workloadendpoint_manager_suite_test.go
@@ -10,6 +10,8 @@ import (
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
+	k8sscheme "k8s.io/client-go/kubernetes/scheme"
+	k8stesting "k8s.io/client-go/testing"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
@@ -19,6 +21,8 @@ import (
 
 var scheme *runtime.Scheme
 var fakeClient client.Client
+var tracker k8stesting.ObjectTracker
+var fakeAPIReader client.Reader
 var endpointManager workloadendpointmanager.WorkloadEndpointManager
 
 func TestWorkloadEndpointManager(t *testing.T) {
@@ -38,11 +42,18 @@ var _ = BeforeSuite(func() {
 		WithScheme(scheme).
 		Build()
 
+	tracker = k8stesting.NewObjectTracker(scheme, k8sscheme.Codecs.UniversalDecoder())
+	fakeAPIReader = fake.NewClientBuilder().
+		WithScheme(scheme).
+		WithObjectTracker(tracker).
+		Build()
+
 	endpointManager, err = workloadendpointmanager.NewWorkloadEndpointManager(
 		workloadendpointmanager.EndpointManagerConfig{
 			MaxConflictRetries: 1,
 		},
 		fakeClient,
+		fakeAPIReader,
 	)
 	Expect(err).NotTo(HaveOccurred())
 })
diff --git a/pkg/workloadendpointmanager/workloadendpoint_manager_test.go b/pkg/workloadendpointmanager/workloadendpoint_manager_test.go
index 6274f2ed3..f31f5c95f 100644
--- a/pkg/workloadendpointmanager/workloadendpoint_manager_test.go
+++ b/pkg/workloadendpointmanager/workloadendpoint_manager_test.go
@@ -34,6 +34,7 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 			manager, err := workloadendpointmanager.NewWorkloadEndpointManager(
 				workloadendpointmanager.EndpointManagerConfig{},
 				fakeClient,
+				fakeAPIReader,
 			)
 			Expect(err).NotTo(HaveOccurred())
 			Expect(manager).NotTo(BeNil())
@@ -43,6 +44,17 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 			manager, err := workloadendpointmanager.NewWorkloadEndpointManager(
 				workloadendpointmanager.EndpointManagerConfig{},
 				nil,
+				fakeAPIReader,
+			)
+			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
+			Expect(manager).To(BeNil())
+		})
+
+		It("inputs nil API reader", func() {
+			manager, err := workloadendpointmanager.NewWorkloadEndpointManager(
+				workloadendpointmanager.EndpointManagerConfig{},
+				fakeClient,
+				nil,
 			)
 			Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
 			Expect(manager).To(BeNil())
@@ -50,6 +62,8 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 	})
 
 	Describe("Test WorkloadEndpointManager's method", func() {
+		var ctx context.Context
+
 		var count uint64
 		var namespace string
 		var endpointName string
@@ -57,6 +71,8 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 		var endpointT *spiderpoolv1.SpiderEndpoint
 
 		BeforeEach(func() {
+			ctx = context.TODO()
+
 			atomic.AddUint64(&count, 1)
 			namespace = "default"
 			endpointName = fmt.Sprintf("endpoint-%v", count)
@@ -86,52 +102,85 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 				PropagationPolicy:  &policy,
 			}
 
-			ctx := context.TODO()
 			err := fakeClient.Delete(ctx, endpointT, deleteOption)
 			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
+
+			err = tracker.Delete(
+				schema.GroupVersionResource{
+					Group:    constant.SpiderpoolAPIGroup,
+					Version:  constant.SpiderpoolAPIVersionV1,
+					Resource: "spiderendpoints",
+				},
+				endpointT.Namespace,
+				endpointT.Name,
+			)
+			Expect(client.IgnoreNotFound(err)).NotTo(HaveOccurred())
 		})
 
 		Describe("GetEndpointByName", func() {
 			It("gets non-existent Endpoint", func() {
-				ctx := context.TODO()
-				endpoint, err := endpointManager.GetEndpointByName(ctx, namespace, endpointName)
+				endpoint, err := endpointManager.GetEndpointByName(ctx, namespace, endpointName, constant.IgnoreCache)
 				Expect(apierrors.IsNotFound(err)).To(BeTrue())
 				Expect(endpoint).To(BeNil())
 			})
 
-			It("gets an existing Endpoint", func() {
-				ctx := context.TODO()
+			It("gets an existing Endpoint through cache", func() {
 				err := fakeClient.Create(ctx, endpointT)
 				Expect(err).NotTo(HaveOccurred())
 
-				endpoint, err := endpointManager.GetEndpointByName(ctx, namespace, endpointName)
+				endpoint, err := endpointManager.GetEndpointByName(ctx, namespace, endpointName, constant.UseCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(endpoint).NotTo(BeNil())
+				Expect(endpoint).To(Equal(endpointT))
+			})
 
+			It("gets an existing Endpoint through API Server", func() {
+				err := tracker.Add(endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				endpoint, err := endpointManager.GetEndpointByName(ctx, namespace, endpointName, constant.IgnoreCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpoint).NotTo(BeNil())
 				Expect(endpoint).To(Equal(endpointT))
 			})
 		})
 
 		Describe("ListEndpoints", func() {
 			It("failed to list Endpoints due to some unknown errors", func() {
-				patches := gomonkey.ApplyMethodReturn(fakeClient, "List", constant.ErrUnknown)
+				patches := gomonkey.ApplyMethodReturn(fakeAPIReader, "List", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, endpointT)
+				err := tracker.Add(endpointT)
 				Expect(err).NotTo(HaveOccurred())
 
-				endpointList, err := endpointManager.ListEndpoints(ctx)
+				endpointList, err := endpointManager.ListEndpoints(ctx, constant.IgnoreCache)
 				Expect(err).To(MatchError(constant.ErrUnknown))
 				Expect(endpointList).To(BeNil())
 			})
 
-			It("lists all Endpoints", func() {
-				ctx := context.TODO()
+			It("lists all Endpoints through cache", func() {
 				err := fakeClient.Create(ctx, endpointT)
 				Expect(err).NotTo(HaveOccurred())
 
-				endpointList, err := endpointManager.ListEndpoints(ctx)
+				endpointList, err := endpointManager.ListEndpoints(ctx, constant.UseCache)
+				Expect(err).NotTo(HaveOccurred())
+				Expect(endpointList.Items).NotTo(BeEmpty())
+
+				hasEndpoint := false
+				for _, endpoint := range endpointList.Items {
+					if endpoint.Name == endpointName {
+						hasEndpoint = true
+						break
+					}
+				}
+				Expect(hasEndpoint).To(BeTrue())
+			})
+
+			It("lists all Endpoints through API Server", func() {
+				err := tracker.Add(endpointT)
+				Expect(err).NotTo(HaveOccurred())
+
+				endpointList, err := endpointManager.ListEndpoints(ctx, constant.IgnoreCache)
 				Expect(err).NotTo(HaveOccurred())
 				Expect(endpointList.Items).NotTo(BeEmpty())
 
@@ -146,11 +195,10 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 			})
 
 			It("filters results by Namespace", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, endpointT)
+				err := tracker.Add(endpointT)
 				Expect(err).NotTo(HaveOccurred())
 
-				endpointList, err := endpointManager.ListEndpoints(ctx, client.MatchingFields{metav1.ObjectNameField: endpointName})
+				endpointList, err := endpointManager.ListEndpoints(ctx, constant.IgnoreCache, client.MatchingFields{metav1.ObjectNameField: endpointName})
 				Expect(err).NotTo(HaveOccurred())
 				Expect(endpointList.Items).NotTo(BeEmpty())
 
@@ -165,11 +213,10 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 			})
 
 			It("filters results by label selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, endpointT)
+				err := tracker.Add(endpointT)
 				Expect(err).NotTo(HaveOccurred())
 
-				endpointList, err := endpointManager.ListEndpoints(ctx, client.MatchingLabels(labels))
+				endpointList, err := endpointManager.ListEndpoints(ctx, constant.IgnoreCache, client.MatchingLabels(labels))
 				Expect(err).NotTo(HaveOccurred())
 				Expect(endpointList.Items).NotTo(BeEmpty())
 
@@ -184,11 +231,10 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 			})
 
 			It("filters results by field selector", func() {
-				ctx := context.TODO()
-				err := fakeClient.Create(ctx, endpointT)
+				err := tracker.Add(endpointT)
 				Expect(err).NotTo(HaveOccurred())
 
-				endpointList, err := endpointManager.ListEndpoints(ctx, client.MatchingFields{metav1.ObjectNameField: endpointName})
+				endpointList, err := endpointManager.ListEndpoints(ctx, constant.IgnoreCache, client.MatchingFields{metav1.ObjectNameField: endpointName})
 				Expect(err).NotTo(HaveOccurred())
 				Expect(endpointList.Items).NotTo(BeEmpty())
 
@@ -205,13 +251,11 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 
 		Describe("DeleteEndpoint", func() {
 			It("deletes non-existent Endpoint", func() {
-				ctx := context.TODO()
 				err := endpointManager.DeleteEndpoint(ctx, endpointT)
 				Expect(err).NotTo(HaveOccurred())
 			})
 
 			It("deletes an existing Endpoint", func() {
-				ctx := context.TODO()
 				err := fakeClient.Create(ctx, endpointT)
 				Expect(err).NotTo(HaveOccurred())
 
@@ -222,15 +266,15 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 
 		Describe("RemoveFinalizer", func() {
 			It("removes the finalizer for non-existent Endpoint", func() {
-				ctx := context.TODO()
 				err := endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
 				Expect(err).NotTo(HaveOccurred())
 			})
 
 			It("removes the finalizer that does not exit on the Endpoint", func() {
-				ctx := context.TODO()
 				err := fakeClient.Create(ctx, endpointT)
 				Expect(err).NotTo(HaveOccurred())
+				err = tracker.Add(endpointT)
+				Expect(err).NotTo(HaveOccurred())
 
 				err = endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
 				Expect(err).NotTo(HaveOccurred())
@@ -242,9 +286,10 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 
 				controllerutil.AddFinalizer(endpointT, constant.SpiderFinalizer)
 
-				ctx := context.TODO()
 				err := fakeClient.Create(ctx, endpointT)
 				Expect(err).NotTo(HaveOccurred())
+				err = tracker.Add(endpointT)
+				Expect(err).NotTo(HaveOccurred())
 
 				err = endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
 				Expect(err).To(MatchError(constant.ErrUnknown))
@@ -256,9 +301,10 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 
 				controllerutil.AddFinalizer(endpointT, constant.SpiderFinalizer)
 
-				ctx := context.TODO()
 				err := fakeClient.Create(ctx, endpointT)
 				Expect(err).NotTo(HaveOccurred())
+				err = tracker.Add(endpointT)
+				Expect(err).NotTo(HaveOccurred())
 
 				err = endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
 				Expect(err).To(MatchError(constant.ErrRetriesExhausted))
@@ -267,9 +313,10 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 			It("removes the Endpoint's finalizer", func() {
 				controllerutil.AddFinalizer(endpointT, constant.SpiderFinalizer)
 
-				ctx := context.TODO()
 				err := fakeClient.Create(ctx, endpointT)
 				Expect(err).NotTo(HaveOccurred())
+				err = tracker.Add(endpointT)
+				Expect(err).NotTo(HaveOccurred())
 
 				err = endpointManager.RemoveFinalizer(ctx, namespace, endpointName)
 				Expect(err).NotTo(HaveOccurred())
@@ -304,7 +351,6 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 			})
 
 			It("inputs nil Pod", func() {
-				ctx := context.TODO()
 				err := endpointManager.PatchIPAllocationResults(ctx, "", []*spiderpooltypes.AllocationResult{}, nil, nil, spiderpooltypes.PodTopController{})
 				Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
 			})
@@ -313,7 +359,6 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 				patches := gomonkey.ApplyFuncReturn(controllerutil.SetOwnerReference, constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
 				err := endpointManager.PatchIPAllocationResults(ctx, "", []*spiderpooltypes.AllocationResult{}, nil, podT, spiderpooltypes.PodTopController{})
 				Expect(err).To(MatchError(constant.ErrUnknown))
 			})
@@ -322,13 +367,11 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 				patches := gomonkey.ApplyMethodReturn(fakeClient, "Create", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
 				err := endpointManager.PatchIPAllocationResults(ctx, "", []*spiderpooltypes.AllocationResult{}, nil, podT, spiderpooltypes.PodTopController{})
 				Expect(err).To(MatchError(constant.ErrUnknown))
 			})
 
 			It("creates Endpoint for orphan Pod", func() {
-				ctx := context.TODO()
 				err := endpointManager.PatchIPAllocationResults(
 					ctx,
 					"",
@@ -355,7 +398,6 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 			})
 
 			It("creates Endpoint for StatefulSet Pod", func() {
-				ctx := context.TODO()
 				err := endpointManager.PatchIPAllocationResults(
 					ctx,
 					"",
@@ -386,7 +428,6 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 				podT.SetUID(uid)
 				endpointT.Status.Current.UID = string(uid)
 
-				ctx := context.TODO()
 				err := endpointManager.PatchIPAllocationResults(ctx, "", []*spiderpooltypes.AllocationResult{}, endpointT, podT, spiderpooltypes.PodTopController{})
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -395,7 +436,6 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 				patches := gomonkey.ApplyMethodReturn(fakeClient, "Update", constant.ErrUnknown)
 				defer patches.Reset()
 
-				ctx := context.TODO()
 				err := endpointManager.PatchIPAllocationResults(ctx, "", []*spiderpooltypes.AllocationResult{}, endpointT, podT, spiderpooltypes.PodTopController{})
 				Expect(err).To(MatchError(constant.ErrUnknown))
 			})
@@ -404,7 +444,6 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 
 		Describe("ReallocateCurrentIPAllocation", func() {
 			It("inputs nil Endpoint", func() {
-				ctx := context.TODO()
 				err := endpointManager.ReallocateCurrentIPAllocation(ctx, "", string(uuid.NewUUID()), "node1", nil)
 				Expect(err).To(MatchError(constant.ErrMissingRequiredParam))
 			})
@@ -413,7 +452,6 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 				uid := uuid.NewUUID()
 				endpointT.Status.Current.UID = string(uid)
 
-				ctx := context.TODO()
 				err := endpointManager.ReallocateCurrentIPAllocation(ctx, "", string(uid), "node", endpointT)
 				Expect(err).NotTo(HaveOccurred())
 			})
@@ -424,7 +462,6 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 
 				endpointT.Status.Current.UID = string(uuid.NewUUID())
 
-				ctx := context.TODO()
 				err := endpointManager.ReallocateCurrentIPAllocation(ctx, "", string(uuid.NewUUID()), "node", endpointT)
 				Expect(err).To(MatchError(constant.ErrUnknown))
 			})
@@ -433,7 +470,6 @@ var _ = Describe("WorkloadEndpointManager", Label("workloadendpoint_manager_test
 				endpointT.Status.Current.UID = string(uuid.NewUUID())
 				endpointT.Status.Current.Node = "old-node"
 
-				ctx := context.TODO()
 				err := fakeClient.Create(ctx, endpointT)
 				Expect(err).NotTo(HaveOccurred())