Это шутливая статья, не стоит ее воспринимать серьезно.

Источником вдохновения выступила статья и высказывание в чатике kubernetes_ru, а также дискуссия на эту тему с Дмитрием Евдокимовым из luntry,  а триггером к написанию - пост Дмитрия

client-go - наше все 

На самом деле, большая часть магии куба находится в этом пакете. Используют контроллеры, kube-apiserver, kubelet. Что неудивительно, если посмотрим в описание на гитхабе, то увидим следующий список, что включено в данный пакет:

  • The kubernetes package contains the clientset to access Kubernetes API.

  • The discovery package is used to discover APIs supported by a Kubernetes API server.

  • The dynamic package contains a dynamic client that can perform generic operations on arbitrary Kubernetes API objects.

  • The plugin/pkg/client/auth packages contain optional authentication plugins for obtaining credentials from external sources.

  • The transport package is used to set up auth and start a connection.

  • The tools/cache package is useful for writing controllers.

Но самая мощь, по моему мнению - это informers. Более подробно можно почитать здесь, если коротко, это подход который позволяет избегать continuous polling к API, иначе это могло бы привести к деградация нашего кластера. 

client-go
client-go

Если посмотрим на первый пункт что произойдет когда сделаем kubectl apply - то увидим, что сперва производится валидация данных, перед тем как отправить запрос, если валидация прошла успешно - отправляется запрос и получает OpenAPI schema которая хэшируется, чтобы меньше нагружать как kube-apiserver, так и etcd. 

Это подход называется client-side caching, и используется, например, в redis

Но не забываем, что client-go есть в kube-apiserver, а так же имеется пакет cacher, задача которого - кэшировать ответы, чтобы не нагружать сторадж. Если интересно чуть более подробнее почитать, то можно это сделать здесь. Это уже server-side caching.

Таким образом мы получаем распределенную систему хранения кэша, то есть по сути своей - распределенную in-memory database. 

в кубе все YAML-манифесты?

А так ли это? На самом деле kubernetes ничего не знает про YAML.  Это лишь упрощенный способ  людей визуализировать схему данных которая хранится в etcd (не только, но об этом позже).  С  YAML умеет работать cli.  Cli уже валидирует, а затем и генерит данные в формате OpenAPI schema. Вот с ним уже kube-apiserver и работает.  Эту схему мы уже можем поменять, через изменение CRD. 

Если посмотреть на порядок обновления компонентов в kubernetes, то можно заметить, что первым будет обновляться etcd, потом  kube-apiserver, а затем уже сильно не важно что, и в каком порядке (утрирую). А почему так? Потому что необходимы наши любимые миграции. Есть KEP на эту тему. 

Таким образом у нас особо нет особой привязки к yaml-манифестам. Мы не перемещаем YAML-файлы для обновления kubernetes. А работаем по тем же правилам, как и с обычной базой данных.

ETCD - это же база данных, причем тут kubernetes?

ETCD довольно простая k-v база данных. В ней нет очередей, нет поисков по лейблам. Если интересно про ETCD, рекомендую вот эту и эту статьи. Я бы сказал бы, что ETCD для kubernetes -  это движок, который еще умеет данные реплицировать (на самом деле у ETCD движок bbolt, но я намеренно упрощаю).  Такой упрощенный аналог leveldb/rockdb для kuberntes.  Еще одним доказательством, что ETCD для kubernetes - это движок, является проект kine. Для нас, как пользователей работы с БД, ничего не меняется. Мы так же взаимодействуем с API, меняем схемы через CRD и так далее. Меняется только способ хранения данных, скрытый от нас под капотом (а под капотом, обычно, находится двигатель))).

В ETCD на запись мы всегда упираемся в лидера. И нам нужно как-то эту запись скейлить. Сам ETCD в шардирование не умеет. Таким образом, в  ETCD отсутствуют много разных вещей, которые бы упрощали нам работу в нагруженных и распределенных системах. 

И тут нам на помощь приходит kube-apiserver. Использование версионирования, поиск по лейблам, полям, объектам - со всем этим умеет работаеть kube-apiserver.

Необходим шардинг? опция --etcd-servers-override в kube-apiserver позволяет нам в рамках нашего кластера использовать более одного ETCD кластера (в моей практике, чаще всего приходилось выделять отдельные ETCD для /events и для CNI). Таким образом мы можем скейлить наш кластер и на запись.

Вообще, данная схема c "умным" api gateway, который умеет в service discovery, кэширование и так далее, используется во многих распределенных базах данных, например в spanner похожее поведение у location proxy, в cockroach - proxy pod (не тот pod что в kubernetes))), ydb - grpc proxy c query движком. 

Так что kubernetes вполне проходит утиный тест как распределенная база данных - если нечто выглядит как утка, плавает как утка и крякает как утка, то это, вероятно, и есть утка.

Кстати, если интересна тема с распределёнными базами данных, то рекомендую курс Романа Липовского. Cмотрел данный курс с большим удовольствием.

Комментарии (0)