support watch namespaces matched namespace selector (#7472)
skip caching namespaces at cluster scope if only watching single namespace add --watch-namespace-selector in user guide add e2e test
This commit is contained in:
parent
67e13bf692
commit
7203a0b8bd
26 changed files with 461 additions and 19 deletions
|
|
@ -32,6 +32,7 @@ import (
|
|||
networkingv1 "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
k8sruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
|
|
@ -127,6 +128,7 @@ type Informer struct {
|
|||
Service cache.SharedIndexInformer
|
||||
Secret cache.SharedIndexInformer
|
||||
ConfigMap cache.SharedIndexInformer
|
||||
Namespace cache.SharedIndexInformer
|
||||
}
|
||||
|
||||
// Lister contains object listers (stores).
|
||||
|
|
@ -137,6 +139,7 @@ type Lister struct {
|
|||
Endpoint EndpointLister
|
||||
Secret SecretLister
|
||||
ConfigMap ConfigMapLister
|
||||
Namespace NamespaceLister
|
||||
IngressWithAnnotation IngressWithAnnotationsLister
|
||||
}
|
||||
|
||||
|
|
@ -172,6 +175,15 @@ func (i *Informer) Run(stopCh chan struct{}) {
|
|||
runtime.HandleError(fmt.Errorf("timed out waiting for ingress classcaches to sync"))
|
||||
}
|
||||
|
||||
// when limit controller scope to one namespace, skip sync namespaces at cluster scope
|
||||
if i.Namespace != nil {
|
||||
go i.Namespace.Run(stopCh)
|
||||
|
||||
if !cache.WaitForCacheSync(stopCh, i.Namespace.HasSynced) {
|
||||
runtime.HandleError(fmt.Errorf("timed out waiting for caches to sync"))
|
||||
}
|
||||
}
|
||||
|
||||
// in big clusters, deltas can keep arriving even after HasSynced
|
||||
// functions have returned 'true'
|
||||
time.Sleep(1 * time.Second)
|
||||
|
|
@ -225,7 +237,9 @@ type k8sStore struct {
|
|||
|
||||
// New creates a new object store to be used in the ingress controller
|
||||
func New(
|
||||
namespace, configmap, tcp, udp, defaultSSLCertificate string,
|
||||
namespace string,
|
||||
namespaceSelector labels.Selector,
|
||||
configmap, tcp, udp, defaultSSLCertificate string,
|
||||
resyncPeriod time.Duration,
|
||||
client clientset.Interface,
|
||||
updateCh *channels.RingChannel,
|
||||
|
|
@ -322,6 +336,35 @@ func New(
|
|||
store.informers.Service = infFactory.Core().V1().Services().Informer()
|
||||
store.listers.Service.Store = store.informers.Service.GetStore()
|
||||
|
||||
// avoid caching namespaces at cluster scope when watching single namespace
|
||||
if namespaceSelector != nil && !namespaceSelector.Empty() {
|
||||
// cache informers factory for namespaces
|
||||
infFactoryNamespaces := informers.NewSharedInformerFactoryWithOptions(client, resyncPeriod,
|
||||
informers.WithTweakListOptions(labelsTweakListOptionsFunc),
|
||||
)
|
||||
|
||||
store.informers.Namespace = infFactoryNamespaces.Core().V1().Namespaces().Informer()
|
||||
store.listers.Namespace.Store = store.informers.Namespace.GetStore()
|
||||
}
|
||||
|
||||
watchedNamespace := func(namespace string) bool {
|
||||
if namespaceSelector == nil || namespaceSelector.Empty() {
|
||||
return true
|
||||
}
|
||||
|
||||
item, ok, err := store.listers.Namespace.GetByKey(namespace)
|
||||
if !ok {
|
||||
klog.Errorf("Namespace %s not existed: %v.", namespace, err)
|
||||
return false
|
||||
}
|
||||
ns, ok := item.(*corev1.Namespace)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return namespaceSelector.Matches(labels.Set(ns.Labels))
|
||||
}
|
||||
|
||||
ingDeleteHandler := func(obj interface{}) {
|
||||
ing, ok := toIngress(obj)
|
||||
if !ok {
|
||||
|
|
@ -338,6 +381,10 @@ func New(
|
|||
}
|
||||
}
|
||||
|
||||
if !watchedNamespace(ing.Namespace) {
|
||||
return
|
||||
}
|
||||
|
||||
_, err := store.GetIngressClass(ing, icConfig)
|
||||
if err != nil {
|
||||
klog.InfoS("Ignoring ingress because of error while validating ingress class", "ingress", klog.KObj(ing), "error", err)
|
||||
|
|
@ -363,6 +410,11 @@ func New(
|
|||
ingEventHandler := cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
ing, _ := toIngress(obj)
|
||||
|
||||
if !watchedNamespace(ing.Namespace) {
|
||||
return
|
||||
}
|
||||
|
||||
ic, err := store.GetIngressClass(ing, icConfig)
|
||||
if err != nil {
|
||||
klog.InfoS("Ignoring ingress because of error while validating ingress class", "ingress", klog.KObj(ing), "error", err)
|
||||
|
|
@ -392,6 +444,10 @@ func New(
|
|||
oldIng, _ := toIngress(old)
|
||||
curIng, _ := toIngress(cur)
|
||||
|
||||
if !watchedNamespace(oldIng.Namespace) {
|
||||
return
|
||||
}
|
||||
|
||||
var errOld, errCur error
|
||||
var classCur string
|
||||
if !icConfig.IgnoreIngressClass {
|
||||
|
|
@ -528,6 +584,10 @@ func New(
|
|||
sec := cur.(*corev1.Secret)
|
||||
key := k8s.MetaNamespaceKey(sec)
|
||||
|
||||
if !watchedNamespace(sec.Namespace) {
|
||||
return
|
||||
}
|
||||
|
||||
if store.defaultSSLCertificate == key {
|
||||
store.syncSecret(store.defaultSSLCertificate)
|
||||
}
|
||||
|
|
@ -566,6 +626,10 @@ func New(
|
|||
}
|
||||
}
|
||||
|
||||
if !watchedNamespace(sec.Namespace) {
|
||||
return
|
||||
}
|
||||
|
||||
store.sslStore.Delete(k8s.MetaNamespaceKey(sec))
|
||||
|
||||
key := k8s.MetaNamespaceKey(sec)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue