Partilhar via


Recursos do Kubernetes em ambientes

Serviços de DevOps do Azure | Azure DevOps Server | Azure DevOps Server 2022

Este artigo descreve o uso de recursos do Kubernetes em ambientes do Azure Pipelines que você pode direcionar com implantações. Você pode se conectar a clusters Kubernetes públicos ou privados no Serviço Kubernetes do Azure (AKS) ou em outros provedores de nuvem.

As visualizações de recursos do ambiente mostram o estado dos recursos do Kubernetes e fornecem rastreabilidade para o pipeline e de volta para o commit que acionou. Você também pode criar recursos dinâmicos do ambiente Kubernetes para revisar solicitações pull antes da mesclagem. Para obter mais informações sobre recursos de ambiente, consulte Recursos em pipelines YAML e Segurança de recursos.

Nota

Um cluster AKS privado não expõe seu ponto de extremidade do servidor de API por meio de um endereço IP público, portanto, você deve se conectar à rede virtual do cluster. Você pode configurar um agente auto-hospedado em uma rede virtual que pode acessar a rede virtual do cluster ou usar Pools de DevOps Gerenciados. Para obter mais informações, consulte Opções para conexão a um cluster privado.

Vantagens dos recursos do ambiente Kubernetes

Os recursos de ambiente do Kubernetes e as visualizações de recursos em ambientes oferecem os seguintes benefícios:

  • Rastreabilidade de oleodutos. A tarefa de implantação do manifesto do Kubernetes adiciona anotações que oferecem suporte à rastreabilidade do pipeline. Você pode ver a organização, o projeto e o pipeline do Azure DevOps responsáveis pelas atualizações de objetos dentro do namespace.

    Captura de tela que mostra a rastreabilidade do pipeline para um cluster Kubernetes.

  • Diagnóstico de integridade de recursos. A visualização de status da carga de trabalho é uma maneira rápida de depurar erros ou regressões introduzidos por novas implantações. Por exemplo, as informações de status do pod podem ajudá-lo a identificar a causa de problemas como o não configurado imagePullSecrets, que resulta em erros ImagePullBackOff.

    Captura de tela que mostra a exibição de status da carga de trabalho para uma implantação do Kubernetes.

  • Rever a aplicação. O aplicativo de revisão implanta cada solicitação pull do seu repositório Git em um recurso dinâmico do Kubernetes no ambiente e publica um comentário do GitHub vinculando ao aplicativo de revisão. Os revisores podem ver a aparência das alterações de RP e trabalhar com outros serviços dependentes antes que as alterações sejam mescladas na ramificação de destino e implantadas na produção.

    Captura de tela que mostra o comentário do aplicativo Review no GitHub.

Recursos do AKS

O AKS cria uma ServiceAccount no cluster e namespace escolhidos e mapeia os recursos do Kubernetes em seu ambiente para o namespace especificado. Para obter informações sobre como configurar uma conexão de serviço Kubernetes fora de um ambiente, consulte Conexão de serviço Kubernetes.

Para um cluster com controlo de acesso baseado em funções (RBAC) do Kubernetes, RoleBinding também é criado para limitar o escopo da conta de serviço ao Namespace escolhido. Para um cluster desabilitado pelo Kubernetes RBAC, a conta de serviço criada tem privilégios em todo o cluster entre namespaces.

Para adicionar um recurso AKS a um ambiente do Azure Pipelines:

  1. Na página do ambiente, em Ambientes de pipelines>, selecione Adicionar recurso e, em seguida, selecione Kubernetes.

  2. Na tela seguinte, selecione Serviço Kubernetes do Azure para o Provedor e selecione sua assinatura do Azure, Cluster AKS e Namespace novo ou existente. Para um novo namespace, insira o nome do namespace.

  3. Selecione Validar e criar. O novo recurso aparece na guia Recursos do ambiente com o texto Nunca implantado.

    Captura de tela que mostra um recurso Kubernetes adicionado.

Recursos Kubernetes não-AKS

Para mapear um recurso do Kubernetes de um cluster não-AKS para um namespace, você precisa ter uma conta de serviço existente para o provedor não-AKS.

Para adicionar um recurso Kubernetes não AKS a um ambiente do Azure Pipelines:

  1. Na página do ambiente, em Ambientes de pipelines>, selecione Adicionar recurso e, em seguida, selecione Kubernetes.

  2. Na tela seguinte, selecione Provedor genérico (conta de serviço existente) para o provedor.

  3. Em Credenciais de cluster, insira o Nome do cluster, Namespace, URL do servidor e Segredo.

    • Para obter a URL do servidor, execute kubectl config view --minify -o jsonpath={.clusters[0].cluster.server} em seu shell local.

    • Para obter o segredo:

      1. Obtenha nomes secretos de conta de serviço executando kubectl get serviceAccounts <service-account-name> -n <namespace> -o=jsonpath={.secrets[*].name}.
      2. Execute kubectl get secret <service-account-secret-name> -n <namespace> -o json usando a saída do comando anterior.

      Nota

      Se não obtiver resultados ao executar o comando get ServiceAccounts, consulte Criar manualmente um token de API de longa duração para uma ServiceAccount.

  4. Selecione Validar e criar.

Recursos do Kubernetes em pipelines

A maneira mais fácil de criar um pipeline YAML para implantar no AKS é começar com o modelo Implantar nos Serviços Kubernetes do Azure . Você não precisa escrever código YAML ou criar manualmente ligações de função explícitas. O pipeline gerado define e usa variáveis e outros valores com base em suas definições de configuração.

Usar o app de revisão

A tarefa DeployPullRequest implanta cada solicitação pull do repositório Git em um recurso Kubernetes dinâmico no ambiente. Para adicionar esta tarefa ao pipeline, marque a caixa de seleção Habilitar fluxo de revisão do aplicativo para pull requests no formulário de configuração Implantar no Azure Kubernetes Services.

Nota

Para adicionar esse trabalho a um pipeline existente, verifique se a conexão de serviço que dá suporte ao recurso de ambiente Kubernetes regular está definida como Usar credenciais de administrador de cluster. Caso contrário, para a conta de serviço subjacente, devem ser criadas associações de função no namespace da aplicação de revisão.

Os recursos do aplicativo de revisão são rotulados como Revisão na listagem de recursos do ambiente.

Captura de tela que mostra o ambiente de revisão na listagem do ambiente de pipeline.

Exemplo de pipeline

O pipeline de exemplo a seguir é baseado no modelo Implantar nos Serviços Kubernetes do Azure . O pipeline primeiro cria e envia por push uma imagem para o Registro de Contêiner do Azure.

Logo após, a primeira tarefa de implantação é executada para qualquer commit na main ramificação e implanta contra um recurso regular de Kubernetes no ambiente.

O segundo trabalho é executado quando uma PR é criada ou atualizada para a ramificação main e é implantado contra um recurso de aplicativo de revisão dinâmica que é criado no cluster sob demanda.

# 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"