Ресурсы Kubernetes в средах

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

В этой статье описывается использование ресурсов Kubernetes в средах Azure Pipelines, на которые вы можете нацелиться с помощью развертываний. Вы можете подключиться к общедоступным или частным кластерам Kubernetes в службе Azure Kubernetes (AKS) или других поставщиков облачных служб.

Представления ресурсов среды показывают состояние ресурсов Kubernetes и обеспечивают трассировку от конвейера к фиксации коммита. Вы также можете создавать динамические ресурсы среды Kubernetes, чтобы просмотреть pull-запросы перед слиянием. Дополнительные сведения о ресурсах среды см. в разделе "Ресурсы" в конвейерах YAML и безопасности ресурсов.

Примечание.

Частный кластер AKS не предоставляет конечную точку сервера API через общедоступный IP-адрес, поэтому необходимо подключиться к виртуальной сети кластера. Вы можете настроить автономный агент в виртуальной сети, которая может получить доступ к виртуальной сети кластера или использовать управляемые пулы DevOps. Дополнительные сведения см. в разделе "Параметры подключения к частному кластеру".

Преимущества ресурсов среды Kubernetes

Ресурсы среды Kubernetes и представления ресурсов в средах предоставляют следующие преимущества:

  • Возможность трассировки конвейера. Задача развертывания манифеста Kubernetes добавляет заметки, поддерживающие трассировку конвейера. Вы можете увидеть организацию, проект и конвейер Azure DevOps, отвечающий за обновления объектов в пространстве имен.

    Снимок экрана, показывающий трассируемость pipeline в кластере Kubernetes.

  • Диагностика работоспособности ресурсов. Представление состояния рабочей нагрузки — это быстрый способ отладки ошибок или регрессий, представленных новыми развертываниями. Например, сведения о состоянии pod могут помочь определить причину таких проблем, как ненастроенные imagePullSecrets, которые вызывают ошибки ImagePullBackOff.

    Снимок экрана: представление состояния рабочей нагрузки для развертывания Kubernetes.

  • Просмотрите приложение. Приложение для рецензирования развертывает каждый pull request из вашего репозитория Git в динамический ресурс Kubernetes в рабочей среде и публикует комментарий GitHub со ссылкой на приложение для рецензирования. Рецензенты могут узнать, как изменения PR выглядят и работают с другими зависимыми службами, прежде чем изменения объединяются в целевую ветвь и развертываются в рабочей среде.

    Снимок экрана: комментарий приложения

Ресурсы AKS

AKS создает ServiceAccount в выбранном кластере и пространстве имен и сопоставляет ресурсы Kubernetes в вашей среде с указанным пространством имен. Сведения о настройке подключения службы Kubernetes за пределами среды см. в разделе "Подключение службы Kubernetes".

Для кластера с поддержкой управления доступом на основе ролей Kubernetes (RBAC) создается RoleBinding, чтобы ограничить область учетной записи службы выбранным пространством имен. Для кластера Kubernetes с отключенной RBAC созданная учетная запись службы имеет привилегии на уровне кластера во всех пространствах имен.

Чтобы добавить ресурс AKS в среду Azure Pipelines, выполните приведенные действия.

  1. На странице среды в разделе Конвейеры>Среды выберите Добавить ресурс, а затем выберите Kubernetes.

  2. На следующем экране выберите службу Azure Kubernetes для поставщика, а затем выберите подписку Azure, кластер AKS и новое или существующее пространство имен. Для нового пространства имен введите имя пространства имен.

  3. Выберите Проверить и создать. Новый ресурс отображается на вкладке Ресурсы среды с пометкой Никогда не развернуто.

    Снимок экрана, показывающий добавленный ресурс Kubernetes.

Ресурсы Kubernetes, отличные от AKS

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

Чтобы добавить ресурс Kubernetes, отличный от AKS, в среду Azure Pipelines:

  1. На странице среды в разделе Конвейеры>Среды выберите Добавить ресурс, а затем выберите Kubernetes.

  2. На следующем экране выберите универсальный поставщик (существующая учетная запись службы) для поставщика.

  3. В разделе учетные данные кластера введите имя кластера, пространство имен, URL-адрес сервера и секрет.

    • Чтобы получить URL-адрес сервера, выполните команду kubectl config view --minify -o jsonpath={.clusters[0].cluster.server} в локальной оболочке.

    • Чтобы получить секрет, выполните следующие действия.

      1. Получите имена секретов учетной записи службы, выполнив команду kubectl get serviceAccounts <service-account-name> -n <namespace> -o=jsonpath={.secrets[*].name}.
      2. Запустите kubectl get secret <service-account-secret-name> -n <namespace> -o json с помощью выходных данных предыдущей команды.

      Примечание.

      Если команда get ServiceAccounts не дает результатов, см. раздел «Ручное создание API-маркера с длительным сроком действия для ServiceAccount».

  4. Выберите Проверить и создать.

Ресурсы Kubernetes в конвейерах

Самый простой способ создать конвейер YAML для развертывания в AKS — начать с шаблона Deploy to Azure Kubernetes Services . Вам не нужно писать код YAML или вручную создавать явные привязки ролей. Созданные поточные процессы задают и используют переменные и другие значения на основе параметров конфигурации.

Использование приложения проверки

Задача DeployPullRequest разворачивает каждый pull request из репозитория Git в динамический ресурс Kubernetes в среде. Чтобы добавить это задание в конвейер, установите флажок включите поток рецензирования приложений для запросов на вытягивание в форме конфигурации развертывания в Azure Kubernetes Services.

Примечание.

Чтобы добавить это задание в существующий пайплайн, убедитесь, что для подключения службы, поддерживающего ресурс среды Kubernetes, установлено значение Use cluster admin credentials. В противном случае необходимо создать привязки ролей для основной учетной записи службы в пространстве имен приложения для обзора.

Просмотрите ресурсы приложения, отмеченные как «Отзыв» в списке ресурсов рабочего окружения.

Снимок экрана: среда проверки в списке среды конвейера.

Пример конвейера

Следующий пример конвейера основан на шаблоне Развертывание в службах Kubernetes Azure. Конвейер сначала создает и отправляет образ в реестр контейнеров Azure.

Первое задание развертывания запускается для любых фиксаций в main ветви и развертывается в обычном ресурсе Kubernetes в среде.

Второе задание выполняется при создании или обновлении pr в main ветви и развертывании в ресурсе приложения динамической проверки, который он создает в кластере по запросу.

# Deploy to Azure Kubernetes Service
# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- main

resources:
- repo: self

variables:

  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: '12345' # Docker service connection identifier
  imageRepository: 'name-of-image-repository' # name of image repository
  containerRegistry: 'mycontainer.azurecr.io' # path to container registry
  dockerfilePath: '**/Dockerfile'
  tag: '$(Build.BuildId)'
  imagePullSecret: 'my-app-secret' # image pull secret

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

  # Name of the new namespace being created to deploy the PR changes.
  k8sNamespaceForPR: 'review-app-$(System.PullRequest.PullRequestId)'

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

    - upload: manifests
      artifact: manifests

- stage: Production
  displayName: Deploy stage
  dependsOn: Build

  jobs:
  - deployment: Production
    condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
    displayName: Production
    pool:
      vmImage: $(vmImageName)
    environment: 'myenvironmentname.myresourcename'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: KubernetesManifest@1
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@1
            displayName: Deploy to Kubernetes cluster
            inputs:
              action: deploy
              manifests: |
                $(Pipeline.Workspace)/manifests/deployment.yml
                $(Pipeline.Workspace)/manifests/service.yml
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository):$(tag)

  - deployment: DeployPullRequest
    displayName: Deploy Pull request
    condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/pull/'))
    pool:
      vmImage: $(vmImageName)

    environment: 'myenvironmentname.$(k8sNamespaceForPR)'
    strategy:
      runOnce:
        deploy:
          steps:
          - reviewApp: default

          - task: Kubernetes@1
            displayName: 'Create a new namespace for the pull request'
            inputs:
              command: apply
              useConfigurationFile: true
              inline: '{ "kind": "Namespace", "apiVersion": "v1", "metadata": { "name": "$(k8sNamespaceForPR)" }}'

          - task: KubernetesManifest@1
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              namespace: $(k8sNamespaceForPR)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@1
            displayName: Deploy to the new namespace in the Kubernetes cluster
            inputs:
              action: deploy
              namespace: $(k8sNamespaceForPR)
              manifests: |
                $(Pipeline.Workspace)/manifests/deployment.yml
                $(Pipeline.Workspace)/manifests/service.yml
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository):$(tag)

          - task: Kubernetes@1
            name: get
            displayName: 'Get services in the new namespace'
            continueOnError: true
            inputs:
              command: get
              namespace: $(k8sNamespaceForPR)
              arguments: svc
              outputFormat: jsonpath='http://{.items[0].status.loadBalancer.ingress[0].ip}:{.items[0].spec.ports[0].port}'

          # Get the IP of the deployed service and writing it to a variable for posting comment
          - script: |
              url="$(get.KubectlOutput)"
              message="Your review app has been deployed"
              if [ ! -z "$url" -a "$url" != "http://:" ]
              then
                message="${message} and is available at $url."
              fi
              echo "##vso[task.setvariable variable=GITHUB_COMMENT]$message"