Примечание переводчика: В преддверии 10-летней годовщины со дня выхода Kubernetes 1.0 DevOps-инженер Мэт Дугган поразмышлял о том, что могло бы войти в релиз 2.0. Например, предложил заменить YAML и etcd, а также существенно переработать пакетный менеджер. Статья наделала шума в сообществе — её обсуждают как на Reddit и Hacker News, так и в русскоязычных каналах. Перевели текст для тех, кому не очень комфортно читать на английском, а посмотреть и обсудить предложенные идеи хочется. Слово автору.
Приблизительно в 2012–2013 годах в сообществе системных администраторов стали говорить о технологии под названием «Borg». По всей видимости, это была некая система Linux-контейнеров внутри Google, на которой работали все их сервисы. Терминология несколько озадачивала — «Borglet'ы» внутри кластеров с «ячейками» (cells), но подробности постепенно начали просачиваться наружу. Были «сервисы» (services) и «задачи» (jobs). Приложения могли использовать сервисы для ответа на запросы пользователей, а job'ы — для выполнения пакетных задач, которые выполнялись в течение длительных периодов времени.
7 июня 2014 года был сделан первый коммит в репозиторий Kubernetes. Это греческое слово, означающее «рулевой», которое в течение первых трёх лет никто не мог правильно произнести. (Это ку-бер-НЕТ-ис? ку-бер-НИТ-ис? Проще сдаться и называть его K8s, как все вокруг.)
Вскоре после этого к сообществу Kubernetes присоединились Microsoft, Red Hat, IBM и Docker, что превратило Kubernetes из прикольной гугловской поделки в нечто, заставившее задуматься: «А может, это и правда серьёзный продукт?» 21 июля 2015 года параллельно с анонсом CNCF вышла первая версия.
За десять лет, прошедших с того первого коммита, Kubernetes стал значительной частью моей профессиональной деятельности. Я применяю его дома, на работе, в сторонних проектах — везде, где это целесообразно. Да, сначала приходится почитать-поучиться, но в итоге получаешь мощнейший ускоритель. Мы больше не «управляем инфраструктурой» на уровне серверов; всё является декларативным, масштабируемым, восстанавливаемым и (если повезёт) самовосстанавливающимся.
Однако путь оркестратора не был безоблачным. Вылезли некоторые общие «косяки», когда ошибки или «кривые» конфигурации появляются из-за недостаточной категоричности Kubernetes. Даже спустя десять лет в экосистеме по-прежнему наблюдается значительная текучесть, а специалисты раз за разом наступают на хорошо задокументированные «грабли». И вот вопрос: зная то, что мы знаем сейчас, что́ можно было бы сделать иначе, чтобы этот классный инструмент подошел ещё большему количеству людей и решил ещё больше проблем?
Что было успешно реализовано в Kubernetes?
Начнём с положительных сторон. Почему K8s остаётся актуальным?
Контейнеры
Использование контейнеров как инструмента для разработки программного обеспечения — отличная идея. Можно, наконец, забыть о путанице индивидуальных настроек, получив единый стандарт, применимый ко всему стеку технологий. Инструменты вроде Docker Compose позволяли развёртывать контейнеры, но были громоздкими и требовали от администратора ручного управления многими этапами процесса. Как и многие специалисты, я настраивал стек на базе Compose со скриптом развёртывания, который удалял инстанс из балансировщика нагрузки, загружал новые контейнеры, убеждался в их успешном запуске и снова добавлял его в балансировщик.
Kubernetes масштабировал эту концепцию: теперь можно было брать контейнер с локальной машины разработчика и развёртывать его на тысячах серверов. Такая гибкость позволила организациям пересмотреть свои стратегии проектирования, способствуя отказу от монолитов и переходу к более гибким (и зачастую более сложным) микросервисным решениям.
Простота в обслуживании
Если рассматривать историю эксплуатации как своего рода хронологию перехода от парадигмы «питомцев» к «стаду», то мы начали с периода, который я ласково называю «эпоха Симпсонов».
Серверы представляли собой физическое оборудование (bare metal), настраиваемое вручную; им часто давали уникальные имена, которые становились внутренним сленгом, и каждая система была уникальна. Чем дольше работал сервер, тем больше он накапливал программного мусора и старья, пока простая перезагрузка — не говоря уже о пересборке — не превращалась в рискованную операцию. Я называю этот период «эпоха Симпсонов», потому что на нескольких моих прошлых работах на удивление часто серверы называли в честь персонажей этого мультсериала. Ничто не исправлялось автоматически, все операции выполнялись вручную.
Далее наступила «эпоха 01». Вошли в обиход такие инструменты, как Puppet и Ansible, серверы стали более одноразовыми, а хосты-бастионы и другие системы контроля доступа стали стандартом. Серверы перестали смотреть напрямую в интернет — теперь они стояли за балансировщиками нагрузки, а милые имена поменялись на что-то вроде «app01» или «vpn02». Компании строили архитектуру так, чтобы потеря нескольких серверов не была критичной. Однако сбои всё ещё требовали ручного вмешательства: кому-то всё равно приходилось подключаться по SSH, смотреть, что сломалось, писать фикс и раскатывать его на весь парк машин. Обновление операционных систем оставалось сложной задачей.
Сейчас мы живем в «эпоху UUID». Серверы нужны лишь для того, чтобы запускать контейнеры; они стали полностью одноразовыми. Никого больше не волнует, как долго поддерживается та или иная версия ОС — вы просто создаёте новый образ (AMI) и заменяете всю машину целиком. K8s был не единственной технологией, которая позволяла это делать, но именно он сильно ускорил процесс. Теперь идея зайти на сервер-бастион по SSH-ключу, чтобы починить что-то на узле, воспринимается как решение «на крайний случай». Почти все проблемы решаются по принципу: «убей этот узел, пусть K8s сам разберётся и поднимет новый».
Многие навыки работы с Linux, которые были критически важны для моей карьеры, теперь в значительной степени желательны, но не обязательны. Можно относиться к этому с радостью или с грустью — я, безусловно, регулярно испытываю оба этих чувства, — но такова реальность.
Запуск задач (jobs)
Система задач в K8s не идеальна, но в разы лучше, чем «тот самый сервер cron01» — решение, которое годами встречалось на каждой работе. Запуск по cron-расписанию или из очереди сообщений — теперь можно было надёжно поставить задачу в очередь, дождаться её выполнения, обеспечить перезапуск в случае неудачи и спокойно продолжать заниматься другими делами.
Такой подход не только освобождает инженеров от трудоёмкой и монотонной работы, но и обеспечивает более эффективное использование вычислительных ресурсов. Для каждого элемента в очереди по-прежнему запускается отдельный под, однако концепция пода предоставляет командам значительную гибкость в определении того, что и как они хотят запустить. Это значительно упростило жизнь мне и куче других людей. Теперь можно просто скидывать задачи в фон и не думать о них.
Обнаружение сервисов и балансировка нагрузки
Жёстко закодированные IP-адреса, используемые в приложениях для маршрутизации запросов, — проклятие, которое преследовало меня на протяжении многих лет. В лучшем случае зависимости основывались не на IP-адресах, а на записях DNS, что позволяло изменять ресурс без необходимости координировать развёртывание множества приложений.
Kubernetes позволил обращаться к другим сервисам по простым DNS-именам. Это устранило целую категорию ошибок и сильно упростило весь процесс. Благодаря Service API вы получаете стабильный, долгоживущий IP-адрес и имя хоста, на которые можно направлять запросы, не задумываясь о том, как всё работает. Более того, концепции вроде ExternalName позволяют работать с внешними сервисами так, как если бы они находились внутри кластера.
Что я включил бы в Kubernetes 2.0?
Заменил бы YAML на HCL
YAML поначалу казался привлекательным, потому что это был не JSON и не XML — хотя это всё равно что заявить, что новая машина хороша тем, что она не лошадь и не одноколесный велосипед. Да, он приятнее выглядит в демках для K8s, лучше смотрится в репозитории и создаёт иллюзию простого формата. В реальности же YAML слишком избыточен для того, что мы пытаемся делать с K8s, и при этом недостаточно безопасен. Отступы чреваты ошибками, файлы плохо масштабируются (большой YAML-файл — плохая затея, поверьте), а отладка может стать настоящей головной болью. В спецификации YAML описано великое множество неочевидных нюансов.
До сих пор помню своё удивление, когда впервые столкнулся с «проблемой Норвегии». Для тех, кому повезло её избежать, поясню: «проблема Норвегии» в YAML заключается в том, что строковое значение 'NO' интерпретируется как булево false. Представьте, что вам необходимо объяснить норвежским коллегам, что YAML в конфигах отрицает существование их страны. К этому можно добавить случайное преобразование строк в числа из-за отсутствия кавычек, и список проблем можно продолжать ещё долго. Впрочем, есть гораздо более подробные статьи о недостатках YAML, чем я мог бы написать.
Почему именно HCL?
HCL уже является форматом для Terraform, так что, по крайней мере, нам придётся иметь дело с одним языком конфигурации вместо двух. У него строгая и явная типизация. В него встроены надёжные механизмы валидации. Он специально разработан для тех задач, которые мы возлагаем на YAML, и при этом ненамного сложнее для чтения. В HCL есть встроенные функции, которые уже широко используются и которые позволили бы отказаться от некоторых сторонних инструментов, необходимых при работе с YAML.
Готов поспорить: 30 % всех Kubernetes-кластеров сегодня уже управляются с помощью HCL через Terraform. Но нам не нужен Terraform, чтобы получить массу преимуществ этого замечательного языка описания конфигураций.
Единственные недостатки заключаются в том, что HCL немного более многословен, чем YAML, а его лицензия Mozilla Public License 2.0 (MPL-2.0) потребует тщательного юридического анализа для интеграции в проект с лицензией Apache 2.0, коим является Kubernetes. Но ради такого качественного скачка в удобстве эти препятствия стоит преодолеть.
Почему HCL лучше
Возьмём простой YAML-файл.
# YAML не следит за соблюдением типов.
replicas: "3" # String вместо integer.
resources:
limits:
memory: 512 # Отсутствует единица измерения.
requests:
cpu: 0.5m # Ошибка в значении (должно быть 500m).
Даже в самом базовом примере полно «подводных камней». HCL и его система типов отловили бы все эти проблемы.
replicas = 3 # Целое значение.
resources {
limits {
memory = "512Mi" # String для памяти.
}
requests {
cpu = 0.5 # Число для CPU.
}
}
Возьмите типичный YAML вроде этого, которых у вас в репозитории Kubernetes, наверное, тысячи. А теперь посмотрите на HCL, которому не нужны никакие сторонние костыли.
# Требуются внешние инструменты или шаблоны для динамических значений.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
# Не умеет генерировать или преобразовать значения.
DATABASE_URL: "postgres://user:password@db:5432/mydb"
API_KEY: "static-key-value"
TIMESTAMP: "2023-06-18T00:00:00Z" # Явно прописанная временная метка.
resource "kubernetes_config_map" "app_config" {
metadata {
name = "app-config"
}
data = {
DATABASE_URL = "postgres://${var.db_user}:${var.db_password}@${var.db_host}:${var.db_port}/${var.db_name}"
API_KEY = var.api_key != "" ? var.api_key : random_string.api_key.result
TIMESTAMP = timestamp()
}
}
resource "random_string" "api_key" {
length = 32
special = false
}
Вот плюсы, которые получаем от перехода на HCL:
Строгая типизация: защищает от ошибок с типами ещё до деплоя.
Переменные и ссылки: уменьшают дублирование и упрощают поддержку.
Функции и выражения: позволяют генерировать конфигурации динамически.
Условная логика: помогает настраивать приложение под разные окружения.
Циклы и итерации: упрощают повторяющиеся конфигурации.
Лучшие комментарии: повышают удобство работы с документацией и читаемость.
Обработка ошибок: помогает быстрее находить и исправлять ошибки.
Модульность: даёт возможность переиспользовать части конфигурации.
Валидация: предотвращает невалидные конфигурации.
Трансформация данных: поддерживает сложные преобразования данных.
Замена etcd
Знаю — я далеко не первый, кто поднимает этот вопрос. Хранилище etcd прекрасно справляется со своими задачами, странно только, что это единственный доступный инструмент для хранения состояния кластера. В случае небольших кластеров или аппаратных конфигураций etcd потребляет неоправданно много ресурсов, при этом количество узлов в таких системах никогда не достигнет того порога, при котором его использование становится оправданным. Кроме того, на текущий момент сложились своеобразные взаимоотношения между Kubernetes и etcd — Kubernetes, по сути, остался его единственным крупным пользователем.
Я предлагаю взять наработки проекта kine и сделать их официальной частью Kubernetes. Для долгосрочного развития проекта стратегически важно иметь возможность подключения различных бэкендов. Добавление такого уровня абстракции (в теории) упростит замену и интеграцию новых хранилищ в будущем, а также позволит более тонко настраивать систему в зависимости от используемого аппаратного обеспечения.
Думаю, в итоге это будет выглядеть примерно так. Распределённый in-memory SQLite (то есть живущий в памяти) с консенсусом по протоколу Raft, который почти не требует работы по обновлению. Это дало бы операторам кластеров больше гибкости при работе с уровнем хранения данных в инсталляциях Kubernetes. Если у вас обычный серверный сетап в дата-центре и ресурсы, которые потребляет etcd, не проблема — здорово! Но то, что предлагаю я, сделает работу с K8s на слабом железе приятнее и (надеюсь) уменьшит зависимость от проекта etcd.
Больше чем Helm: нативный менеджер пакетов
Helm — прекрасный пример временного костыля, который превратился в постоянную зависимость. Я признателен мейнтейнерам Helm за их тяжёлую работу, ведь они вырастили из хакатон-проекта общепринятый способ установки софта в кластеры K8s. Для инструмента без глубокой интеграции в Kubernetes он справлялся со своими задачами на удивление хорошо.
Но, если честно, работа с Helm — сущий кошмар. Его Go-шаблоны сложно отлаживать: часто они содержат мудрёную логику, которая выливается в совершенно запутанные сценарии ошибок. А сами сообщения об ошибках в таких случаях — просто бессвязная каша. Helm нельзя назвать хорошим пакетным менеджером, поскольку он проваливает базовые задачи, которые от него ждёшь, а именно обработку транзитивных зависимостей и разрешение конфликтов между ними.
О чём это я?
А вот о чём! Скажите-ка мне, что делает эта условная логика:
# Реальный пример мудреной условной логики в Helm.
{{- if or (and .Values.rbac.create .Values.serviceAccount.create) (and .Values.rbac.create (not .Values.serviceAccount.create) .Values.serviceAccount.name) }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ template "myapp.fullname" . }}
labels:
{{- include "myapp.labels" . | nindent 4 }}
{{- end }}
Или вот, если я подсуну чарту несколько файлов с переменными, какой из них победит?
helm install myapp ./mychart -f values-dev.yaml -f values-override.yaml --set service.type=NodePort
Окей, а что, если я захочу управлять своим приложением и всеми его зависимостями через Helm-чарт? Звучит логично: есть приложение, у которого есть зависимости, так что имеет смысл собрать их все вместе. Для этого создаю саб-чарты (или umbrella-чарты) в Chart.yaml.
dependencies:
- name: nginx
version: "1.2.3"
repository: "<https://example.com/charts>"
- name: memcached
version: "1.2.3"
repository: "<https://another.example.com/charts>"
Но если у меня несколько приложений, вполне может случиться, что у двух сервисов появится зависимость от одного и того же nginx или чего-то подобного.

Helm не может изящно справиться с такой ситуацией, потому что имена шаблонов — глобальные, а загружаются они по алфавиту. В итоге:
Приходится не объявлять зависимость от одного и того же чарта более одного раза (что затруднительно в архитектуре с большим количеством микросервисов).
Если один и тот же чарт всё же объявлен несколько раз, он должен иметь абсолютно идентичную версию.
И этот список проблем можно продолжать до бесконечности:
Установка в разные пространства имён просто отвратительна.
Процесс верификации чартов — та ещё головная боль, и им никто не пользуется.
Давайте просто зайдём на главную страницу Artifact Hub...

Возьму-ка я elasticsearch — кажется, это что-то важное.


С официальным Helm-чартом Elastic дела обстоят плачевно. Ну с ingress-nginx
уж точно должно быть всё в порядке — это же абсолютно критическая зависимость для всей отрасли:

Ан нет. Как вообще так получается, что мейнтейнер чарта — Kubernetes, а он до сих пор не помечен как «проверенный издатель» (verified publisher
)? Господи, да куда уж провереннее-то…
Нет поиска по метаданным. Искать можно только по имени и описанию, но не по фичам, возможностям или другим метаданным.

Helm не следит за семантическим версионированием.
# Chart.yaml с НЕсемантическим версионированием.
apiVersion: v2
name: myapp
version: "v1.2-alpha"
Если удалить и переустановить чарт с CRD, он может «прибить» ресурсы, созданные этими CRD. Сто раз на этом попадался — дико небезопасная фича.
Можно накатать ещё 100 томов, и их всё равно не хватило бы, чтобы описать все проблемы. Невозможно сделать Helm достаточно хорошим «пакетным менеджером для всей критической инфраструктуры на планете».
Каким должен быть пакетный менеджер для Kubernetes
Давайте назовём нашу гипотетическую пакетную систему KubePkg, потому что если экосистеме Kubernetes чего-то и не хватает, так это ещё одного названия на букву «K». Разумно скопировать как можно больше существующих наработок из экосистемы Linux, используя при этом всю мощь CRD в K8s. Моя идея выглядит примерно так:

Пакеты представляют собой бандлы, подобные пакетам в Linux:

Есть файл с определением, который учитывает максимум реальных сценариев, с которыми можно столкнуться при установке чего-либо.
apiVersion: kubepkg.io/v1
kind: Package
metadata:
name: postgresql
version: 14.5.2
spec:
maintainer:
name: "PostgreSQL Team"
email: "maintainers@postgresql.example.com"
description: "PostgreSQL database server"
website: "https://postgresql.org"
license: "PostgreSQL"
# Зависимости с указанием семантических версий.
dependencies:
- name: storage-provisioner
versionConstraint: ">=1.0.0"
- name: metrics-collector
versionConstraint: "^2.0.0"
optional: true
# Контекст безопасности и требования.
security:
requiredCapabilities: ["CHOWN", "SETGID", "SETUID"]
securityContextConstraints:
runAsUser: 999
fsGroup: 999
networkPolicies:
- ports:
- port: 5432
protocol: TCP
# Ресурсы, которые необходимо создать (встроенные или ссылки).
resources:
- apiVersion: v1
kind: Service
metadata:
name: postgresql
spec:
ports:
- port: 5432
- apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql
spec:
# Определение StatefulSet'а.
# Схема конфигурации с использованием JSON Schema.
configurationSchema:
type: object
properties:
replicas:
type: integer
minimum: 1
default: 1
persistence:
type: object
properties:
size:
type: string
pattern: "^[0-9]+[GMK]i$"
default: "10Gi"
# Хуки жизненного цикла в надлежащем порядке.
hooks:
preInstall:
- name: database-prerequisites
job:
spec:
template:
spec:
containers:
- name: init
image: postgres:14.5
postInstall:
- name: database-init
job:
spec:
# Определение job'ы.
preUpgrade:
- name: backup
job:
spec:
# Определение backup job'ы.
postUpgrade:
- name: verify
job:
spec:
# Определение verification job'ы.
preRemove:
- name: final-backup
job:
spec:
# Определение конечной backup job'ы.
# Управление состоянием для stateful-приложений.
stateManagement:
backupStrategy:
type: "snapshot" # или "dump"
schedule: "0 2 * * *" # Daily at 2 AM
retention:
count: 7
recoveryStrategy:
type: "pointInTime"
verificationJob:
spec:
# Job для проверки успешности восстановления.
dataLocations:
- path: "/var/lib/postgresql/data"
volumeMount: "data"
upgradeStrategies:
- fromVersion: "*"
toVersion: "*"
strategy: "backup-restore"
- fromVersion: "14.*.*"
toVersion: "14.*.*"
strategy: "in-place"
Есть полноценный и обязательный процесс подписи, который обеспечил бы контроль за процессом.
apiVersion: kubepkg.io/v1
kind: Repository
metadata:
name: official-repo
spec:
url: "https://repo.kubepkg.io/official"
type: "OCI" # or "HTTP"
# Настройки верификации.
verification:
publicKeys:
- name: "KubePkg Official"
keyData: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvF4+...
-----END PUBLIC KEY-----
trustPolicy:
type: "AllowList" # или "KeyRing"
allowedSigners:
- "KubePkg Official"
- "Trusted Partner"
verificationLevel: "Strict" # или "Warn", "None"
Представляете, как круто было бы иметь нечто, что автоматически обновляло бы пакеты без участия пользователя.
apiVersion: kubepkg.io/v1
kind: Installation
metadata:
name: postgresql-main
namespace: database
spec:
packageRef:
name: postgresql
version: "14.5.2"
# Значения конфигурации (проверенные на соответствие схеме).
configuration:
replicas: 3
persistence:
size: "100Gi"
resources:
limits:
memory: "4Gi"
cpu: "2"
# Политика обновлений.
updatePolicy:
automatic: false
allowedVersions: "14.x.x"
schedule: "0 2 * * 0" # Еженедельно по воскресеньям в 2:00.
approvalRequired: true
# Ссылка на управление состоянием.
stateRef:
name: postgresql-main-state
# Используемый Service account.
serviceAccountName: postgresql-installer
Kubernetes нужна система, отвечающая следующим требованиям:
Истинно нативная для Kubernetes: всё является ресурсом Kubernetes с соответствующими статусами и событиями.
Первоклассное управление состоянием: встроенная поддержка stateful-приложений.
Повышенная безопасность: толковый механизм подписания, верификация и сканирование.
Декларативная конфигурация: никаких шаблонов, только структурированная конфигурация со схемами.
Управление жизненным циклом: комплексные хуки жизненного цикла и стратегии обновления.
Разрешение зависимостей: управление зависимостями в стиле Linux с семантическим версионированием.
Журнал аудита: полная история изменений с информацией о том, кто, что и когда сделал, а не то, что сейчас предлагает Helm.
Контроль за соблюдением политик: поддержка организационных политик и комплаенс.
Упрощённый UX: привычные команды управления пакетами, как в Linux. Кажется просто дикостью, что мы пытаемся идти каким-то иным путём, отличным от пакетных систем, которые работают десятилетиями.
IPv6 по умолчанию
Только представьте, сколько времени и сил по всему миру ушло на попытки решить каждую из следующих проблем:
Нужно, чтобы под в этом кластере мог связаться с подом в том кластере.
Где-то в процессе прохождения NAT возникла проблема, и её нужно решить.
В кластере закончились IP-адреса, потому что ошиблись с оценкой нужного их количества. Классический случай: компания начинает с подсетью /20 (4096 адресов), развёртывает 40 узлов по 30 подов в каждом и внезапно осознаёт, что лимит IP почти исчерпан. А ведь узлов не так уж и много!
Я не предлагаю всему интернету прямо сейчас переключиться на IPv6, к тому же K8s и без того прекрасно поддерживает и режим «только IPv6», и dual-stack (одновременную работу с IPv4 и IPv6). Но всё же настало время сменить настройку по умолчанию и просто перейти на IPv6. Одним махом устраняется огромное количество проблем:
Более плоская и простая сетевая топология внутри кластера.
Возможность для организаций абстрагироваться от границ между кластерами при использовании публичных IP-адресов.
Упрощённый анализ потоков трафика внутри технологического стека.
Встроенная поддержка IPSec.
Я не пытаюсь ускорить глобальное внедрение IPv6, а лишь признаю тот факт, что мы больше не живём в мире, где необходимо принимать странные ограничения IPv4, особенно в условиях, когда внезапно могут потребоваться десятки тысяч IP-адресов.
Преимущества для организаций с публичными IPv6-адресами очевидны, но существует и значительная ценность для облачных провайдеров и пользователей, так что даже корпоративные гиганты могут поддержать эту идею. Например, AWS больше не нужно будет изыскивать дополнительное пространство частных IPv4-адресов внутри VPC. Это определённо чего-то стоит.
Заключение
Частый ответ на все эти идеи: «Но ведь Kubernetes — открытая платформа, сообщество само может всё это реализовать». Согласен, но такой аргумент упускает главное: «умолчания» — самая мощная сила в технологиях. Тот самый «счастливый путь» (happy path), который заложен в ядре проекта, определяет, как 90 % пользователей будут с ним работать. Если система по умолчанию будет требовать подписанные пакеты и предоставит надёжный нативный инструмент для управления ими, то именно это экосистема и возьмёт на вооружение.
Список амбициозный, я знаю. Но если уж мечтать, так по-крупному. В конце концов, мы же работаем в индустрии, где кто-то решил, что название «Kubernetes» приживётся — и ведь оно прижилось!
Мы постоянно видим подобное в других сферах, например в мобильной и веб-разработке, где платформы оценивают ситуацию и совершают радикальные рывки вперёд. Не факт, что за все эти проекты взялись бы мейнтейнеры или компании, но мне кажется, к этим идеям кто-то должен вернуться и подумать: «Не пора ли нам этим заняться теперь, когда на нашу долю приходится столь нетривиальный процент всех операций в дата-центрах по всему миру?»
Есть вопросы или хотите дать обратную связь Пишите: https://c.im/@matdevdug
P. S.
Читайте также в нашем блоге:
Комментарии (2)
M0rdecay
27.06.2025 11:56Всё описанное очень сильно похоже на... Nomad. Всё описывается в HCL нативно (ну ещё бы), пакетный менеджер из коробки (Nomad Pack), всё состояние хранится в распределенном Consul KV.
Даже немного обидно, что номад не популярен, приходилось с ним работать, и лично мне он показался гибче и проще в настройке и обслуживании, чем кубер. Плюс, умеет в оркестрацию не только контейнеров, но и, например, джавовых сервлетов и обычных бинарей
YaDr
По замене yaml/json на HCL
yaml/json - языки описывающие объекты, конвертируются друг в друга легко и непринужденно, внешние вызовы "не умеют". Хочешь динамическое значение - рендери тот же YAML чем-то снаружи. HCL же вообще из другой области и представляет собой DSL с вызовами, для задач кубера не подходит примерно никак. Если предлагается хранить голый HCL в etcd, с его "random_string" и ко - то придется тащить аналог terraform state в тот же etcd, что бред по многим причинам. Если рендерить HCL в что-то статичное (да тот же yaml) - то это и сегодня можно сделать. Резюмируя - идея бредовая.
etcd прекрасно работает от 1й ноды and up. Скейлится мощнейще. Посмотрел на домашнем кластере из 3х нод etcd - суммарное потребление 3х инстансов = 108m cpu, 1208Mi ram. Весьма скромно. Не совсем понятно о каком lower-end k8s experience он говорит - кластер из трех Raspberry pi 4?.. Так даже они начинаются с 8гб рамы теперь... Просто так прикручивать альтернативы - классическое "решение, ищущее проблему".
Helm да, стал стандартом при этом имея тонну лютых недостатков. Заменить его было бы очень хорошо.
IPv6 "в дефолте" - зачем? Дебаг усложнить? Приведенные проблемы решены текущим дизайном куба с самого начала.
4.1) Общаться "pod-pod по внутренним айпи между кластерами" - бред, специально для этого созданы сервисы и ингрессы. IPv6 проблему "мы выдали две одинаковых серых сети двум кластерам и хотим в нарушение всех концептов k8s общаться pod-pod между кластерами, но у нас внутренние ip пересекаются" не решит никак.
4.2) NAT в кубе, в общем-то, простейший. Один на входе в сервис, если у того 'internalTrafficPolicy: Cluster' стоит. Конкретный случай он не описал, а каких-то широкоизвестных "NAT-проблем" у кубера и нет.
4.3) Так и IPv6 можно выдать /116 на весь кластер и так же внезапно "кончатся адреса". Вопрос планирования.
Вообще через весь его спич про IPv6 сквозит "я хочу роутиться к подам напрямую, мимо сервисов и ингрессов, но нормально спланировать это не могу".
Резюмируя - три откровенно бредовых идеи и одна нормальная. Meh.