Примерно в 2012-2013 году в сообществе сисадминов стали много говорить о технологии под названием «Borg». Складывалось впечатление, что это какая-то система управления контейнерами, основанная на Linux и применяемая в Google — с её помощью они эксплуатируют свои внутренние ресурсы. Терминология по этой системе немного озадачивала; внутри кластеров, состоящих из «ячеек» (cells), в ней находились какие-то «борглеты», но суть уже на данном этапе начинала ускользать. В системе существовали концепции «сервисов» (services) и «заданий» (jobs), так, что приложения могли при помощи сервисов откликаться на пользовательские запросы, после чего система собирала задания в пакеты, и эти пакетные задания уже выполнялись достаточно долго.
Затем, 7-го июня 2014 года состоялся первый коммит в Kubernetes. Это греческое слово означает «кормчий», и в течение первых трёх лет существования этой технологии решительно никто не понимал, как его правильно произносить. Поэтому пришлось сдаться и позволить простым смертным обозначать его как k8s.
Довольно скоро к работе с Kubernetes подключились Microsoft, RedHat, IBM, Docker, благодаря чему статус Kubernetes очень быстро повысился от какой-то диковины из Google до «а может быть, ему найдётся реальное применение»? 21 июля 2015 года состоялся релиз версии 1.0, а также был создан фонд CNCF.
Спустя десять лет после того исходного коммита Kubernetes стал играть важную роль в моей профессиональной деятельности. Я пользуюсь им дома, на работе, применяю его в сайд-проектах — и везде он уместен. Кривая обучения у этого инструмента крутая, но, в то же время, он кратно вас усиливает. Мы более не «управляем инфраструктурой» на уровне серверов; вся она стала декларативной, хорошо масштабируется, восстанавливается после отказов и (если вам повезёт) самозалечивается.
Но не сказать, что этот путь прошёл без проблем. Уже прослеживаются общие тенденции: смысловые или конфигурационные ошибки возникают именно там, где к Kubernetes относятся недостаточно продуманно. Даже через десять лет наблюдается значительный отток кода внутри экосистемы, а специалисты подрываются даже на тех «минах» в коде, которые хорошо документированы. Итак, располагая теми знаниями, что есть у нас сейчас, что можно скорректировать в нашей работе, чтобы такой отличный инструмент как Kubernetes находил ещё более широкое применение при решении различных задач и помогал ещё более широкому кругу пользователей?
Что в k8s как следует налажено?
Начнём с хорошего. Почему мы до сих пор рассуждаем об этой платформе?
Широкомасштабное использование контейнеров
Использовать контейнеры при разработке софта более чем целесообразно. Забудьте о той путанице, которая возникает, когда каждый ноутбук сконфигурирован по-своему и внедрите один стандарт. Это расхожая концепция, применимая в пределах всего стека. Такие инструменты как Docker Compose в некоторой степени справляются с развёртыванием контейнеров, но они неудобны в работе, и обслуживающему их системному администратору требуется управлять множеством шагов. Я настроил стек Compose, предусмотрев в нём такой скрипт развёртывания, который удаляет инстанс из балансировщика нагрузки, подтягивает новые контейнеры, удостоверяется, что они запустились, после чего заново добавляет их в балансировщик нагрузки — действительно, многие так и делают.
K8s обеспечил горизонтальное масштабирование такого подхода. То есть, теперь можно взять контейнер с вашего ноутбука и развернуть идентичные ему контейнеры на тысячах серверов. Благодаря такой гибкости во многих организациях удалось полностью пересмотреть стратегию проектирования, отказаться от монолитов и взять на вооружение более гибкие (и при этом зачастую более сложные) микросервисные архитектуры.
Малозатратная поддержка
Если история эксплуатации компьютеров (Ops) представляется вам как своего рода «хронология переосмысления от котиков до скота», то я хотел бы заглянуть в ещё более далёкое прошлое, которое любя называю «симпсоновской». Тогда серверы были железными ящиками, работали на голом металле. Настраивала такую машину целая команда, имя у сервера было одноразовым и могло перекочевать во внутрикомандный сленг. Всё было хрупким как снежинка. Чем дольше сервер работал, тем больше в нём накапливалось программного мусора, пока не становилось страшно не то что эксплуатировать его, но даже просто перезагрузить, а тем более — пересобрать. Я называю эту эпоху «симпсоновской», так как в нашей повседневной практике в те времена мы очень любили называть задачи именами героев этого сериала. Всё делалось вручную, и ничего само собой не исправлялось.
Потом наступила «Эра 01». Повсеместно распространились такие инструменты как Puppet и Ansible, серверами уже можно было немного разбрасываться, стали просматриваться такие штуки как узлы-бастионы, а также другие системы контроля доступа, постепенно становившиеся нормой. Серверы отнюдь не были обращены в Интернет — нет, они стояли за балансировщиком нагрузки, а милые прозвища сменились функциональными именами вроде «app01» или «vpn02». Организации проектировали сети так, что время от времени некоторые серверы могли просто отказывать. Тем не менее, самовосстановление после таких сбоев по-прежнему не происходило, иногда не оставалось иного выхода, кроме как войти по SSH на сломавшуюся машину, пропатчить тот или иной инструмент, а потом развернуть новую версию сразу на весь парк серверов. Обновление операционной системы также было делом не из лёгких.
Теперь же мы живём в «эре UUID». Серверы нужны для того, чтобы гонять на них контейнеры, с любым сервером расстаются без сожаления. Никого не интересует, как долго будет поддерживаться конкретная версия операционной системы — можно просто выпечь новый AMI, который заменит целую машину. Kubernetes – не единственная технология, дающая такие возможности, но именно Kubernetes ускорил этот переход. В наше время можно представить себе сервер-бастион с SSH-ключами. В такой конфигурации я могу зайти на несущий сервер и решить возникшие проблемы, но такое решение всё больше воспринимается как экстренное. Почти все нормальные решения строятся по принципу: «тот узел уничтожаем, поручаем k8s всё реорганизовать с учётом этого, создаём новый узел».
Многочисленные навыки работы с Linux, которые были принципиально важны на разных этапах моей карьеры, теперь в лучшем случае являются плюсом, но совсем не необходимы. Кому-то это нравится, кому-то нет, что уж говорить обо мне с моими эмоциональными качелями, но просто это так.
Выполнение заданий
Система заданий в k8s устроена неидеально, но она гораздо лучше, чем те «хрупкие cron01», которые де-факто были хрупкими как снежинки. Как бы ни выполнялось задание — по расписанию cron или поступая из очереди сообщений, теперь появился надёжный механизм, позволяющий ставить задания в очередь, обеспечивать из запуск, перезапускать их, если они почему-то не работали и жить дальше.
Так люди не только освободились от времязатратной и скучной задачи, но и попросту стали более эффективно использовать ресурсы. Вы всё равно вынуждены поднимать под для каждого элемента в очереди, но внутри этого «пода» у вашей команды развязаны руки, и люди сами решают, что именно необходимо запустить, и как именно они хотят это запустить. Это действительно упростило жизнь очень для многих, в том числе для меня — так как у нас появилась возможность легко создавать задачи в фоновом режиме и больше не вспоминать о них.
Возможность обнаружения сервисов и балансировка нагрузки
Жёстко вшитые IP-адреса внутри приложений настолько живучи, поскольку любые попытки подобрать шаблон, описывающий правильную маршрутизацию запросов, превращаются в неотступное проклятье. Если вам везло, то соответствующие зависимости оказывались не связаны с IP-адресами, а представляли собой полноценные DNS-записи. Не составляет труда изменить содержимое такой записи, не координируя при этом развёртывание миллионов экземпляров одного приложения.
K8s позволяет вызывать другие сервисы через простые DNS-имена. Так в нём был устранён целый класс ошибок, стало меньше возни, вся работа существенно упростилась. Располагая names Service API, вы имеете стабильный и долгоживущий IP-адрес и хост-имя, на которые можно просто указывать, не задумываясь, как именно эти операции концептуально устроены внутри. Есть даже такие вещи как ExternalName
, позволяющие обращаться с внешними сервисами так, как будто они находятся в пределах кластера.
Что бы я изменил в Kubernetes 2.0
Отказываемся от YAML в пользу HCL
Язык разметки YAML привлекателен, так как это ни JSON, ни XML. Формулировка из разряда «у меня отличная новая машина, потому что она ни лошадь, ни моноколесо». Демо-примеры на YAML хорошо смотрятся в k8s, аккуратнее укладываются в репозитории, и поэтому создаётся иллюзия, будто этот формат файлов прост. На самом же деле, YAML банально перегружен, если применять его в тех задачах, которые обычно решаются при помощи k8s, а к тому же недостаточно безопасен. Из-за отступов возникают ошибки, файлы не очень хорошо масштабируются (в самом деле, никому не хочется иметь слишком длинный YAML-файл). Отладка может раздражать. В самом деле, YAML изобилует неочевидными вариантами поведения — все они описаны в спецификации языка.
Припоминаю, как глазам своим поверить не мог, когда впервые столкнулся с «норвежской проблемой». Тем, счастливчикам, которым она пока не знакома, поясню: «норвежская проблема» (Norway Problem) возникает в YAML-файлах в тех случаях, когда «NO» интерпретируется как «ложь». Вообразите, каково объяснять вашим норвежским коллегам, что вся их страна в ваших конфигурационных файлах результирует в «false». Присовокупите сюда случайные числа, возникающие из-за непроставленных кавычек, да и многое другое. Впрочем, есть множество отличных постов, в которых разобраны глюки YAML — гораздо лучших, чем могли бы получиться у меня.
Почему HCL?
Язык HCL уже принят в качестве стандартного формата в Terraform, так что там хотя бы можно сетовать всего на один конфигурационный язык, а не на два. Он строго типизирован, и типы в нём явные. В нём уже хорошо поставлена валидация. Он специально спроектирован для решения именно тех задач, которые мы пытаемся решать на YAML, и не сильно уступает YAML в удобочитаемости. В нём есть встроенные функции, которыми мы уже привыкли пользоваться, поэтому при работе с HCL можно обойтись без некоторых сторонних инструментов, которые необходимы при решении задач на YAML.
Готов предположить, что в наше время уже 30% кластеров Kubernetes управляются на языке HCL с применением Terraform. Не нужно быть специалистом по Terraform, чтобы так или иначе пользоваться этим превосходным конфигурационным языком.
Основные недостатки HCL заключаются в том, что он немного пространнее YAML, и в том, что он используется по лицензии Mozilla Public License 2.0 (MPL-2.0), в соответствии с которой требуется грамотная юридическая консультация, если вы хотите интегрировать Kubernetes в проект на Apache 2.0. Тем не менее, учитывая, насколько HCL облегчает жизнь, с этими препятствиями как-то можно справиться.
Почему HCL лучше YAML
Рассмотрим простой файл на YAML.
# YAML не обязывает соблюдать типы
replicas: "3" # строка вместо целого числа
resources:
limits:
memory: 512 # отсутствует обозначение величины
requests:
cpu: 0.5m # Опечатка в характеристике ЦП (должно быть 500m)
Даже в таком элементарном примере — повсюду капканы. Язык HCL со своей системой типов отловил бы все эти проблемы.
replicas = 3 # Перед нами явно целое число
resources {
limits {
memory = "512Mi" # Строка для обозначения величин в памяти
}
requests {
cpu = 0.5 # Число для значений ЦП
}
}
Возьмём YAML-файл примерно следующего содержания — пожалуй, у вас в репозитории с k8s таких найдутся тысячи. А потом сравните его с кодом на 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
}
Вот в чём вы выиграете, перейдя с YAML на HCL.
Безопасность типов: ещё до развёртывания предотвращаются возможные ошибки, связанные с типизацией
Переменные и ссылки: код меньше дублируется, поддерживать его становится удобнее
Функции и выражения: теперь можно динамически генерировать конфигурацию
Условная логика: поддерживаются варианты конфигурации, специфичные для конкретного окружения
Циклы и перебор: упрощается работа с конфигурациями, в которых много повторов
Улучшенные комментарии: код становится удобнее документировать и читать
Обработка ошибок: ошибки легче выявляются и исправляются
Модульность: становится проще переиспользовать компоненты конфигурации
Валидация: не допускаются недействительные варианты конфигурации
Преобразование данных: поддерживаются сложные манипуляции с данными
Можно подобрать замену etcd
Знаю, что я 10 000-й, кто пишет об этом, но, всё же. Etcd славно поработал, но есть небольшая безуминка в том, что он — единственный инструмент для своих задач. Если он применяется в сравнительно небольших кластерах или аппаратных конфигурациях, то слишком расточительно расходует ресурсы. При этом, в кластере такого типа у нас никогда не наберётся столько узлов, чтобы это стало окупаться. В настоящее время между k8s и etcd сложились странные отношения, в особенности потому, что k8s, в принципе, остался единственным «потребителем» etcd.
Я намекаю на то, что пора воспользоваться наработками kine и придать им официальный статус. Это целесообразно для того, чтобы обеспечить работоспособность проекта в долгосрочной перспективе, обеспечить возможность подключения к нему более разнообразных бэкендов. Таким образом, добавляя такую абстракцию мы (должно быть) в будущем сможем легче подключать к системе другие серверные интерфейсы и более прицельно настраивать их в зависимости от того, на каком именно железе они будут работать.
Подозреваю, этот путь приведёт нас к чему-то подобному: https://github.com/canonical/k8s-dqlite. Распределённая база данных SQlite, работающая в оперативной памяти, использующая протокол консенсуса Raft и почти не требующая работы по обнеовлению. Такая конфигурация позволила бы операторам облаков более гибко взаимодействовать с уровнем долговременного (персистентного) хранения данных в установленных у них экземплярах k8s. Если вы работаете с обычной серверной конфигурацией, расположенной в ЦОД, и ресурсная прожорливость etcd для вас не проблема — отлично! Но описанный подход значительно упростит работу с более бюджетными инстансами k8s и (надеюсь) ослабит всеобщую зависимость от проекта etcd.
Не только Helm: нативный менеджер пакетов
Helm — отличный пример импровизированного костыля, превратившегося в постоянную зависимость. Я благодарен команде поддержки Helm за весь проделанный ими тяжёлый труд. Их инструмент вырос из проекта для хакатона до де-факто стандартного установщика программ в кластеры k8s. Helm хорошо справился с поставленными перед ним задачами, и при этом не потребовалось слишком глубоко интегрировать его с k8s.
Не умаляя сказанного, пользоваться 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. Это логично, ведь у меня приложение, в котором есть собственные зависимости от другого материала, и я хочу собрать их все в одном месте. Таким образом, мне приходится определять субдиаграммы или зонтичные диаграммы прямо у меня в файле 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>"
Но в случае, если я работаю со множеством приложений, совершенно не исключено, что у меня найдётся 2 таких сервиса, которые будут одновременно зависеть и от nginx, и от чего-то подобного:

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

Беру elasticsearch, так как он кажется важным.


У нас большие беды с официальной helm-диаграммой Elastiс. Определённо, здесь был бы нужен ingress-nginx, и эта зависимость абсолютно критична для целой отрасли.

Ничего подобного. Кроме того, посмотрите, кто поддерживает диаграмму "Kubernetes" – и этот источник тоже до сих пор не помечен как verified publisher
.
Не поддерживается поиск по многим метаданным диаграмм. Можно искать только по имени или описанию, но не по фичам, возможностям или другим метаданным

В Helm не требуется строго соблюдать семантическое версионирование
# Chart.yaml с несемантическим версионированием
apiVersion: v2
name: myapp
version: "v1.2-alpha"
Если деинсталлировать и вновь установить диаграмму с пользовательскими определениями ресурсов (CRD), то могут оказаться удалены ресурсы, созданные этими CRD. Это неоднократно меня бесило и к тому же безумно небезопасно.
Я мог бы написать ещё целую простыню текста, и всё равно не смог бы описать всех проблем Helm. Просто не существует способа допилить Helm настолько, чтобы он мог считаться «хорошим менеджером пакетов для управления всей критической инфраструктурой планеты».
Как должна выглядеть нормальная система для работы с пакетами k8s?
Давайте назовём эту гипотетическую систему работы с пакетами KubePkg, поскольку если и есть всего одна штука, остро необходимая в экосистеме Kubernetes, то пусть она будет называться ещё одной аббревиатурой на «K». Постараемся скопировать как можно больше ценной работы, уже проделанной в экосистеме Linux, при этом усилив её таким козырем k8s как CRD. Мне эта система представляется примерно так:
Система KubePkg | |||
CRD пакетов |
CRD репозиториев |
Установочные CRD |
CRD состояния |
Контроллеры | |||
Контроллер пакета |
Контроллер репозитория |
Контроллер установки |
Контроллер состояния |
Вспомогательные сервисы | |||
Верификация сигнатур |
Разрешение зависимостей |
Сканер обеспечения безопасности |
Менеджер резервных копий |
Эти пакеты организуются подобно связкам в пакете 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:
# Определение с сохранением состояния
# Конфигурационная схема на основе JSON
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:
# Определение задания
preUpgrade:
- name: backup
job:
spec:
# Определение задания для резервного копирования
postUpgrade:
- name: verify
job:
spec:
# Определение задания верификации
preRemove:
- name: final-backup
job:
spec:
# Определение окончательного задания для резервного копирования
# Определение состояния в тех приложениях, которые его сохраняют
stateManagement:
backupStrategy:
type: "snapshot" # или "dump"
schedule: "0 2 * * *" # Ежедневно в 2.00
retention:
count: 7
recoveryStrategy:
type: "pointInTime"
verificationJob:
spec:
# Задание, проверяющее, успешно ли прошло восстановление
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" # or "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" # Weekly on Sunday at 2am
approvalRequired: true
# Ссылка на управление состоянием
stateRef:
name: postgresql-main-state
# Служебный аккаунт, которым будем пользоваться
serviceAccountName: postgresql-installer
k8s требуется система, которая бы удовлетворяла следующим требованиям:
Подлинная нативность Kubernetes: всё является ресурсом Kubernetes, обладающим соответствующим статусом и связанным с соответствующими событиями
Управление состоянием как сущность первого класса: встроенная поддержка приложений, сохраняющих состояние
Повышенная безопасность: надёжное подписывание, верификация и сканирование на предмет безопасности
Декларативная конфигурация: никаких шаблонов, просто структурированная конфигурация со схемами
Управление жизненным циклом: полноценные привязки жизненного цикла и стратегии обновления
Разрешение зависимостей: Linux-подобная система управления зависимостями, в которой предусмотрено семантическое версионирование
Отслеживание аудита: полная история изменений, в которой учитывается, кто, что и когда сделал, а не так, как сейчас в Helm.
Обязательное соблюдение политик: поддержка организационных политик и обеспечение соответствия стандартам.
Более простая и удобная в работе система: Знакомые Linux-подобные команды для управления пакетами. Это дико, что мы пытаемся дрейфовать куда-то в сторону от той системы пакетов, которая работает уже не один десяток лет
IPv6 по умолчанию
Вы только подумайте, сколько времени и энергии в глобальном масштабе тратится на попытки решить зотя бы одну из трёх следующих проблем:
Чтобы пообщаться с этим подом в кластере, мне нужен другой под в том же кластере.
Есть проблема, происходящая где-то в процессе обхода NAT, и мне необходимо её решить
Я израсходовал IP-адреса в моём кластере, поскольку не учёл ваших аппетитов. Помните: компания, исходно имевшая подсеть /20 (4 096 адресов), развёртывает 40 узлов с 30 подами в каждом, внезапно осознаёт, что уже почти исчерпала свой лимит IP адресов. А 40 узлов — это не так много!
Я не призываю срочно переключить весь Интернет на IPv6, а прямо сейчас k8s вполне поддерживает режим «только IPv6», если вы хотите попробовать подход с двойным стеком. Но я утверждаю, что время пересмотреть имеющиеся умолчания и просто переходить на IPv6. В таком случае одним махом устраняется огромная совокупность проблем. Появляется
Более плоская и не столь усложнённая топология сети внутри кластера,.
Организация может осознанно игнорировать различия между многими кластерами, если в них требуется обзавестись публичными IP.
Прощен понимать, как именно складываются потоки трафика внутри вашего стека.
Встроенный механизм IPSec
Совсем не то де самое, что силой продвигать переход на IPv6 в глобальном масштабе; просто признание того факта, что мы оставили в прошлом мир, где требовалось мириться со странными ограничениями IPv4. Мы живём в мире, где вам может внезапно понадобиться 10 000 IP-адресов, хотя, почти ничего этого не предвещало.
Вполне очевидно, в чём выигрывают организации с публичными IP, но польза от этого будет и облачным провайдерам, и даже крупнейшим корпоративным игрокам. Так, AWS, возможно, больше никогда не понадобиться насилу втискивать всё новые и новые приватные адреса IPv4 в виртуальный частный кластер. Это чего-то да стоит.
Заключение
Парировать подобные идеи обычно пытаются в духе: «Kubernetes —открытая платформа, и сообщество в силах само разработать такие решения». Справедливо, но в такой аргументации упускается принципиальный момент: нет в технологии более мощной силы, чем привычные умолчания. «Лёгкий путь», выбранный с точки зрения ключевого проекта, определяет, как именно будут взаимодействовать с продуктом 90% его пользователей. Если в системе по умочланию ожидаются пакеты с цифровой подписью и предоставляется надёжный нативный способ ими управлять, именно это и приживётся в экосистеме.
Знаю, планы получились наполеоновскими. Но, если мечтать — давайте мечтать масштабно. В конце концов, мы с вами из индустрии, где кому-то показалось, что технология под названием «Kubernetes» приживётся, и ведь как-то это удалось!
В других областях, например, мобильной разработке или веб-разработке, то и дело случается так, что на платформе удаётся трезво оценить сложившуюся ситуацию и совершить качественный скачок вперёд. Не все такие проекты сразу пользовались благосклонностью компаний или сообществ, которые их поддерживали, но я думаю, что всегда есть идеи, к которым стоит хотя бы кому-то вернуться и задаться вопросом: «а может быть, мы зря действуем как раньше, затрачивая на это такую огромную долю мощностей ЦОД во всём мире»?
Комментарии (2)
cupraer
28.06.2025 09:48Удивительно, конечно, как Гугл до сих пор выезжает на репутации, которая поломалась с концами почти 20 лет назад. С тех пор ничего хорошего (и/или технически интересного) Гугл не сделал, но вот они выпускают убогий, непродуманный, откровенно нишевой язык «для середняков» (по меткому выражению Пайка) — и на нём начинают писать всё, от операционных систем до распределенных вычислений.
Выпускают кривой, сырой и убогий суррогат деревьев супервизоров эрланга — и вот уже пивной ларек «Рога и Копыта» ведет свою бухгалтерию в кубере.
Удивительно, но факт.
olku
https://habr.com/ru/companies/flant/articles/922242/ лучше получился