Skip to content

Commit

Permalink
[no-cluster-rbac] Introduce xns-informer
Browse files Browse the repository at this point in the history
MAISTRA-2051: Add xns-informer for Kubernetes types (#223)

* vendor: Add github.com/maistra/xns-informer

* Update mirrored licenses to fix gen-check

* MAISTRA-2051: Add xns-informer for Kubernetes types

This integrates the xns-informer library for multi-namespace support,
but only for core Kubernetes types.  The informers are hard-coded to
watch all namespaces here.  The integration with MemberRoll will come
in a follow-up.

MAISTRA-2051 Add xns-informer for Istio types (#221)

MAISTRA-2051: Add MemberRollController (#227)

* MAISTRA-2051: Add MemberRollController

Includes the following:

* 75742b0 - Add Makefile for Maistra client generation

This adds a Makefile with tasks for generating the Maistra specific
clients. It is adapted from the one in the Istio client-go repository.

* 5f8562c - Add MemberRollController

Squashed commit, consisting of:

  * MAISTRA-417: Add MemberRollController

  * MAISTRA-450: Switch across to ConfiguredMembers and check existing
    config for changes

  * MAISTRA-1005 Do not expect namespaces to have a stable ordering

The clients have also been regenerated.

* 1b7a89d - Add missing licenses

* fe2f8cd - Fix Copyright holder

* 06ea2db - MAISTRA-1666: Add `go mod vendor` as part of `make gen`

This is to make sure all PR's will have an updated
vendor directory. The `gencheck` prow job will ensure that.

* MAISTRA-2051: Update MemberRollController for xns-informers

* MAISTRA-2051: Add AddMemberRoll to kube client

* MAISTRA-2051: Configure MemberRoll controller in istiod

MAISTRA-2051: Add xns-informer for Service APIs (#229)

* MAISTRA-2051: Update xns-informers

* MAISTRA-2051: Add xns-informer for Service APIs

MAISTRA-2051: Use shared Kubernetes client in galley (#241)

This moves galley to the shared Kubernetes client, which will let it
use xns-informers for multi-namespace support like everything else.

MAISTRA-2051: Update xns-informers to latest (#252)

* MAISTRA-2051: Reset Kubernetes client to release-1.8 state

* MAISTRA-2051: Use xns-informers in Kubernetes client

* MAISTRA-2051: Un-skip tests with xns-informers issues

These tests were skipped because of issues with xns-informers, which
have now been solved.  They should no longer be skipped.

* MAISTRA-2051: Update xns-informers to latest

* MAISTRA-2051: Skip problematic integration test: TestDashboard

MAISTRA-2051: Use MultiNamespaceInformer in galley (#254)

* Revert "MAISTRA-2051: Use shared Kubernetes client in galley (#241)"

This reverts commit 0b1567a.

* MAISTRA-2051: Use MultiNamespaceInformer in galley

This is a rework of the previous change that used the central
Kubernetes client in Galley.  The watchers in Galley manage stopping
and starting individual informers, which doesn't work well with the
factory returning cached informers.  This creates multi-namespace
informers individually instead of using the central factory.  It's
also a much smaller change overall and doesn't affect the tests.

* MAISTRA-2051: Add GetMemberRoll method to Kubernetes client

* MAISTRA-2051: Integrate MemberRoll with Galley

This configures the mulit-namespace aware infomers in Galley to
respond to changes in the set of namespaces via the MemberRoll.

This includes parts of the following:

  - 4b70b8d MAISTRA-1895 Add option to enable/disable CRD scan
  - 6e8019e MAISTRA-1968 allow analyzer to work with multi list watcher

MAISTRA-1724: Don't watch namespaces if MemberRoll is used (#257)

Rewrite of the following for Maistra 2.1 / Istio 1.8 rebase:

a161a53 - MAISTRA-1724 Don't watch namespaces if MRC is used (#161)

MAISTRA-1755: invoke UpdateNamespaces() as part of MemberRollController.Register()

Cherry-pick of f0eed15 for Maistra 2.1 / Istio 1.8 rebase.

MAISTRA-1724: Better hanlde deletion in NamespaceController

MAISTRA-2153: Disable namespace informer if MemberRoll is used (#283)

This causes istiod to skip creating the namespace informer in the
Kubernetes service registry controller if a MemberRoll is specified,
because Maistra cannot read namespace objects.  This will affect the
behavior of multi-network deployments that do not use mesh networks
for configuration, i.e. a namespace cannot be labeled with a default
network now.

MAISTRA-2197: Push first update when cache is warm (#294)

Change SMMR Controller behavior to only send the first update to
listeners when it has a list of members ready. In other words, when
cache is synced.

Before this, the first update was sent with only one hardcoded member:
The control plane namespace. Now it is sent with the full list of SMMR
members.

While on that, switch to our own log scope, to facilitate debugging.

Manual cherry pick of #291

MAISTRA-2233: Start xns-informers with empty namespace set (#303)

The multi-namespace informers created by xns-informers default to
watching all namespaces to match upstream behaviour.  This causes
permissions issues in Maistra because they will do this until the
first update from the MemberRoll controller sets the correct set of
namespaces on each informer.  We should instead explicitly configure
them with an empty set of namespaces at startup.

MAISTRA-2234: Seed MemberRoll listeners with system namespace (#302)

The MemberRoll controller was changed in MAISTRA-2197 to not send the
initial update with just the system namespace to all listeners.  This
can be a problem when the user hasn't created an SMMR resource yet,
because any listeners registered before the caches sync may never get
an update informing them to watch the system namespace.

This attempts to work around the issue by having all listeners
individually wait on the caches to sync, then seed just the system
namespace if no SMMR resource is found.

MAISTRA-2271: Update xns-informers to fix delete events issue (#315)

This updates xns-informers to include a fix for sending delete events
for all objects when a namespace is no longer watched.

See: maistra/xns-informer#12
  • Loading branch information
bison authored and maistra-bot committed Mar 1, 2022
1 parent d8d5c03 commit 8d2bb2b
Show file tree
Hide file tree
Showing 269 changed files with 17,904 additions and 2,487 deletions.
3 changes: 3 additions & 0 deletions Makefile.core.mk
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ gen: \
gen-nds-proto \
copy-templates \
gen-kustomize \
maistra-gen \
update-golden ## Update all generated code.

gen-check: gen check-clean-repo
Expand Down Expand Up @@ -548,3 +549,5 @@ include tools/packaging/packaging.mk
include tests/integration/tests.mk

include common/Makefile.common.mk

include pkg/servicemesh/maistra.mk
5 changes: 5 additions & 0 deletions galley/pkg/config/source/kube/apiserver/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"istio.io/istio/galley/pkg/config/source/kube"
"istio.io/istio/galley/pkg/config/source/kube/apiserver/status"
"istio.io/istio/pkg/config/schema/collection"
memberroll "istio.io/istio/pkg/servicemesh/controller"
)

// Options for the kube controller
Expand All @@ -34,4 +35,8 @@ type Options struct {
StatusController status.Controller

WatchedNamespaces string

MemberRoll memberroll.MemberRollController

DisableCRDScan bool
}
28 changes: 22 additions & 6 deletions galley/pkg/config/source/kube/apiserver/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,29 @@ func (s *Source) Start() {
// Releasing the lock here to avoid deadlock on crdWatcher between the existing one and a newly started one.
s.mu.Unlock()

// Start the CRD listener. When the listener is fully-synced, the listening of actual resources will start.
scope.Source.Infof("Beginning CRD Discovery, to figure out resources that are available...")
s.provider = rt.NewProvider(s.options.Client, s.options.WatchedNamespaces, s.options.ResyncPeriod)
a := s.provider.GetAdapter(crdKubeResource.Resource())
s.crdWatcher = newWatcher(crdKubeResource, a, s.statusCtl)
s.crdWatcher.dispatch(event.HandlerFromFn(s.onCrdEvent))
s.crdWatcher.start()

if s.options.MemberRoll != nil {
s.options.MemberRoll.Register(s.provider, "galley")
}

if s.options.DisableCRDScan {
scope.Source.Infof("Starting listeners for all known types...")
s.mu.Lock()
defer s.mu.Unlock()
for key := range s.expectedResources {
s.foundResources[key] = true
}
s.startWatchers()
s.publishing = true
} else {
// Start the CRD listener. When the listener is fully-synced, the listening of actual resources will start.
scope.Source.Infof("Beginning CRD Discovery, to figure out resources that are available...")
a := s.provider.GetAdapter(crdKubeResource.Resource())
s.crdWatcher = newWatcher(crdKubeResource, a, s.statusCtl)
s.crdWatcher.dispatch(event.HandlerFromFn(s.onCrdEvent))
s.crdWatcher.start()
}
}

func (s *Source) onCrdEvent(e event.Event) {
Expand Down
29 changes: 16 additions & 13 deletions galley/pkg/config/source/kube/rt/dynamic.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"

"github.com/gogo/protobuf/proto"
xnsinformers "github.com/maistra/xns-informer/pkg/informers"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -28,7 +29,6 @@ import (

"istio.io/istio/galley/pkg/config/util/pb"
"istio.io/istio/pkg/config/schema/resource"
"istio.io/istio/pkg/listwatch"
)

func (p *Provider) getDynamicAdapter(r resource.Schema) *Adapter {
Expand Down Expand Up @@ -61,20 +61,23 @@ func (p *Provider) getDynamicAdapter(r resource.Schema) *Adapter {
return nil, err
}

mlw := listwatch.MultiNamespaceListerWatcher(p.namespaces, func(namespace string) cache.ListerWatcher {
return &cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return d.List(context.TODO(), options)
newInformer := func(namespace string) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return d.Namespace(namespace).List(context.TODO(), options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return d.Namespace(namespace).Watch(context.TODO(), options)
},
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
options.Watch = true
return d.Watch(context.TODO(), options)
},
}
})
&unstructured.Unstructured{},
p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
}

informer := cache.NewSharedIndexInformer(mlw, &unstructured.Unstructured{}, p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
informer := xnsinformers.NewMultiNamespaceInformer(p.namespaces, p.resyncPeriod, newInformer)

return informer, nil
},
Expand Down
177 changes: 99 additions & 78 deletions galley/pkg/config/source/kube/rt/known.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"reflect"

"github.com/gogo/protobuf/proto"
xnsinformers "github.com/maistra/xns-informer/pkg/informers"
webhookv1 "k8s.io/api/admissionregistration/v1"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
Expand All @@ -33,7 +34,6 @@ import (

"istio.io/istio/galley/pkg/config/scope"
"istio.io/istio/galley/pkg/config/source/kube/apiserver/stats"
"istio.io/istio/pkg/listwatch"
)

func (p *Provider) initKnownAdapters() {
Expand All @@ -56,20 +56,23 @@ func (p *Provider) initKnownAdapters() {
return nil, err
}

mlw := listwatch.MultiNamespaceListerWatcher(p.namespaces,
func(namespace string) cache.ListerWatcher {
return &cache.ListWatch{
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().Services(namespace).List(context.TODO(), opts)
newInformer := func(namespace string) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().Services(namespace).List(context.TODO(), options)
},
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().Services(namespace).Watch(context.TODO(), opts)
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().Services(namespace).Watch(context.TODO(), options)
},
}
})
},
&v1.Service{},
p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
}

informer := cache.NewSharedIndexInformer(mlw, &v1.Service{}, p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
informer := xnsinformers.NewMultiNamespaceInformer(p.namespaces, p.resyncPeriod, newInformer)

return informer, nil
},
Expand Down Expand Up @@ -161,20 +164,23 @@ func (p *Provider) initKnownAdapters() {
return nil, err
}

mlw := listwatch.MultiNamespaceListerWatcher(p.namespaces,
func(namespace string) cache.ListerWatcher {
return &cache.ListWatch{
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().Pods(namespace).List(context.TODO(), opts)
newInformer := func(namespace string) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().Pods(namespace).List(context.TODO(), options)
},
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().Pods(namespace).Watch(context.TODO(), opts)
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().Pods(namespace).Watch(context.TODO(), options)
},
}
})
},
&v1.Pod{},
p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
}

informer := cache.NewSharedIndexInformer(mlw, &v1.Pod{}, p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
informer := xnsinformers.NewMultiNamespaceInformer(p.namespaces, p.resyncPeriod, newInformer)

return informer, nil
},
Expand Down Expand Up @@ -206,20 +212,23 @@ func (p *Provider) initKnownAdapters() {
return nil, err
}

mlw := listwatch.MultiNamespaceListerWatcher(p.namespaces,
func(namespace string) cache.ListerWatcher {
return &cache.ListWatch{
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().Secrets(namespace).List(context.TODO(), opts)
newInformer := func(namespace string) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().Secrets(namespace).List(context.TODO(), options)
},
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().Secrets(namespace).Watch(context.TODO(), opts)
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().Secrets(namespace).Watch(context.TODO(), options)
},
}
})
},
&v1.Secret{},
p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
}

informer := cache.NewSharedIndexInformer(mlw, &v1.Secret{}, p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
informer := xnsinformers.NewMultiNamespaceInformer(p.namespaces, p.resyncPeriod, newInformer)

return informer, nil
},
Expand Down Expand Up @@ -250,20 +259,23 @@ func (p *Provider) initKnownAdapters() {
return nil, err
}

mlw := listwatch.MultiNamespaceListerWatcher(p.namespaces,
func(namespace string) cache.ListerWatcher {
return &cache.ListWatch{
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().Endpoints(namespace).List(context.TODO(), opts)
newInformer := func(namespace string) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().Endpoints(namespace).List(context.TODO(), options)
},
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().Endpoints(namespace).Watch(context.TODO(), opts)
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().Endpoints(namespace).Watch(context.TODO(), options)
},
}
})
},
&v1.Endpoints{},
p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
}

informer := cache.NewSharedIndexInformer(mlw, &v1.Endpoints{}, p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
informer := xnsinformers.NewMultiNamespaceInformer(p.namespaces, p.resyncPeriod, newInformer)

return informer, nil
},
Expand Down Expand Up @@ -306,20 +318,23 @@ func (p *Provider) initKnownAdapters() {
return nil, err
}

mlw := listwatch.MultiNamespaceListerWatcher(p.namespaces,
func(namespace string) cache.ListerWatcher {
return &cache.ListWatch{
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
return client.ExtensionsV1beta1().Ingresses(namespace).List(context.TODO(), opts)
newInformer := func(namespace string) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.ExtensionsV1beta1().Ingresses(namespace).List(context.TODO(), options)
},
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
return client.ExtensionsV1beta1().Ingresses(namespace).Watch(context.TODO(), opts)
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.ExtensionsV1beta1().Ingresses(namespace).Watch(context.TODO(), options)
},
}
})
},
&v1beta1.Ingress{},
p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
}

informer := cache.NewSharedIndexInformer(mlw, &v1beta1.Ingress{}, p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
informer := xnsinformers.NewMultiNamespaceInformer(p.namespaces, p.resyncPeriod, newInformer)

return informer, nil
},
Expand Down Expand Up @@ -427,20 +442,23 @@ func (p *Provider) initKnownAdapters() {
return nil, err
}

mlw := listwatch.MultiNamespaceListerWatcher(p.namespaces,
func(namespace string) cache.ListerWatcher {
return &cache.ListWatch{
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
return client.AppsV1().Deployments(namespace).List(context.TODO(), opts)
newInformer := func(namespace string) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.AppsV1().Deployments(namespace).List(context.TODO(), options)
},
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
return client.AppsV1().Deployments(namespace).Watch(context.TODO(), opts)
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.AppsV1().Deployments(namespace).Watch(context.TODO(), options)
},
}
})
},
&appsv1.Deployment{},
p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
}

informer := cache.NewSharedIndexInformer(mlw, &appsv1.Deployment{}, p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
informer := xnsinformers.NewMultiNamespaceInformer(p.namespaces, p.resyncPeriod, newInformer)

return informer, nil
},
Expand Down Expand Up @@ -470,20 +488,23 @@ func (p *Provider) initKnownAdapters() {
return nil, err
}

mlw := listwatch.MultiNamespaceListerWatcher(p.namespaces,
func(namespace string) cache.ListerWatcher {
return &cache.ListWatch{
ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().ConfigMaps(namespace).List(context.TODO(), opts)
newInformer := func(namespace string) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
return client.CoreV1().ConfigMaps(namespace).List(context.TODO(), options)
},
WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().ConfigMaps(namespace).Watch(context.TODO(), opts)
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
return client.CoreV1().ConfigMaps(namespace).Watch(context.TODO(), options)
},
}
})
},
&v1.ConfigMap{},
p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
)
}

informer := cache.NewSharedIndexInformer(mlw, &v1.ConfigMap{}, p.resyncPeriod,
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
informer := xnsinformers.NewMultiNamespaceInformer(p.namespaces, p.resyncPeriod, newInformer)

return informer, nil
},
Expand Down

0 comments on commit 8d2bb2b

Please sign in to comment.