Lasso — это платформа контроллера.
Lasso имеет некоторую функциональную идентичность с проектом среды выполнения контроллера и может использоваться вместо среды выполнения контроллера.
Лассо — низкий уровень. Если вы хотите управлять своими собственными контроллерами, вы можете использовать его. Если вы ищете больше удобства и функциональности для создания собственных типов ресурсов, рекомендуем обратить внимание на Wrangler.
Платформа базового контроллера, используемая Wrangler и Norman.
Этот документ был написан для двух аудиторий: для тех, кто плохо знаком с контроллерами Kubernetes, и для тех, кто не новичок в контроллерах Kubernetes, но не знаком с lasso.
Если вы попадаете в категорию «Тот, кто не новичок в контроллерах Kubernetes», вы можете перейти к ценностному предложению Лассо.
Если вы новичок в контроллерах Kubernetes, рекомендуется не пропускать ни одного раздела.
Если вам не хватает базовых знаний Kubernetes, рекомендуется сначала ознакомиться с другой документацией по основам, например с обзором Kubernetes.
Примечание. Это будет очень краткий ускоренный курс. Мы рекомендуем вам поискать другие ресурсы по этой теме, их много! Двумя рекомендуемыми ресурсами являются пример проекта контроллера и введение в платформы контроллеров Kubernetes.
Из документации Kubernetes
В Kubernetes контроллер — это цикл управления, который отслеживает общее состояние кластера через API-сервер и вносит изменения, пытаясь приблизить текущее состояние к желаемому.
Слово «контроллер» используется более свободно, чем то, во что вы могли бы поверить из приведенного выше определения. Нашими словами: контроллеры — это обработчики циклов, которые действуют в ответ на события ресурсов Kubernetes. В Lasso мы также используем слово «контроллер» для обозначения всей структуры, которая отвечает за регистрацию этого обработчика цикла и предоставление ему необходимых ресурсов. Короче говоря, контроллеры — это структуры, объединяющие все необходимое для взаимодействия с типами Kubernetes и работы с ними.
Для достижения вышеуказанной цели необходимо выполнить несколько подцелей:
Существует множество рамок, помогающих достичь вышеуказанных целей. Лассо — один из них. Общим для большинства этих фреймворков, включая lasso, является то, что для достижения этих целей они используют функциональные возможности клиентской версии. Вы можете достичь этих целей, используя только client-go. В оставшейся части этого раздела мы рассмотрим, как собирается контроллер, используя только концепции client-go.
Информер используется для достижения вышеуказанных целей, необходимых для контроллера Kubernetes. Информер имеет обработчик событий и индексатор. Индексатор имеет функции хранилища и карты для индексации объектов внутри хранилища, называемых индексаторами. Базовые структуры различаются, но для иллюстрации этого ниже показана псевдоструктура:
Informer
EventHandler
Indexer
Store
Indexers
EventHandler может иметь различную логику для создания, обновления и удаления событий. Обработчик событий — это место, где появляется контроллер. Вы используете его для настройки обработчиков событий создания, обновления и удаления.
Индексатор используется в качестве кэша.
Хранилище — это место, где индексатор сохраняет объекты.
Индексаторы — это функции, которые индексатор может использовать для индексации сохраняемых объектов. После индексации с помощью индексатора объекты можно извлекать с помощью строк, описывающих характеристики, которые важны для индексатора.
Индексатор часто используется для получения объекта по простым метаданным, таким как пространство имен и имя.
Информер сначала заполняет индексатор, перечисляя все ресурсы, возвращенные клиентом. Затем информер наблюдает за ресурсом Kubernetes, к которому он привязан. Когда происходит событие, оно использует это событие для обновления своего индексатора и выполнения обработчиков событий.
Обычно приложению требуется несколько контроллеров. Однако для каждого контроллера может быть неэффективно иметь свой собственный информер и, следовательно, собственный индексатор. SharedIndexerInformer из client-go можно использовать для добавления нескольких контроллеров, которые используют одни и те же индексаторы.
В репозитории kubernetes/sample-controller можно найти отличное наглядное представление того, как может работать контроллер Kubernetes.
Примечание. Информеры были упрощены для краткости. Если вас интересует, как именно они работают, рекомендуется прочитать код client-go.
Lasso стандартизирует контроллер с помощью его пакета контроллера. Lasso представляет фабрики для управления кэшами, контроллерами и клиентами в рамках проекта. Это крайне важно для владельца ранчо, который управляет множеством экземпляров разных типов.
Контроллер лассо использует рабочую очередь клиента. Лассо регистрирует обработчик событий, который обрабатывает рабочую очередь. Обработчик, ориентированный на рабочую очередь, позволяет добавлять только один обработчик событий для каждого типа Kubernetes. Теперь регистрация обработчика просто добавляет его в список обработчиков контроллера типа. Постановка объекта в очередь добавляет его в рабочую очередь. Каждый объект в рабочей очереди затем будет обработан воркёрами, работающими в горутинах. Обработчик событий контроллера повторно поставит в очередь любой объект, который заставляет один или несколько обработчиков контроллера возвращать ошибку, которая не относится к типу ErrIgnore
. Эта рабочая очередь также может содержать объекты из других источников. Эта функциональность предоставляется через функцию Enqueue контроллера. Это превращает контроллеры из просто реагирующих на ресурсы Kubernetes и повторную синхронизацию кэша в возможность вызова с помощью кода.
ТипsharedController встраивает интерфейс контроллера, чтобы раскрыть функциональность его контроллера. SharedController также предоставляет функцию RegisterHandler вместе с функцией Client. RegisterHandler добавляет переданный обработчик в список обработчиков контроллера, а Client возвращает клиента для соответствующего типа ресурса SharedController; SharedController имеет поле GVK (вид версии группы), которое указывает, для какого типа оно предназначено.
«Общий» аспект начинается с более примитивного контроллера Lasso. Использование рабочей очереди позволяет, например, совместно использовать один набор обработчиков событий. Затем к этому добавляется общий контроллер Lasso, поддерживающий многоразовый клиент для GVK и добавляющий способ простой регистрации обработчиков в контроллере под ним с помощью RegisterHandler.
SharedController может создать свой базовый контроллер. Это произойдет только после того, как обработчик будет зарегистрирован в SharedController.
Обертывает клиент Kubernetes. Содержит поля GVK для управления клиентом в родительской структуре, такой как SharedClientFactory. Предоставляет некоторые дополнительные функции, такие как настройка заголовка User-Agent для базового клиента REST.
Lasso Cache — это легкая оболочка SharedIndexInformer из клиентской части.
Основное преимущество Lasso Cache заключается в том, что ему можно назначить Cache Factory, которая управляет SharedIndexInformer в памяти с помощью GVK, чтобы их можно было повторно использовать. При использовании функций Lasso Cache он будет управлять собой в CacheFactory, который был передан для его создания.
Фабрика общего кэша хранит кэши и позволяет управлять ими через структуры GVK. После создания кэшей их можно использовать повторно.
Фабрика общих клиентов существует для того, чтобы клиент для GVK можно было повторно использовать после его создания.
SharedControllerFactory связывает все вышеперечисленное воедино. Он позволяет использовать единую точку входа для доступа к клиентам, кэшам и обработчикам — всем, чем он управляет за вас. В основном можно взаимодействовать с общей фабрикой контроллеров. Он создаст все необходимые вам базовые контроллеры, клиенты и кеши. Это обеспечит отсутствие дубликатов этих объектов. Это предотвратит условия гонки.
Когда вы используете ForObject, ForKind, ForResource или ForResourceKind, SharedControllerFactory выполнит следующее:
deferredController — это функция, которая после выполнения создаст и вернет контроллер. Он создаст контроллер, используя кеш из SharedCacheFactory. Цель функции deferredController — отложить заполнение кэша до тех пор, пока это не станет абсолютно необходимым. Это гарантирует, что в памяти будут храниться только те ресурсы Kubernetes, которые зарегистрировали обработчики, были поставлены в очередь или получили запрос к кешу контроллера.
Когда вы получаете общий контроллер из SharedControllerFactory, у него еще не будет создан экземпляр базового контроллера. Вместо этого он будет вызывать метод deferredController для его создания после выполнения одной из упомянутых операций.
Ниже приведены шаги для простого способа регистрации обработчиков и запуска их в лассо:
package main
import (
"context"
"github.com/rancher/lasso/pkg/controller"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
)
func main () {
config , err := clientcmd . BuildConfigFromFlags ( "" , os . Getenv ( "KUBECONFIG" ))
if err != nil {
panic ( err )
}
// Setup types you want to work with
scheme := runtime . NewScheme ()
appsv1 . AddToScheme ( scheme )
controllerFactory , err := controller . NewSharedControllerFactoryFromConfig ( config , scheme )
if err != nil {
panic ( err )
}
// ForObject, ForKind, ForResource, and ForResourceKind can all be used to retrieve the controller.
// They all accept different parameters but the first three all eventually call ForResourceKind.
// Refer to [How to use Lasso](#how-to-use-lasso) for more information on how ForResourceKind works.
sharedController , err := controllerFactory . ForObject ( & appsv1. Deployment {})
if err != nil {
panic ( err )
}
// Register a handler on a shared controller. If you need a dedicated queue then use controller.New()
sharedController . RegisterHandler ( context . TODO (), "my-handler" , controller . SharedControllerHandlerFunc ( func ( key string , obj runtime. Object ) (runtime. Object , error ) {
// obj is the latest version of this obj in the cache and MAY BE NIL when an object is finally deleted
dep , ok := obj .( * appsv1. Deployment )
if ! ok {
return obj , nil
}
// Do some stuff ...
// Get stuff from the cache
sharedController . Informer (). GetStore (). Get ( key )
result := & appsv1. Deployment {}
err := sharedController . Client (). Update ( ctx , dep . Namespace , dep , result , metav1. UpdateOptions {})
// return the latest version of the object
return result , err
}))
// the second, int parameter is the number of workers to be used for EACH controller.
err = controllerFactory . Start ( context . TODO (), 5 )
if err != nil {
panic ( err )
}
}
Некоторые тесты lasso используют для запуска envtest. Envtest позволяет запускать тесты на «поддельном» сервере Kubernetes с небольшими накладными расходами или вообще без них.
Чтобы установить необходимый двоичный файл setup-envtest
, используйте следующую команду:
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
Перед запуском тестов вы должны запустить следующую команду для настройки поддельного сервера:
# note that this will use a new/latest version of k8s. Our CI will run against the version of k8s that corresponds to lasso's
# current client-go version, as seen in scripts/test.sh
export KUBEBUILDER_ASSETS= $( setup-envtest use -p path )
Следующие ресурсы были полезны при написании этих документов. Они настоятельно рекомендуются для изучения большего, чем то, что представлено здесь: