• Русский
  • Custom Applications

    Понимание пользовательских приложений

    Пользовательское приложение — это парадигма приложения, построенная на нативных ресурсах Kubernetes (например, Deployment, Service, ConfigMap), строго соответствующая принципам декларативного дизайна API Kubernetes. Пользователи могут определять и развертывать приложения через стандартные YAML-файлы или прямые вызовы Kubernetes API, что обеспечивает тонкий контроль над жизненным циклом приложения. Приложения, созданные из таких источников, как образы, код и YAML, классифицируются как пользовательские приложения в Alauda Container Platform. Основой дизайна является баланс между гибкостью и стандартизацией, что идеально подходит для сценариев, требующих глубокой кастомизации управления.

    Основные возможности

    1. Управление на основе декларативного API
    • Объединяет распределённые ресурсы (например, Deployment, Service, Ingress) в логическую единицу приложения через Application CRD, обеспечивая атомарные операции.
    1. Абстракция на уровне приложения и агрегация состояния
    • Скрывает детали низкоуровневых ресурсов (например, статус реплик Pod). Разработчики могут напрямую через ресурс Application отслеживать общее состояние приложения (например, соотношение готовых endpoint, согласованность версий).

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

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

    • Разрешение зависимостей: автоматически выявляет и управляет совместимостью версий между компонентами (например, соответствие версий API Service и контроллеров Ingress).

    1. Расширенная наблюдаемость
    • Агрегирует метрики состояния всех связанных ресурсов (например, доступные реплики Deployment, нагрузка на Service), предоставляя глобальный обзор через единый Dashboard.

    Ценность дизайна

    ИзмерениеЦенностное предложение
    Управление сложностьюИнкапсулирует разбросанные ресурсы (например, Deployment, Service) в единую логическую сущность, снижая когнитивную и операционную нагрузку.
    СтандартизацияУнифицирует стандарты описания приложений через Application CRD, устраняя хаос управления, вызванный фрагментацией YAML.
    Совместимость с экосистемойБесшовно интегрируется с нативными инструментами (например, kubectl, Kubernetes Dashboard) и поддерживает расширения Helm Chart.
    Эффективность DevOpsРеализует декларативную доставку через GitOps пайплайны (например, Argo CD), ускоряя автоматизацию CI/CD.

    Архитектурный дизайн CRD пользовательского приложения

    Модуль пользовательского приложения определяет два основных CRD-ресурса, формирующих атомарные абстракции для управления приложением:

    ИзмерениеЦенностное предложение
    ApplicationОписывает метаданные и топологию компонентов логической единицы приложения, агрегируя ресурсы, такие как Deployment/Service, в единую сущность.
    ApplicationHistoryФиксирует все операции жизненного цикла приложения (создание/обновление/откат/удаление) в виде версионированных снимков, тесно связанный с Application CRD для сквозного аудита.

    Определение Application CRD

    Application CRD использует поле spec.componentKinds для объявления типов ресурсов Kubernetes (например, Deployment, Service), обеспечивая управление жизненным циклом между ресурсами.

    apiVersion: apiextensions.k8s.io/v1beta1
    kind: CustomResourceDefinition
    metadata:
      name: applications.app.k8s.io
    spec:
      group: app.k8s.io
      names:
        kind: Application
        listKind: ApplicationList
        plural: applications
        singular: application
      scope: Namespaced
      subresources:
        status: {}
      validation:
        openAPIV3Schema:
          properties:
            apiVersion:
              description: 'APIVersion определяет версионированную схему этого представления объекта. Сервера должны преобразовывать распознанные схемы в последнее внутреннее значение и могут отклонять нераспознанные значения. Подробнее: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#resources'
              type: string
            kind:
              description: 'Kind — строковое значение, представляющее REST-ресурс, который представляет этот объект. Сервера могут выводить это из конечной точки, на которую клиент отправляет запросы. Не может быть обновлено. В CamelCase. Подробнее: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
              type: string
            metadata:
              description: 'Metadata — объект, представляющий метаданные ресурса Kubernetes. Подробнее: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata'
              type: object
            spec:
              properties:
                assemblyPhase:
                  description: |
                    Инсталлятор может установить это поле, чтобы указать, что компоненты приложения
                    всё ещё разворачиваются ("Pending") или все уже развернуты ("Succeeded"). Если
                    приложение не может быть успешно собрано, инсталлятор может установить это поле в "Failed".'
                  type: string
                componentKinds:
                  description: |
                    Этот массив GroupKinds используется для указания типов ресурсов, из которых
                    состоит приложение. Например, приложение, имеющее сервис и деплоймент,
                    установит это поле в [{"group":"core","kind": "Service"},{"group":"apps","kind":"Deployment"}]
                  items:
                    description: 'Элемент GroupKinds, структура вида "{\"group\":\"core\",\"kind\": \"Service\"}"'
                    type: object
                  type: array
                descriptor:
                  properties:
                    description:
                      description: 'Краткое, удобочитаемое текстовое описание приложения.'
                      type: string
                    icons:
                      description: 'Список иконок приложения. Информация об иконках включает источник, размер и MIME-тип.'
                      items:
                        properties:
                          size:
                            description: 'Размер иконки.'
                            type: string
                          src:
                            description: 'Источник иконки.'
                            type: string
                          type:
                            description: 'MIME-тип иконки.'
                            type: string
                        required:
                        - src
                        type: object
                      type: array
                    keywords:
                      description: 'Список ключевых слов, идентифицирующих приложение.'
                      items:
                        type: string
                      type: array
                    links:
                      description: 'Ссылки — список описательных URL, предназначенных для предоставления дополнительной документации, дашбордов и т.д.'
                      items:
                        properties:
                          description:
                            description: 'Описание ссылки.'
                            type: string
                          url:
                            description: 'URL ссылки.'
                            type: string
                        type: object
                      type: array
                    maintainers:
                      description: 'Список сопровождающих приложение. Каждый сопровождающий имеет имя, email и URL. Это поле предназначено для дистрибьюторов приложения для указания своей идентичности и контактной информации.'
                      items:
                        properties:
                          email:
                            description: 'Email сопровождающего.'
                            type: string
                          name:
                            description: 'Имя сопровождающего.'
                            type: string
                          url:
                            description: 'URL для связи с сопровождающим.'
                            type: string
                        type: object
                      type: array
                    notes:
                      description: 'Заметки содержат удобочитаемые фрагменты, предназначенные для быстрого старта пользователей приложения. Могут быть в виде простого текста или CommonMark markdown.'
                      type: string
                    owners:
                      items:
                        properties:
                          email:
                            description: 'Email владельца.'
                            type: string
                          name:
                            description: 'Имя владельца.'
                            type: string
                          url:
                            description: 'URL для связи с владельцем.'
                            type: string
                        type: object
                      type: array
                    type:
                      description: 'Тип приложения (например, WordPress, MySQL, Cassandra). В одном namespace может быть много приложений с разными именами. Поле type используется для указания, что они все одного типа приложения.'
                      type: string
                    version:
                      description: 'Индикатор версии приложения (например, 5.7 для MySQL версии 5.7).'
                      type: string
                  type: object
                info:
                  description: 'Info содержит удобочитаемые пары ключ-значение для приложения.'
                  items:
                    properties:
                      name:
                        description: 'Имя информации.'
                        type: string
                      type:
                        description: 'Тип информации.'
                        type: string
                      value:
                        description: 'Значение информации.'
                        type: string
                      valueFrom:
                        description: 'Ссылка на значение из другого ресурса.'
                        properties:
                          configMapKeyRef:
                            description: 'Ссылка на ключ ConfigMap.'
                            properties:
                              key:
                                type: string
                            type: object
                          ingressRef:
                            description: 'Ссылка на ingress.'
                            properties:
                              host:
                                description: 'Хост ссылки ingress.'
                                type: string
                              path:
                                description: 'Путь ссылки ingress.'
                                type: string
                            type: object
                          secretKeyRef:
                            description: 'Ссылка на секретный ключ.'
                            properties:
                              key:
                                type: string
                            type: object
                          serviceRef:
                            description: 'Ссылка на сервис.'
                            properties:
                              path:
                                description: 'Путь ссылки сервиса.'
                                type: string
                              port:
                                description: 'Порт ссылки сервиса.'
                                format: int32
                                type: integer
                            type: object
                          type:
                            type: string
                        type: object
                    type: object
                  type: array
                selector:
                  description: 'Селектор используется для сопоставления ресурсов, принадлежащих приложению. Все ресурсы приложения должны иметь метки, чтобы соответствовать этому селектору. Пользователи должны использовать метку app.kubernetes.io/name на всех компонентах приложения и установить селектор для соответствия этой метке. Например, {"matchLabels": [{"app.kubernetes.io/name": "my-cool-app"}]} должен использоваться как селектор для приложения с именем "my-cool-app", и каждый компонент должен содержать соответствующую метку.'
                  type: object
              type: object
            status:
              description: 'Статус суммирует текущее состояние объекта.'
              properties:
                observedGeneration:
                  description: 'observedGeneration — поколение, недавно наблюдаемое компонентом, ответственным за действия при изменениях желаемого состояния ресурса.'
                  format: int64
                  type: integer
              type: object
      version: v1beta1
      versions:
      - name: v1beta1
        served: true
        storage: true
    

    Определение ApplicationHistory

    ApplicationHistory CRD фиксирует все операции жизненного цикла (например, создание, обновление, откат) в виде версионированных снимков и тесно интегрирован с Application CRD для обеспечения сквозного аудита.

    apiVersion: apiextensions.k8s.io/v1beta1
    kind: CustomResourceDefinition
    metadata:
      name: applicationhistories.app.k8s.io
    spec:
      group: app.k8s.io
      names:
        kind: ApplicationHistory
        listKind: ApplicationHistoryList
        plural: applicationhistories
        singular: applicationhistory
      scope: Namespaced
      validation:
        openAPIV3Schema:
          properties:
            apiVersion:
              description: 'APIVersion определяет версионированную схему этого представления объекта. Сервера должны преобразовывать распознанные схемы в последнее внутреннее значение и могут отклонять нераспознанные значения. Подробнее: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#resources'
              type: string
            kind:
              description: 'Kind — строковое значение, представляющее REST-ресурс, который представляет этот объект. Сервера могут выводить это из конечной точки, на которую клиент отправляет запросы. Не может быть обновлено. В CamelCase. Подробнее: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
              type: string
            metadata:
              description: 'Metadata — объект, представляющий метаданные ресурса Kubernetes. Подробнее: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata'
              type: object
            spec:
              properties:
                changeCause:
                  description: 'Причина изменения приложения, породившая ApplicationHistory.'
                  type: string
                creationTimestamp:
                  description: 'Временная метка создания истории приложения.'
                  format: date-time
                  type: string
                resourceDiffs:
                  description: 'Различия ресурсов между текущей и предыдущей версией приложения. Содержит 3 типа изменений: `create`, `delete` и `update`. Элемент различия состоит из kind и name изменённого ресурса.'
                  properties:
                    create:
                      items:
                        properties:
                          kind:
                            description: 'Тип созданного ресурса.'
                            type: string
                          name:
                            description: 'Имя созданного ресурса.'
                            type: string
                        type: object
                      type: array
                    delete:
                      items:
                        properties:
                          kind:
                            description: 'Тип удалённого ресурса.'
                            type: string
                          name:
                            description: 'Имя удалённого ресурса.'
                            type: string
                        type: object
                      type: array
                    update:
                      items:
                        properties:
                          kind:
                            description: 'Тип обновлённого ресурса.'
                            type: string
                          name:
                            description: 'Имя обновлённого ресурса.'
                            type: string
                        type: object
                      type: array
                  type: object
                revision:
                  description: |
                    Номер ревизии истории приложения. Целое число, увеличивающееся при каждом изменении приложения.'
                  type: integer
                user:
                  description: 'Имя пользователя, вызвавшего изменение приложения.'
                  type: string
                yaml:
                  description: |
                    YAML-строка снимка приложения и его компонентов.
                  type: string
              type: object
            status:
              description: 'Статус суммирует текущее состояние объекта.'
              properties:
                observedGeneration:
                  description: 'observedGeneration — поколение, недавно наблюдаемое компонентом, ответственным за действия при изменениях желаемого состояния ресурса.'
                  format: int64
                  type: integer
              type: object
          type: object
      version: v1beta1
      versions:
      - name: v1beta1
        served: true
        storage: true