Практическое руководство по упрощению управления конфигурацией Kubernetes с помощью KCL и KPM.

Что такое ККЛ

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

Что такое КПМ

KPM — менеджер пакетов KCL. KPM загружает зависимости вашего пакета KCL, компилирует ваши пакеты KCL, создает пакеты и загружает их в реестр пакетов kcl.

Зачем использовать ККЛ

Когда мы управляем ресурсами Kubernetes, мы часто обслуживаем их вручную или используем инструменты Helm и Kustomize для поддержки наших конфигураций YAML или шаблонов конфигураций, а затем применяем ресурсы к кластеру с помощью инструментов kubectl. Однако для «инженера YAML» ежедневная поддержка конфигурации YAML, несомненно, тривиальна и утомительна и подвержена ошибкам. Например, следующим образом:

apiVersion: apps/v1
kind: Deployment
metadata: ... # Omit
spec:
  selector:
    matchlabels:
      cell: RZ00A
  replicas: 2
  template:
    metadata: ... # Omit
    spec:
      tolerations:
      - effect: NoSchedules
        key: is-over-quota
        operator: Equal
        value: 'true'
      containers:
      - name: test-app
          image: images.example/app:v1 # Wrong ident
        resources:
          limits:
            cpu: 2 # Wrong type. The type of cpu should be str
            memory: 4Gi
            # Field missing: ephemeral-storage
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: is-over-quota
                operator: In
                values:
                - 'true'
  • Структурированные данные в YAML нетипизированы и не имеют методов проверки, поэтому достоверность всех данных нельзя проверить сразу.
  • YAML имеет плохие возможности программирования. Легко написать неправильные отступы и не имеет общих методов организации кода, таких как логическое суждение. Легко написать большое количество повторяющихся конфигураций и сложно поддерживать.
  • Дизайн Kubernetes сложен, и пользователям сложно понять все детали, такие как поля toleration и affinity в приведенной выше конфигурации. Если пользователи не понимают логику планирования, она может быть ошибочно опущена или добавлена ​​лишняя.

Поэтому KCL рассчитывает решить следующие проблемы в управлении ресурсами Kubernetes YAML:

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

Как использовать KCL для создания ресурсов Kubernetes и управления ими

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

Создание манифестов Kubernetes

Мы можем написать следующий код KCL и назвать его main.k. KCL вдохновлен Python. Его базовый синтаксис очень близок к Python, который легко освоить. Режим конфигурации простой, k [: T] = v, где k обозначает имя сконфигурированного атрибута, v обозначает сконфигурированное значение атрибута, а : T обозначает необязательную аннотацию типа.

apiVersion = "apps/v1"
kind = "Deployment"
metadata = {
    name = "nginx"
    labels.app = name
}
spec = {
    replicas = 3
    selector.matchLabels = metadata.labels
    template.metadata.labels = metadata.labels
    template.spec.containers = [
        {
            name = metadata.name
            image = "${metadata.name}:1.14.2"
            ports = [{ containerPort = 80 }]
        }
    ]
}

В приведенном выше коде KCL мы объявляем apiVersion, kind, metadata, spec и другие переменные ресурса Kubernetes Deployment и соответственно назначаем соответствующее содержимое. В частности, мы назначим поля metadata.labels повторно используемыми в полях spec.selector.matchLabels и spec.template.metadata.labels. Видно, что по сравнению с YAML структура данных, определенная KCL, более компактна, а повторное использование конфигурации может быть реализовано путем определения локальных переменных.

Мы можем получить файл Kubernetes YAML, выполнив следующую командную строку

kcl main.k

Выход

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

Конечно, мы можем использовать KCL вместе с kubectl и другими инструментами. Давайте выполним следующие команды и посмотрим на результат:

$ kcl main.k | kubectl apply -f -
deployment.apps/nginx-deployment configured

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

Проверить статус развертывания через kubectl

$ kubectl get deploy

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           15s

Как использовать KPM для управления ресурсами Kubernetes

Вы можете получить kpm из выпуска kpm github и установить двоичный путь kpm в переменную окружения PATH.

# KPM_INSTALLATION_PATH is the path of the `kpm` binary.
export PATH=$KPM_INSTALLATION_PATH:$PATH

Используйте следующую команду, чтобы убедиться, что вы успешно установили kpm.

kpm --help

Установить переменные среды

Вам нужно установить переменную среды KPM_HOME для хранения пакетов KCL, загруженных kpm.

Примечание. kpm не поддерживает загрузку внешних пакетов в текущий каталог пакетов kcl, поэтому убедитесь, что «$KPM_HOME» не находится в том же каталоге, что и текущий пакет KCL.

# The directory to save the packages downloaded by Kpm. 
export KPM_HOME="/user/xxx/xxx/path"

Чтобы убедиться, что KCLVM может найти пакеты, загруженные kpm, вам необходимо установить переменные среды $KCLVM_VENDOR_HOME и указать их на $KPM_HOME для KCLVM после загрузки KCLVM.

export KCLVM_VENDOR_HOME=$KPM_HOME

Запустите пустой пакет KCL

Сначала создайте пустую папку для пакета KCL и перейдите в эту папку.

mkdir my_package # create an empty folder 'my_package'
cd my_package # go into the folder 'my_package'

Создайте новый пакет kcl с именем my_package.

kpm init my_package

kpm создаст два файла конфигурации пакета kcl: kcl.mod и kcl.mod.lock в каталоге, где вы выполнили команду.

- my_package
      |- kcl.mod
      |- kcl.mod.lock
      |- # You can write your kcl program directly in this directory.

kcl.mod.lock — это файл, сгенерированный kpm для исправления версии зависимостей. Не изменяйте этот файл вручную.

kpm инициализирует kcl.mod для пустого проекта, как показано ниже:

[package]
name = "my_package"
edition = "0.0.1"
version = "0.0.1"

Добавить зависимость от Git Registry

Если вам нужно использовать модель KCL в Конфиге, написать программу kcl.

kpm add -git https://github.com/awesome-kusion/konfig.git -tag v0.0.1

Вы можете видеть, что kpm добавляет зависимость, которую вы только что добавили в kcl.mod.

[package]
name = "my_package"
edition = "0.0.1"
version = "0.0.1"

[dependencies]
# 'konfig' is the package name
# If you want to use the contents of this package, 
# you need to write the import statment with the package name 'konfig' as the prefix.
konfig = { git = "https://github.com/awesome-kusion/konfig.git", tag = "v0.0.1" }

Напишите программу KCL, которая использует содержимое в konfig

Создайте файл main.k в текущем пакете.

- my_package
      |- kcl.mod
      |- kcl.mod.lock
      |- main.k # Your KCL program.

И напишите следующее в файл main.k.

import konfig.base.pkg.kusion_kubernetes.api.apps.v1 as apps

demo = apps.Deployment {
    metadata.name = "nginx-deployment"
    spec = {
        replicas = 3
        selector.matchLabels = {
            app = "nginx"
        }
        template.metadata.labels = {
            app = "nginx"
        }
        template.spec.containers = [
            {
                name = "nginx"
                image = "nginx:1.14.2"
                ports = [
                    {containerPort = 80}
                ]
            }
        ]
    }
}

Используйте kpm скомпилируйте пакет kcl

Вы можете использовать kpm для компиляции файла main.k, который вы только что написали.

kcl main.k -S demo

Если вы получите следующий вывод, поздравляем!, вы успешно скомпилировали свой пакет kcl с kpm.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: "nginx:1.14.2"
          name: nginx
          ports:
            - containerPort: 80

Интеграция OAM в KCL

Kubevela и Open Application Model (OAM) предлагают модульную, расширяемую и переносимую конструкцию для моделирования развертывания приложений с более высоким уровнем, но согласованным API.

Точно так же вы можете использовать OAM в коде KCL напрямую, как показано ниже:

import konfig.base.pkg.kusion_kubevela.v1beta1

app: v1beta1.Application {
    metadata.name = "webservice-app"
    spec.components = [{
        name = "front-end"
        type = "webservice"
        properties = {
            image = "oamdev/testapp:v1"
            cmd = ["node", "server.js"]
            ports = [{port = 8080, expose = True}]
            exposeType = "NodePort"
            cpu = "0.5"
            memory = str(512Mi)
        }
        traits = [
            {
                type = "scaler"
                properties.replicas = 1
            }
        ]
    }]
}

Выполните следующие команды

$ kcl main.k -S app

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: webservice-app
spec:
  components:
    - name: front-end
      properties:
        image: "oamdev/testapp:v1"
        cmd:
          - node
          - server.js
        ports:
          - port: 8080
            expose: true
        exposeType: NodePort
        cpu: "0.5"
        memory: 512Mi
      traits:
        - properties:
            replicas: 1
          type: scaler
      type: webservice

Хочу больше?

Дополнительную информацию см. на веб-сайте KCL и примечаниях к выпуску KCL v0.4.6.