Блог используется только для разъяснения ландшафта декларативной конфигурации, основной концепции и функций KCL, а также для сравнения с другими языками конфигурации.

1. Ландшафт декларативной конфигурации

1.1 Важность конфигурации

  • Каждый день выпускаются тысячи обновлений конфигурации, потому что разработка программного обеспечения и сама конфигурация постепенно развиваются, что требует высокой эффективности в больших масштабах.
  • 1. Конфигурация обновляется чаще: меняющиеся бизнес-требования, требования к инфраструктуре и другие факторы означают, что система должна постоянно меняться, а конфигурация обеспечивает недорогой способ изменения функций системы.
  • 2. Масштаб конфигурации становится больше: конфигурация часто распределяется по разным облачным площадкам, разным арендаторам, разным средам и т. д.
  • 3. Широкие сценарии конфигурации: приложение, база данных, сеть, мониторинг и т. д.
  • 4. Различные форматы конфигурации: JSON, YAML, XML, TOML, различные шаблоны конфигурации, такие как Java Velocity, Go Template и т. д.
  • Стабильность конфигурации имеет решающее значение. Одна из основных причин системных ошибок заключается в том, что большое количество инженеров часто обновляют конфигурацию. В таблице 1 показано несколько событий системных ошибок, вызванных конфигурацией.

Таблица 1 События системных ошибок, вызванные конфигурацией.

1.2 Классификация декларативной конфигурации

Облачная эра привела к быстрому технологическому развитию с большим количеством декларативных конфигураций. Как показано на рис. 1, декларативную конфигурацию можно в целом разделить на следующие способы.

Рис. 1: Классификация декларативной конфигурации.

1.2.1 Структурированный K-V

Структурированный K-V соответствует минимальным требованиям к объявлению данных (int, string, list, dict и т. д.). Декларативный API отвечает требованиям разработки X as Data благодаря быстрой разработке и применению облачных технологий. Машиночитаемый и записываемый, человекочитаемый.

Плюсы

  • Простой синтаксис, легко писать и читать.
  • Богатые многоязычные API.
  • Различные инструменты пути для запроса данных, такие как XPath, JsonPath и т. д.

Минусы

  • Слишком много избыточной информации: при большом масштабе конфигурации сложно поддерживать конфигурацию, поскольку важная информация о конфигурации скрыта в большом количестве нерелевантных повторяющихся деталей данных.
  • Отсутствие функциональности: ограничение, сложная логика, тест, отладка, абстракция и т. д.
  • Патчи Kustomize в основном исправляют несколько стратегий слияния патчей.

Репрезентативные технологии структурированного KV включают:

  • JSON/YAML: очень удобен для чтения и автоматизации, имеет поддержку различных языков API.
  • Kustomize: предоставляет решение для настройки конфигурации базы ресурсов Kubernetes и дифференциальной конфигурации без шаблона и DSL. Он не решает саму проблему ограничений, но должен взаимодействовать с большим количеством дополнительных инструментов для проверки ограничений, таких как Кубе-линтер, Чеков. На рис. 2 показан типичный рабочий режим Kustomize.

Рис. 2: Типичный рабочий режим Kustomize.

1.2.3 Шаблон K-V

Шаблонный KV имеет возможность статических данных конфигурации и динамических параметров и может выводить различные статические данные конфигурации с одним шаблоном + динамическими параметрами. Преимущества и недостатки заключаются в следующем:

Плюсы

  • Простая логика конфигурации и поддержка циклов.
  • Поддержка внешних динамических параметров.

Минусы

  • Легко попасть в ловушку, что все конфигурации являются параметрами шаблона.
  • Когда масштаб конфигурации становится больше, разработчикам и инструментам становится сложно их поддерживать и анализировать.

Репрезентативные технологии шаблонного KV включают:

  • Helm: инструмент управления пакетами ресурсов Kubernetes, который управляет конфигурацией ресурсов Kubernetes через шаблон конфигурации. На рис. 3 показан шаблон конфигурации Helm Jekins Package ConfigMap. Видно, что эти шаблоны очень короткие с простой логикой. Ряд конфигураций ресурсов, подходящих для базовых компонентов Kubernetes, устанавливаются с помощью управления пакетами и дополнительных параметров конфигурации. По сравнению с простым шаблоном K-V, Helm обеспечивает хранение шаблонов, справочные и семантические возможности управления версиями. По сравнению с Kustomize, Helm больше подходит для управления внешними диаграммами, но не подходит для управления несколькими средами и конфигурациями с несколькими арендаторами.
  • Другие шаблоны конфигурации: Java Velocity, Go Template и другие механизмы текстовых шаблонов очень подходят для написания шаблонов HTML. Однако при использовании в сценариях конфигурации разработчикам и инструментам сложно поддерживать и анализировать их.

Рис. 3: Шаблон конфигурации Helm Jekins Package ConfigMap.

1.2.3 Программируемый K-V

Configuration as Code (CaC) использует код для создания конфигурации, точно так же, как инженерам нужно только написать расширенный код GPL, а не вручную писать подверженный ошибкам и трудный для понимания двоичный код сервера.

  • Изменения конфигурации рассматриваются так же серьезно, как и изменения кода, и также могут выполняться модульные и интеграционные тесты.
  • Модульность кода является ключевой причиной, по которой поддерживать код конфигурации проще, чем вручную редактировать файлы конфигурации, такие как JSON/YAML.

Возможности

  • Необходимые возможности языка программирования (определения переменных, логические суждения, циклы, утверждения и т. д.).
  • Необходимая возможность шаблона, которая поддерживает определение шаблонов данных и использование шаблонов для получения новых данных конфигурации.
  • Модульность кода: определение структуры и управление пакетами.
  • Машиночитаемый и записываемый, человекочитаемый и записываемый.

Плюсы

  • Необходимые навыки программирования.
  • Модульность кода и абстракция.
  • Шаблон конфигурации и возможность переопределения.

Минусы

  • Недостаточная проверка типа.
  • Недостаточная ограничивающая способность.
  • Много ошибок во время выполнения.

Репрезентативные технологии программируемого KV включают:

  • GCL: декларативный язык конфигурационного программирования, реализованный на Python, предоставляет необходимые языковые возможности для поддержки абстракции шаблонов. Однако сам компилятор написан на Python, а сам язык интерпретируется и выполняется. Для больших экземпляров шаблонов (таких как модели Kubernetes) производительность низкая.
  • HCL: Язык структурированной конфигурации реализации Go. Родной синтаксис HCL вдохновлен конфигурациями libucl и Nginx. Он используется для создания структурированного языка конфигурации, удобного для людей и машин, в основном для инструментов DevOps, конфигураций серверов и конфигураций ресурсов в качестве языка Terraform.
  • Jsonnet: язык шаблонов данных, реализованный на C++, подходит для разработчиков приложений и инструментов, может генерировать данные конфигурации и организовывать, упрощать и управлять большими конфигурациями без побочных эффектов.

1.2.4 Тип К-В

Возможности

  • Основанный на программируемом K-V, типизированный K-V имеет больше возможностей ограничения типа.

Плюсы

  • Слияние конфигураций полностью идемпотентно, что естественным образом предотвращает конфликты конфигураций.
  • Богатый синтаксис ограничений для записи конфигурации.
  • Абстрагируйте ограничения типа и значения в одну и ту же форму, которую легко написать.
  • Порядок конфигурации не зависит.

Минусы

  • Концепции слияния графов и слияния идемпотентов сложны, а затраты на понимание высоки.
  • Смешанное определение типа и значения повышает степень абстракции и стоимость понимания. Все ограничения проверяются во время выполнения, и для крупномасштабного кода конфигурации существует узкое место в производительности.
  • Трудно реализовать сценарии с несколькими арендаторами и несколькими средами, которые требуют настройки покрытия и модификации.
  • Для ограниченных сценариев с условиями пользовательский интерфейс для написания гибридных определений определения и проверки неудобен.

Репрезентативные технологии типизированного КВ включают:

  • CUE: основной проблемой, которую решает CUE, является проверка типов, которая в основном используется в сценариях проверки ограничений конфигурации и простых сценариях облачной конфигурации.

1.2.5 Модель К-В

Возможности

  • Возможность языкового моделирования высокого уровня в качестве основного описания

Плюсы

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

Минусы

  • Расширение новых моделей и экологического строительства требует определенных затрат на НИОКР.

Репрезентативные технологии смоделированного KV включают:

  • KCL: декларативный язык программирования конфигураций и политик, реализованный на Rust, который улучшает написание большого количества сложных конфигураций с помощью зрелой технологии и практики языка программирования и стремится к созданию лучшей модульности, масштабируемости и стабильности конфигурации, более простой логики. написание, быстрая автоматизация и хорошее экологическое расширение. На рис. 4 показан типичный сценарий написания KCL кода конфигурации доставки приложений.

Рис. 4: Типичный сценарий написания KCL кода конфигурации доставки приложений.

1.3 Рекомендации и лучшие практики для различных декларативных конфигураций

  • Масштаб конфигурации: для мелкомасштабных сценариев конфигурации мы можем использовать YAML/JSON и другие конфигурации, такие как простая конфигурация самого приложения и конфигурация CI/CD. Кроме того, для требований нескольких сред и нескольких арендаторов в сценариях с небольшими конфигурациями возможности наложения Kustomize можно использовать для реализации таких операций, как слияние и покрытие простых конфигураций.
  • Необходимость абстрагирования модели и ограничения: для крупномасштабных сценариев конфигурации, особенно для тех, которые остро нуждаются в модели конфигурации и функциях O&M, R&D и ускорении многопользовательской и мультисреды, метод кодирования, типизации и моделирования K-V может быть использовал.

Кроме того, рассмотрим сценарии использования разных декларативных конфигураций:

  • YAML рекомендуется, если вам нужно написать структурированный статический K-V или использовать собственные инструменты Kubernetes.
  • HCL рекомендуется, если вы хотите использовать удобство языка программирования для удаления шаблонов с хорошей удобочитаемостью для человека или если вы уже являетесь пользователем Terraform.
  • CUE рекомендуется, если вы хотите использовать систему типов для повышения стабильности и поддержки масштабируемых конфигураций.
  • KCL рекомендуется, если вам нужны типы и модели, такие как современный язык, масштабируемые конфигурации, внутренние чистые функции и правила, а также производительность и автоматизация, готовые к производству.

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

Обратите внимание, что в этом блоге не будет обсуждаться общий язык, используемый для написания конфигурации. Общий язык обычно избыточен, то есть выходит далеко за рамки проблем, которые необходимо решить. В общем языке существуют различные проблемы безопасности, такие как проблема границ возможностей (запуск локальных потоков, доступ к вводу-выводу, сети, бесконечное зацикливание кода и другие риски безопасности). Например, в музыкальной сфере есть специальные ноты для выражения музыки, которая удобна для обучения и общения. Она не может быть четко выражена на общем языке.

Кроме того, из-за различных стилей общего языка, который имеет стоимость унифицированного обслуживания, управления и автоматизации. Общий язык обычно используется для написания среды выполнения клиента, которая является продолжением среды выполнения сервера. Он не подходит для написания конфигураций, не зависящих от среды выполнения, и компилируется в бинарник и запускается из процесса окончательно. Кроме того, стабильность и масштабируемость нелегко контролировать. Однако язык конфигурации часто используется для записи данных, которые сочетаются с простой логикой и описывают ожидаемый конечный результат, который затем используется компилятором или механизмом.

2. Основные функции и варианты использования KCL

Основными функциями KCL являются его возможности моделирования и ограничений, а основные функции KCL вращаются вокруг двух основных функций. Кроме того, KCL следует концепции конфигурации, ориентированной на пользователя, для разработки своих основных функций, которые можно понять с двух точек зрения:

  • Представление конфигурации, ориентированное на модель предметной области: благодаря богатым функциям языка KCL и инструментам KCL OpenAPI мы можем напрямую интегрировать широкий спектр хорошо разработанных моделей в сообществе в KCL (например, модель ресурсов K8s). Мы также можем разрабатывать и внедрять собственные модели или библиотеки KCL в соответствии с различными сценариями, формируя полный набор моделей предметной области для использования другими конечными пользователями конфигурации.
  • Представление конфигурации, ориентированное на конечного пользователя: благодаря возможностям инкапсуляции, абстракции и повторного использования кода KCL архитектура модели может быть дополнительно абстрагирована и упрощена (например, модель ресурсов K8s абстрагируется в модель сервера, ориентированную на приложения), чтобы свести к минимуму конфигурацию конечного пользователя. input**, упростить пользовательский интерфейс конфигурации и облегчить ручную или автоматическую модификацию API.

Независимо от того, на каком представлении конфигурации сосредоточено, для кода конфигурации существуют требования к ограничениям данных конфигурации, таким как ограничения типов, обязательные/необязательные ограничения атрибутов конфигурации, ограничения диапазона и ограничения неизменности. Это также одна из основных проблем, которую KCL стремится решить. KCL в основном содержит основные функции, показанные на рис. 5.

Рис. 5: Основные характеристики KCL.

  • Простота в использовании: создана на основе языков высокого уровня, таких как Python и Golang, включает в себя функции функционального языка с минимальными побочными эффектами.
  • Хорошо спроектированный: независимый синтаксис, семантика, время выполнения и дизайн системных модулей, основанные на спецификации.
  • Быстрое моделирование: ориентированные на схему типы конфигурации и модульная абстракция.
  • Богатые возможности: Конфигурация с типом, логикой и политикой на основе Конфиг, Схема, Лямбда, Правило.
  • Стабильность: стабильность конфигурации, построенная на статической системе типов, ограничениях и правилах.
  • Масштабируемость: высокая масштабируемость благодаря механизму автоматического слияния изолированных блоков конфигурации.
  • Быстрая автоматизация: Градиентная схема автоматизации CRUD API, многоязычные SDK, языковой плагин
  • Высокая производительность: высокое время компиляции и производительность во время выполнения с использованием Rust & C и LLVM, а также поддержка компиляции в собственный код и WASM.
  • Соответствие API: встроенная поддержка экологических спецификаций API, таких как OpenAPI, Kubernetes CRD, спецификация Kubernetes YAML.
  • Удобство разработки: Удобный опыт разработки с богатыми языковыми инструментами (Format, Lint, Test, Vet, Doc и т. д.) и плагинами IDE.
  • Безопасность и удобство обслуживания. Ориентированность на предметную область, отсутствие системных функций, таких как встроенные потоки и ввод-вывод, низкий уровень шума и угроз безопасности, простота обслуживания и управления.
  • Готов к производству: широко используется в производственной практике разработки платформ и автоматизации в Ant Group.

Рис. 6: Конструкция сердечника KCL.

Дополнительные сведения о языковом дизайне и возможностях см. в разделе Документы KCL. Хотя KCL не является языком общего назначения, у него есть соответствующие сценарии применения. Как показано на рис. 6, разработчики могут писать конфигурацию, схему, функцию и правило через KCL, где конфигурация используется для определения данных, схема используется для описания определения модели данных, правило используется для проверки данных, а схема и правило также можно комбинировать для использования моделей и ограничений, которые полностью описывают данные. Кроме того, мы также можем использовать чистую лямбда-функцию в KCL для организации кода данных, инкапсуляции общего кода и прямого вызова его при необходимости.

Для вариантов использования KCL может выполнять структурированную проверку данных K-V, определение и абстракцию сложной модели конфигурации, проверку жестких ограничений, чтобы избежать ошибок конфигурации, интеграцию автоматизации и инженерное расширение. Эти функции и варианты использования описаны ниже.

2.1 Проверка структурированных данных

Как показано на рис. 7, KCL поддерживает проверку формата данных JSON/YAML. Как язык конфигурации, KCL охватывает почти все функции OpenAPI с точки зрения проверки. В KCL данные конфигурации могут быть ограничены определением структуры. В то же время он поддерживает определяемые пользователем правила ограничения с помощью контрольных блоков и записи выражений проверки в схеме для проверки и ограничения атрибутов, определенных в схеме. Выражение проверки можно использовать для четкой и простой проверки того, соответствует ли входной JSON/YAML соответствующему определению структуры схемы и ограничениям проверки.

Рис. 7: Проверка структурированных данных в KCL.

Исходя из этого, KCL предоставляет соответствующий Инструмент проверки для непосредственной проверки данных JSON/YAML. Кроме того, на основе этой возможности мы можем создать продукт визуализации проверки K-V, как показано на рис. 8.

Рис. 8: Продукт визуализации проверки K-V на основе KCL.

2.2 Определение и абстракция модели сложной конфигурации

Как показано на рис. 9, с помощью инструмента KCL OpenAPI мы можем напрямую интегрировать широкий спектр хорошо спроектированных моделей.

Рис. 9: Общий способ моделирования сложной конфигурации KCL.

Как показано на рисунке 10, Konfig используется для управления всеми кодами конфигурации KCL, код бизнес-конфигурации и код базовой конфигурации хранятся в монорепозитории, что облегчает управление зависимостями версий между кодами, а автоматическая обработка системы относительно проста. . Достаточно найти директорию и файлы уникальной кодовой базы. Коды взаимосвязаны, управляются единообразно, их легко найти, изменить и поддерживать. Кроме того, единый процесс CI/CD можно использовать для управления конфигурацией.

Рис. 10. Использование языковых возможностей KCL для интеграции моделей предметной области и пользовательских моделей.

2.3 Сильное ограничение для избежания ошибок

Как показано на рис. 11, ошибок конфигурации можно избежать с помощью надежных методов проверки ограничений в KCL.

Рис. 11: Методы проверки сильных ограничений в KCL.

  • Система типов языка KCL спроектирована так, чтобы быть статической. Определения типа и значения разделены. Поддерживается вывод типов и проверка типов во время компиляции. Статические типы могут не только заранее анализировать большинство ошибок типов во время компиляции, но и уменьшать потери производительности при проверке динамических типов во время выполнения. Кроме того, атрибуты схемы KCL принудительно должны быть не нулевыми, что позволяет эффективно избежать пропусков конфигурации.
  • При объявлении экспортируемых конфигураций KCL их типы и значения не могут изменяться. Эта статическая функция гарантирует, что конфигурация не будет изменена по желанию.
  • KCL поддерживает дальнейшее обеспечение стабильности за счет встроенных в структуру правил проверки. Например, на рис. 12 показано, что код KCL определяет ограничения для containerPort, services и volumes в App.

Рис. 12: Проверка кода KCL с правилами ограничения.

2.4 Объединение блоков изолированной конфигурации

KCL предоставляет возможность писать изолированные блоки конфигурации и автоматически объединять их, а также поддерживает идемпотентное слияние, слияние исправлений и другие стратегии. Несколько конфигураций при идемпотентном слиянии должны соответствовать закону обмена, а разработчикам необходимо вручную обрабатывать конфликты конфигураций между базовой и различными средами. Слияние патчей включает в себя наложение, удаление и добавление. KCL упрощает совместную разработку на стороне пользователя и уменьшает связь между конфигурациями за счет нескольких стратегий слияния.

Рис. 13: Написание блока конфигурации сценария с несколькими средами.

2.5 Автоматизация

KCL предоставляет множество возможностей, связанных с автоматизацией, в основном включая инструменты и многоязычные API. В режиме package_identifier : key_identifier KCL поддерживает индексирование любого настроенного значения ключа, таким образом завершая добавление, удаление, изменение и запрос любого значения ключа. Например, на рис. 14 показано, что мы можем напрямую выполнить следующую команду для изменения изображения. Разница в коде до и после модификации также показана на рис. 14.

Рис. 14: Автоматическое изменение образа конфигурации приложения через KCL CLI/API.

Кроме того, возможности автоматизации KCL могут быть реализованы и интегрированы в CI/CD, как показано на рис. 15.

Рис. 15: Типичная интеграция автоматизации KCL.

3. Сравнение KCL и других декларативных конфигураций

3.1 по сравнению с JSON/YAML

Конфигурации YAML/JSON подходят для небольших сценариев конфигурации. Для крупномасштабных сценариев конфигурации собственного облака, требующих частых изменений, они больше подходят для KCL. Основное различие заключается в разнице между абстракцией данных конфигурации и развертыванием:

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

3.2 по сравнению с Настройкой

Основная возможность Kustomize — это возможность наложения на уровне файлов. Однако существует проблема с несколькими цепочками наложений, потому что нахождение оператора определенного значения атрибута не гарантирует, что это окончательное значение, потому что другое конкретное значение, которое появляется в другом месте, может переопределить его. Для сложных сценариев извлечение цепочки наследования файлов Kustomize часто не так удобно, как извлечение цепочки наследования кода KCL. Необходимо тщательно продумать указанный порядок перезаписи файла конфигурации. Кроме того, Kustomize не может решить проблемы написания конфигурации YAML, проверки ограничений, абстрагирования модели и разработки и больше подходит для простых сценариев конфигурации.

В KCL операция слияния конфигураций может быть детализирована для каждого атрибута конфигурации в коде, а стратегия слияния может гибко задаваться, не ограничиваясь общим ресурсом, а зависимость между конфигурациями может быть статически проанализирована с помощью оператора импорта ККЛ.

3.3 по сравнению с HCL

3.3.1 Особенности

3.3.2 Примеры

Переменная Terraform HCL и схема KCL

  • HCL
variable "subnet_delegations" {
  type = list(object({
    name               = string
    service_delegation = object({
      name    = string
      actions = list(string)
    })
  }))
  default     = null
  validation {
    condition = var.subnet_delegations == null ? true : alltrue([for d in var.subnet_delegations : (d != null)])
  }
  validation {
    condition = var.subnet_delegations == null ? true : alltrue([for n in var.subnet_delegations.*.name : (n != null)])
  }
  validation {
    condition = var.subnet_delegations == null ? true : alltrue([for d in var.subnet_delegations.*.service_delegation : (d != null)])
  }
  validation {
    condition = var.subnet_delegations == null ? true : alltrue([for n in var.subnet_delegations.*.service_delegation.name : (n != null)])
  }
}
  • ККЛ
schema SubnetDelegation:
    name: str
    service_delegation: ServiceDelegation

schema ServiceDelegation:
    name: str  # Required attributes
    actions?: [str]  # Optional attributes

subnet_delegations: [SubnetDelegation] = option("subnet_delegations")

Функция Terraform HCL и KCL Lambda

  • Как показано на https://www.terraform.io/language/functions и https://github.com/hashicorp/terraform/issues/27696, Terraform HCL предоставляет множество встроенных функций, но не поддержка пользователей для определения функций в Terraform (или необходимость написания сложных поставщиков Go для имитации локальных определяемых пользователем функций); KCL не только поддерживает использование пользователями ключевого слова lambda для прямого определения функций в коде KCL, но также поддерживает использование Python, Go и других языков для написания плагинов.
  • Определение функций и их вызов в KCL
add_func = lambda x: int, y: int -> int {
    x + y
}
two = add_func(1, 1)  # 2

Удалить нулевые значения в HCL и удалить нулевые значения в KCL

  • HCL
variable "conf" {
  type = object({
    description = string
    name        = string
    namespace   = string
    params = list(object({
      default     = optional(string)
      description = string
      name        = string
      type        = string
    }))
    resources = optional(object({
      inputs = optional(list(object({
        name = string
        type = string
      })))
      outputs = optional(list(object({
        name = string
        type = string
      })))
    }))
    results = optional(list(object({
      name        = string
      description = string
    })))
    steps = list(object({
      args    = optional(list(string))
      command = optional(list(string))
      env = optional(list(object({
        name  = string
        value = string
      })))
      image = string
      name  = string
      resources = optional(object({
        limits = optional(object({
          cpu    = string
          memory = string
        }))
        requests = optional(object({
          cpu    = string
          memory = string
        }))
      }))
      script     = optional(string)
      workingDir = string
    }))
  })
}

locals {
  conf = merge(
    defaults(var.conf, {}),
    { for k, v in var.conf : k => v if v != null },
    { resources = { for k, v in var.conf.resources : k => v if v != null } },
    { steps = [for step in var.conf.steps : merge(
      { resources = {} },
      { for k, v in step : k => v if v != null },
    )] },
  )
  • KCL (с использованием флага -n)
schema Param:
    default?: str
    name: str

schema Resource:
    cpu: str
    memory: str

schema Step:
    args?: [str]
    command?: [str]
    env?: {str:str}
    image: str
    name: str
    resources?: {"limits" | "requests": Resource}
    script?: str
    workingDir: str

schema K8sManifest:
    name: str
    namespace: str
    params: [Param]
    results?: [str]
    steps: [Step]

conf: K8sManifest = option("conf")

Подводя итог, в KCL его типы и ограничения определяются декларативно через схему. Видно, что по сравнению с Terraform HCL ограничения KCL могут быть записаны проще, когда реализованы те же функции (поля проверки и условия не нужно записывать повторно, как в Terraform). Кроме того, он предоставляет возможность задавать поля как необязательно (в отличие от поля конфигурации Terraform, которое по умолчанию может быть нулевым).

3.4 по сравнению с CUE

3.4.1 Особенности

3.4.2 Примеры

Ограничение CUE против ограничения KCL

CUE (прогон cue export base.cue prod.cue)

  • base.cue
// base.cue
import "list"

#App: {
    domainType: "Standard" | "Customized" | "Global",
    containerPort: >=1 & <=65535,
    volumes: [...#Volume],
    services: [...#Service],
}
#Service: {
    clusterIP: string,
    type: string,
    if type == "ClusterIP" {
        clusterIP: "None"
    }
}
#Volume: {
    container: string | *"*"  // The default value of `container` is "*"
    mountPath: string,
    _check: false & list.Contains(["/", "/boot", "/home", "dev", "/etc", "/root"], mountPath),
}
app: #App & {
    domainType: "Standard",
    containerPort: 80,
    volumes: [
        {
            mountPath: "/tmp"
        }
    ],
    services: [
        {
            clusterIP: "None",
            type: "ClusterIP"
        }
    ]
}
  • prod.cue
// prod.cue
app: #App & {
    containerPort: 8080,  // error: app.containerPort: conflicting values 8080 and 80:
}

KCL (запуск kcl base.k prod.k)

  • база.k
# base.k
schema App:
    domainType: "Standard" | "Customized" | "Global"
    containerPort: int
    volumes: [Volume]
    services: [Service]

    check:
        1 <= containerPort <= 65535

schema Service:
    clusterIP: str
    $type: str
    check:
        clusterIP == "None" if $type == "ClusterIP"

schema Volume:
    container: str = "*"  # The default value of `container` is "*"
    mountPath: str
    check:
        mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"]

app: App {
    domainType = "Standard"
    containerPort = 80
    volumes = [
        {
            mountPath = "/tmp"
        }
    ]
    services = [
        {
            clusterIP = "None"
            $type = "ClusterIP"
        }
    ]
}
  • прод.к
# prod.k
app: App {
    # Using `=` attribute operator to modify the `containerPort` of the base `app`.
    containerPort = 8080
    # Using `+=` attribute operator to add volumes of the base `app`.
    # Here, it means to add one volume in the prod environment.
    volumes += [
        {
            mountPath = "/tmp2"
        }
    ]
}

Кроме того, из-за идемпотентной функции слияния CUE нелегко использовать конфигурацию наложения, аналогичную Kustomize, для переопределения дополнительной возможности в сценариях, например, когда приведенный выше код CUE сообщит об ошибке конфликта.

3.5 Производительность

KCL работает лучше, чем CUE/Jsonnet/HCL и другие языки, в сценариях с большим размером кода или высокой вычислительной нагрузкой (CUE и другие языки ограничены накладными расходами на проверку ограничений во время выполнения, тогда как KCL является статически компилируемым языком).

  • CUE (тест.cue)
import "list"

temp: {
        for i, _ in list.Range(0, 10000, 1) {
                "a\(i)": list.Max([1, 2])
        }
}
  • KCL (тест.k)
a = lambda x: int, y: int -> int {
    max([x, y])
}
temp = {"a${i}": a(1, 2) for i in range(10000)}
  • Jsonnet (test.jsonnet)
local a(x, y) = std.max(x, y);
{
    temp: [a(1, 2) for i in std.range(0, 10000)],
}
  • Terraform HCL (test.tf. Поскольку функция terraform range поддерживает только до 1024 итераторов, range(10000) делится на 10 поддиапазонов)
output "r1" {
  value = {for s in range(0, 1000) : format("a%d", s) => max(1, 2)}
}
output "r2" {
  value = {for s in range(1000, 2000) : format("a%d", s) => max(1, 2)}
}
output "r3" {
  value = {for s in range(1000, 2000) : format("a%d", s) => max(1, 2)}
}
output "r4" {
  value = {for s in range(2000, 3000) : format("a%d", s) => max(1, 2)}
}
output "r5" {
  value = {for s in range(3000, 4000) : format("a%d", s) => max(1, 2)}
}
output "r6" {
  value = {for s in range(5000, 6000) : format("a%d", s) => max(1, 2)}
}
output "r7" {
  value = {for s in range(6000, 7000) : format("a%d", s) => max(1, 2)}
}
output "r8" {
  value = {for s in range(7000, 8000) : format("a%d", s) => max(1, 2)}
}
output "r9" {
  value = {for s in range(8000, 9000) : format("a%d", s) => max(1, 2)}
}
output "r10" {
  value = {for s in range(9000, 10000) : format("a%d", s) => max(1, 2)}
}
  • Время выполнения (учитывая фактическую стоимость ресурсов производственной среды, этот тест относится к одному ядру).

Еще одно сложное дело

Использование KCL и CUE для записи конфигурации Kubernetes.

  • CUE (тест.cue)
package templates

import (
 apps "k8s.io/api/apps/v1"
)
deployment: apps.#Deployment
deployment: {
 apiVersion: "apps/v1"
 kind:       "Deployment"
 metadata: {
  name:   "me"
  labels: me: "me"
 }
}
  • KCL (тест.к)
import kubernetes.api.apps.v1

deployment = v1.Deployment {
    metadata.name = "me"
    metadata.labels.name = "me"
}

4. Резюме

В блоге представлен общий обзор технологии декларативной конфигурации с акцентом на концепции KCL, основных функциях, вариантах использования и сравнении с другими языками конфигурации, в надежде помочь вам понять технологию декларативной конфигурации и язык KCL. Для получения дополнительной информации о концепции, предыстории и дизайне KCL посетите веб-сайт KCL.

5. Ссылка