Пользовательский контроллер реагирует на обработчик событий addfunc до того, как кэш будет синхронизирован? Это поведение правильно? - PullRequest
0 голосов
/ 10 апреля 2019

Ниже приведен мой фрагмент

factory := informers.NewFilteredSharedInformerFactory(clientset, 0, "", func(o *metaV1.ListOptions) {
    o.LabelSelector = "node-role.kubernetes.io/master="
})

nodeInformer := factory.Core().V1().Nodes().Informer()

i.lister = factory.Core().V1().Nodes().Lister()

nodeInformer.AddEventHandler(
    cache.ResourceEventHandlerFuncs{
        AddFunc: func(obj interface{}) {
            i.updateIPs()
        },
        UpdateFunc: func(oldobj, newObj interface{}) {
            i.updateIPs()
        },
        DeleteFunc: func(obj interface{}) {
            i.updateIPs()
        },
    })

factory.Start(ctx.Done())

if !cache.WaitForCacheSync(ctx.Done(), nodeInformer.HasSynced) {
    runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))
    return
}

Полный код: https://github.com/tweakmy/fotofona/blob/master/nodeinformer.go

Это результат, когда я запускаю свой модульный тест:

   $ go test -v -run TestInformer
   === RUN   TestInformer
   Update ip host [10.0.0.1]
   cache is synced
   --- PASS: TestInformer (3.10s)

Это ожидаемое поведение?Как получить его в списке после синхронизации кэша и реагировать на обработчик событий после синхронизации кэша.

1 Ответ

0 голосов
/ 10 апреля 2019

То, что вы видите, является стандартным поведением. Пока вы ожидаете синхронизации, получаются уведомления и выполняются соответствующие обработчики уведомлений.

Ваш код отличается от кода, который использует API Informer, поскольку обработка происходит непосредственно в обработчиках уведомлений. Это пахнет как поведение, основанное на краях, в то время как Kubernetes поощряет поведение, основанное на уровнях.

Типичный шаблон при написании контроллера Kubernetes (это то, что вам следует делать) - это когда обработчики уведомлений ничего не делают, кроме как помещают ссылку (обычно имя в пространстве имен) на уведомленный объект в рабочей очереди и имеют пул рабочих (если вы используете go-подпрограммы), извлеките такие ссылки, используйте их для извлечения всего объекта из кэша Informer, а затем выполните фактическую обработку. Поэтому обычно выполняется синхронизация кешей информеров перед запуском рабочих, чтобы работники не начинали обработку до синхронизации кеша. Чтобы быть точным, updateIPs() должен выполняться не в коде обработчиков уведомлений, а в теле рабочих.

На этой странице есть отдельный пример обычного шаблона. Более точно, см. этот код для примера типичных обработчиков уведомлений и этот код для примера того, как выполняется синхронизация с запуском рабочих.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...