Entorno: recurso de Kubernetes

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

La vista de recursos de Kubernetes proporciona una visión del estado de los objetos dentro del espacio de nombres asignado al recurso. Esta vista de recursos también superpone la rastreabilidad de la canalización para que pueda realizar un seguimiento desde un objeto de Kubernetes a la canalización y, a continuación, volver a la confirmación.

Use recursos de Kubernetes para dirigirse a clústeres de Kubernetes en un entorno para la implementación. Use canalizaciones para implementar en Azure Kubernetes Service (AKS) y clústeres de cualquier otro proveedor de nube.

Puede usar recursos de Kubernetes con clústeres públicos o privados. Para obtener más información sobre cómo funcionan los recursos, consulte recursos en YAML y seguridad con recursos.

Información general

Consulte las siguientes ventajas del uso de la vista de recursos de Kubernetes en entornos:

  • Rastreabilidad de canalización: la tarea de manifiesto de Kubernetes, que se usa para las implementaciones, agrega más anotaciones para mostrar la rastreabilidad de la canalización en la vista de recursos. La rastreabilidad de canalizaciones ayuda a identificar la organización, el proyecto y la canalización de Azure DevOps de origen responsables de las actualizaciones realizadas en un objeto dentro del espacio de nombres.

    Pipeline traceability

  • Diagnóstico del estado de los recursos: el estado de la carga de trabajo puede ser útil para depurar rápidamente errores o regresiones que podría haber introducido una nueva implementación. Por ejemplo, en el caso de imagePullSecrets no configurados que dan lugar a errores imagePullBackOff, la información de estado del pod puede ayudarle a identificar la causa principal del problema.

    ImagePullBackOff

  • Review App: Review App funciona mediante la implementación de todas las solicitudes de incorporación de cambios del repositorio de Git en un recurso dinámico de Kubernetes en el entorno. Los revisores pueden ver cómo se ven esos cambios y cómo funcionan con otros servicios dependientes antes de combinarlos en la rama de destino e implementarlos en producción.

Uso de Azure Kubernetes Service

Se crea una ServiceAccount en el clúster y el espacio de nombres elegidos al usar Azure Kubernetes Service (AKS). En el caso de un clúster habilitado para RBAC de Kubernetes, RoleBinding también se crea para limitar el ámbito de la cuenta de servicio creada al espacio de nombres elegido. En el caso de un clúster deshabilitado por RBAC de Kubernetes, la ServiceAccount creada tiene privilegios en todo el clúster (en todos los espacios de nombres).

Adición de un recurso de Kubernetes de AKS

  1. En la página de detalles del entorno, seleccione Agregar recurso y elija Kubernetes.

  2. Seleccione Azure Kubernetes Service en la lista desplegable Proveedor.

  3. Elija la suscripción, el clúster y el espacio de nombres de Azure (nuevo o existente).

  4. Seleccione Validar y crear para crear el recurso de Kubernetes.

  5. Compruebe que ve un clúster para su entorno. Verá el texto "Nunca implementado" si aún no ha implementado código en el clúster.

    Add a Kubernetes cluster.

Usar una cuenta de servicio existente

El Azure Kubernetes Service asigna un recurso Kubernetes de su entorno a un espacio de nombres.

Para obtener más información sobre cómo configurar una conexión de servicio de Kubernetes fuera de un entorno, consulte la sección Conexión de servicio de Kubernetes en Conexiones de servicio.

Sugerencia

Use el proveedor genérico (cuenta de servicio existente) para asignar un recurso de Kubernetes a un espacio de nombres desde un clúster que no es de AKS.

Adición de un recurso de Kubernetes que no es de AKS

  1. En la página de detalles del entorno, seleccione Agregar recurso y elija Kubernetes.

  2. Seleccione Proveedor genérico (cuenta de servicio existente) para el proveedor.

  3. Agregue los valores de nombre y espacio de nombres del clúster.

  4. Agregue la dirección URL del servidor. Puede obtener la dirección URL con el siguiente comando:

    kubectl config view --minify -o 'jsonpath={.clusters[0].cluster.server}'
    
  5. Para obtener el objeto secreto.

    Kubernetes 1.22+

    Reemplace service-account-name por su propio nombre de cuenta.

    kubectl get secret -n <namespace>  -o jsonpath='{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name==\"service-account-name\")]}'
    

    Si no obtiene nada, consulte Creación manual de un token de API de larga duración para ServiceAccount.

    Kubernetes 1.22 y versiones posteriores:

    1. Búsqueda del nombre del secreto de la cuenta de servicio
    kubectl get serviceAccounts <service-account-name> -n <namespace> -o 'jsonpath={.secrets[*].name}'
    
    1. reemplazar <service-account-secret-name> con el valor en el comando anterior en este comando
    kubectl get secret <service-account-secret-name> -n <namespace> -o json
    
  6. Obtenga el objeto secreto mediante la salida del paso anterior.

    kubectl get secret <service-account-secret-name> -n <namespace> -o json
    
  7. Copie y pegue el objeto Secret capturado en formato JSON en el campo de texto "Secreto".

  8. Seleccione Validar y crear para crear el recurso de Kubernetes.

Referencia a los recursos de Kubernetes en una canalización

Si usa Azure Kubernetes Service y crea una canalización YAML, la manera más fácil de configurar la canalización es usar una plantilla. Conéctese al repositorio y seleccione una de las dos opciones siguientes de Kubernetes Service:

Las plantillas le permiten configurar Review App sin necesidad de escribir código YAML desde cero o crear manualmente enlaces de roles explícitos.

Kubernetes template options.

Configuración de Review App

En el siguiente ejemplo, el primer trabajo de implementación se ejecuta para ramas que no son de PR y realiza implementaciones en un recurso normal de Kubernetes en entornos. El segundo trabajo solo se ejecuta para las ramas de PR y se implementa en los recursos de Review App (espacios de nombres dentro del clúster de Kubernetes) generados a petición. Los recursos se etiquetan con "Revisar" en la vista de lista de recursos del entorno. Defina las variables que se van a usar en la canalización. Si usa la plantilla Implementar en Azure Kubernetes Services, estas variables se definen por usted.

# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service
trigger:
- main

resources:
- repo: self

variables:

  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: '12345' # Docker service connection identifier
  envName: 'myEnv' # name of your environment
  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: 
      name: $(envName).$(resourceName)
      resourceType: Kubernetes 
    strategy:
      runOnce:
        deploy:
          steps:
          - task: KubernetesManifest@0
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@0
            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: 
      name: $(envName).$(resourceName)
      resourceType: Kubernetes
    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@0
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              namespace: $(k8sNamespaceForPR)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@0
            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}'

          # Getting 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.<br><br>[Learn More](https://aka.ms/testwithreviewapps) about how to test and provide feedback for the app."
              fi
              echo "##vso[task.setvariable variable=GITHUB_COMMENT]$message"

Para usar este trabajo en una canalización existente, la conexión de servicio que respalda el recurso de entorno normal de Kubernetes debe modificarse a "Usar credenciales de administrador de clúster". De lo contrario, se deben crear enlaces de rol para la cuenta de servicio subyacente en el espacio de nombres de Review App.

Pasos siguientes