Обзор фреймворка cdk8s для «программирования» Kubernetes-манифестов

в 9:09, , рубрики: cdk8s, devops, kubernetes, TypeScript, yaml, Блог компании Флант, системное администрирование

Kubernetes стал стандартом для запуска микросервисных (и не только) приложений. Компании разных размеров — от стартапов до enterprise — стараются проектировать свои приложения готовыми для запуска в Kubernetes-кластере.

Обзор фреймворка cdk8s для «программирования» Kubernetes-манифестов - 1

А для запуска приложения в K8s обычно используют Helm-шаблоны с описанием манифестов. Хотя формат шаблонов легко читается и прост в изучении, он может вызвать определенные сложности, когда логика деплоя приложения разрастается, когда создаются дополнительные тестовые контуры (с деплоем только отдельных частей приложения) и т.д. При активном использовании Go-шаблонов рефакторинг манифестов может превратиться в нетривиальную задачу*.

Что делать, если у разработчиков нет времени разбираться со всеми тонкостями Helm-шаблонов, синтаксисом YAML и Go templates, но нужно запустить приложение в Kubernetes? Ответом на этот вопрос может стать использование cdk8s.

* Хотя применение Go-шаблонов и позволяет внедрять некоторые продвинутые возможности в таких шаблонах, чтобы этого добиться, придется «выкручиваться» с Helm-шаблонизацией по максимуму. О некоторых таких хитростях мы писали в этой статье.

Что такое cdk8s

Обзор фреймворка cdk8s для «программирования» Kubernetes-манифестов - 2

cdk8s — это фреймворк с открытым исходным кодом для генерации ресурсов Kubernetes. Название расшифровывается как Cloud Development Kit for Kubernetes.

Основная идея cdk8s заключается в том, что с ним вместо Helm-шаблонов для управления ресурсами и приложениями в Kubernetes можно использовать привычные языки разработки: TypeScript, JavaScript, Python и Java. Недавно также появилась поддержка Go, хотя формальный issue по этому поводу ещё не закрыли. Список этих языков будет расширяться и в дальнейшем — например, можно найти тикеты по Rust или Ruby.

Разработкой и поддержкой проекта занимается AWS, а также более широкое сообщество (на данный момент у GitHub-репозитория около 50 контрибьюторов в кодовую базу и около 2500 звёзд).

При использовании cdk8s для описания Kubernetes-объектов вы получаете все преимущества знакомого вам языка, а также все возможности привычной IDE: подсказки типов, автозаполнение, циклы и итерации, совместно используемые модули и классы… Кроме того, применение тестов поможет избежать ошибок, повысить продуктивность и избавиться от написания огромного количества Helm-шаблонов.

После того, как необходимые для работы приложения ресурсы спроектированы с помощью фреймворка, cdk8s сгенерирует для него Helm-шаблоны, которые легко развернуть в K8s с помощью команды kubectl apply или другой утилиты.

cdk8s работает локально, но все сгенерированные Helm-шаблоны можно применить к любому кластеру Kubernetes.

Компоненты cdk8s

Фреймворк cdk8s состоит из трех основных компонентов:

  • ядро фреймворка,

  • библиотека конструкций,

  • интерфейс командной строки.

Библиотека конструкций (на базе constructs) — набор основных компонентов для создания манифестов для конкретного объекта: Pod, Service, Deployment, ReplicaSet и т.д.

Конструкции позволяют:

  • создавать API абстракции, используя строго типизированные типы данных;

  • взаимодействовать с методами и свойствами;

  • тестировать, используя знакомые инструменты и методы тестирования.

Чтобы воспользоваться библиотекой конструкций, достаточно подключить ее в коде через import { Construct } from 'constructs';.

Интерфейс командной строки позволяет инициализировать шаблон для cdk8s на нужном языке программирования и сгенерировать конечные манифесты.

Пример использования cdk8s на TypeScript

Технически, cdk8s — это набор библиотек, который устанавливается как npm-пакет и является кроссплатформенным. Минимальные требования для работы cdk8s на TypeScript (JavaScript) — установить Node.js и npm.

После этого инсталляция фреймворка выполняется командой:

$ npm install -g cdk8s-cli

Для инициализации проекта cdk8s нужно использовать утилиту командной строки с указанием шаблона языка — например, python-app или javascript-app. Далее будем рассматривать для примера работу с TypeScript:

$ mkdir /app
$ cd /app
$ cdk8s init typescript-app

В результате выполнения команды у нас в директории будет создана структура проекта:

app@cdk8s:/app# cdk8s init typescript-app
Initializing a project from the typescript-app template
npm notice created a lockfile as package-lock.json. You should commit this file.

+ constructs@3.3.75
+ cdk8s@1.0.0-beta.18
+ cdk8s-plus-17@1.0.0-beta.20
added 11 packages from 10 contributors and audited 11 packages in 2.863s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities

+ @types/jest@26.0.23
+ jest@27.0.4
+ @types/node@15.12.0
+ ts-jest@27.0.2
+ typescript@4.3.2
added 423 packages from 297 contributors and audited 436 packages in 53.492s

25 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

+ cdk8s-cli@1.0.0-beta.19
added 131 packages from 106 contributors and audited 567 packages in 10.449s

63 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

> app@1.0.0 import /app
> cdk8s import

k8s

> app@1.0.0 compile /app
> tsc

> app@1.0.0 test /app
> jest "-u"

 PASS  ./main.test.ts
  Placeholder
    ✓ Empty (8 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        2.588 s
Ran all test suites.

> app@1.0.0 synth /app
> cdk8s synth

dist/app.k8s.yaml
========================================================================================================

 Your cdk8s typescript project is ready!

   cat help         Print this message

  Compile:
   npm run compile     Compile typescript code to javascript (or "yarn watch")
   npm run watch       Watch for changes and compile typescript in the background
   npm run build       Compile + synth

  Synthesize:
   npm run synth       Synthesize k8s manifests from charts to dist/ (ready for 'kubectl apply -f')

Deploy:
   kubectl apply -f dist/*.k8s.yaml

 Upgrades:
   npm run import        Import/update k8s apis (you should check-in this directory)
   npm run upgrade       Upgrade cdk8s modules to latest version
   npm run upgrade:next  Upgrade cdk8s modules to latest "@next" version (last commit)

========================================================================================================

Имя сгенерированного YAML-файла (в нашем случае это dist/app.k8s.yaml) зависит от параметров, с которыми производится вызов библиотеки. В этом файле будут содержаться все ресурсы, которые использовались при генерации. При желании можно разделить генерацию манифестов на разные файлы.

Содержимое dist/app.k8s.yaml, созданного на этапе инициализации библиотеки, сейчас будет пустым.

Изучим файл TypeScript-приложения (main.ts) на примере из Getting Started и увидим там базовый шаблон без определения компонентов Kubernetes. Исправим это, добавив два объекта: Deployment и Service. Для этого приведем файл к следующему виду:

import { Construct } from 'constructs';
import { App, Chart, ChartProps } from 'cdk8s';

// imported constructs
import { KubeDeployment, KubeService, IntOrString } from './imports/k8s';

export class MyChart extends Chart {
  constructor(scope: Construct, id: string, props: ChartProps = { }) 
  {
    super(scope, id, props);

    const label = { app: 'hello-k8s' };

    new KubeService(this, 'service', {
      spec: {
        type: 'LoadBalancer',
        ports: [ { port: 80, targetPort: IntOrString.fromNumber(8080) } ],
        selector: label
      }
    });

    new KubeDeployment(this, 'deployment', {
      spec: {
        replicas: 2,
        selector: {
          matchLabels: label
        },
        template: {
          metadata: { labels: label },
          spec: {
            containers: [
              {
                name: 'hello-kubernetes',
                image: 'paulbouwer/hello-kubernetes:1.7',
                ports: [ { containerPort: 8080 } ]
              }
            ]
          }
        }
      }
    });
  }
}

const app = new App();
new MyChart(app, 'hello');
app.synth();

Мы добавили сервис типа LoadBalancer и Deployment, который будет иметь 2 реплики и предварительно определенный label.

Теперь для генерации манифестов необходимо запустить команду cdk8s synth (от англ. synthesize — «синтезировать»), которая и делает всю «магию»:

$ cdk8s synth
dist/hello.k8s.yaml

Файлы с манифестами создаются с именем hello, которое мы передали в качестве параметра для инициализации объекта класса.

Теперь можно посмотреть на содержимое результирующего файла dist/hello.k8s.yaml: в нем будут перечислены все необходимые компоненты для деплоя приложения (с добавленными нами ресурсами) в кластер Kubernetes:

$ cat dist/hello.k8s.yaml
apiVersion: v1
kind: Service
metadata:
  name: hello-service-c8c17160
spec:
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: hello-k8s
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deployment-c8c7fda7
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello-k8s
  template:
    metadata:
      labels:
        app: hello-k8s
    spec:
      containers:
        - image: paulbouwer/hello-kubernetes:1.7
          name: hello-kubernetes
          ports:
            - containerPort: 8080

Остается только задеплоить эти YAML-файлы в кластер, например с помощью команды kubectl:

$ kubectl apply -f dist/hello.k8s.yaml

Готово!

Больше готовых примеров использования cdk8s на разных языках можно найти в репозитории проекта.

Заключение

cdk8s — очень перспективный фреймворк для генерации манифестов ресурсов Kubernetes. Разработчики могут достаточно быстро освоить основные компоненты фреймворка, необходимые для запуска приложения в кластере.

На текущий момент есть примеры интеграции cdk8s с Flux в случае использования библиотеки для Python или JavaScript, а также интеграция с Argo (для Python).

В настоящий момент проект имеет статус бета-версии и, по всей видимости, приближается к своему первому стабильному релизу. Несмотря на то, что последний формальный релиз на GitHub — v1.0.0-beta.10 — состоялся полгода назад, разработка cdk8s медленно, но верно продвигается, что подтверждается статистикой за последний месяц.

Статистика по проекту на GitHub за последний месяц
Статистика по проекту на GitHub за последний месяц

Возможно, авторы просто перестали публиковать публичные бета-релизы, потому что в документации проекта указана другая актуальная версия:

Обзор фреймворка cdk8s для «программирования» Kubernetes-манифестов - 4

К слову, в других репозиториях организации на GitHub доступны некоторые дополнения к основному проекту — например, готовые constructs для конкретных приложений (Redis, Grafana) и библиотеку cdk8s-operator для создания Kubernetes-операторов.

Наконец, важно отметить, что в конце прошлого года cdk8s был принят в «песочницу» CNCF.

P.S.

Читайте также в нашем блоге:

Автор: Алексей

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js