Cómo crear una canalización de CI/CD con Azure Pipelines y Google Kubernetes Engine

En este instructivo, aprenderás cómo utilizar Azure Pipelines (anteriormente llamado Visual Studio Team Services), Google Kubernetes Engine (GKE) y Container Registry a fin de crear una canalización de integración continua/implementación continua (CI/CD). El instructivo utiliza la aplicación web ASP.NET MusicStore basada en ASP.NET Core.

La canalización CI/CD utiliza dos clústeres de GKE separados, uno para las pruebas y otro para la producción. Al comienzo de la canalización, los desarrolladores confirman cambios en la base de código de ejemplo. Esta acción activa la canalización para crear una nueva versión y para implementarla en el clúster de desarrollo. Un administrador de versión puede promover la versión a fin de que se implemente en el clúster de producción. En el siguiente diagrama, se ilustra este proceso.

Diagrama conceptual de la canalización de CI/CD en el que se muestra cómo los desarrolladores y los usuarios finales interactúan con la aplicación

En el instructivo, se da por sentado que tienes conocimientos básicos de NET Core, Azure Pipelines y GKE. Además, el instructivo requiere que cuentes con acceso administrativo a una cuenta de Azure DevOps y a una instalación de Visual Studio 2017 que ya esté conectada con tu cuenta de Azure DevOps.

Objetivos

  • Conectar Container Registry con Azure Pipelines para publicar imágenes de Docker
  • Preparar una aplicación de muestra de .NET Core para su implementación en GKE
  • Autenticar de forma segura en GKE sin tener que utilizar la autenticación heredada
  • Utilizar la administración de versiones de Azure Pipelines para organizar las implementaciones de GKE

Costos

En este instructivo, se utilizan componentes facturables de Google Cloud Platform, incluidos los siguientes:

Usa la Calculadora de precios para generar una estimación de los costos según el uso previsto. Consulta la página de precios de Azure DevOps para conocer las tarifas que podrían aplicarse al uso de Azure DevOps.

Antes de comenzar

Por lo general, se recomienda utilizar proyectos separados para las cargas de trabajo de desarrollo y producción, a fin de que las funciones y los permisos de administración de identidades y accesos (IAM) se puedan conceder de forma individual. A los fines de la simplicidad, este instructivo utiliza un solo proyecto para ambos clústeres de GKE: uno para desarrollo y otro para producción.

  1. Select or create a Google Cloud Platform project.

    Go to the Manage resources page

  2. Comprueba que la facturación esté habilitada en tu proyecto.

    Descubre cómo puedes habilitar la facturación

  3. Asegúrate de tener una cuenta de Azure DevOps y de contar con acceso de administrador. Si todavía no tienes una cuenta de Azure DevOps, puedes registrarte en la página principal de Azure DevOps.
  4. Asegúrate de haber instalado Visual Studio 2017 y de que esté conectado con la cuenta de Azure DevOps.

Cómo crear un proyecto de Azure DevOps

Azure DevOps se utiliza para administrar el código fuente, ejecutar compilaciones y pruebas, y organizar la implementación en GKE. Para comenzar, crea un nuevo proyecto en tu cuenta de Azure DevOps.

  1. Ve a la página principal de Azure DevOps (https://dev.azure.com/[YOUR_AZURE_DEVOPS_ACCOUNT_NAME]).
  2. Haz clic en Crear proyecto.
  3. Ingresa un nombre de proyecto, como Music Store.
  4. Configura la Visibilidad como Privada y, a continuación, haz clic en Crear.
  5. Una vez que el proyecto se haya creado, en el menú de la izquierda, haz clic en Repositorios.
  6. Haz clic en Importar para bifurcar el repositorio de Orchard CMS de GitHub. Configura los siguientes valores:

    • Source type (Tipo de fuente): Git
    • Clone URL (URL de clonación): https://github.com/aspnet/MusicStore.git
    • La casilla de verificación Requires authorization (Requiere autorización) no debe quedar seleccionada.

    Captura de pantalla del cuadro de diálogo "Importar un repositorio de Git"

  7. Haz clic en Import (Importar).

    Una vez completado el proceso de importación, verás el código fuente de la aplicación MusicStore.

Cómo hacer compilaciones continuas

Ahora puedes utilizar Azure Pipelines para configurar integraciones continuas. Para cada confirmación que se envía al repositorio de Git, Azure Pipelines compila el código y empaqueta los artefactos de la compilación en un contenedor de Docker. Luego, el contenedor se publica en Container Registry.

Crear una rama de prueba

Para garantizar que las instrucciones de este instructivo funcionen, crea una rama del código basada en una versión específica del código fuente. (De esta forma, garantizas que cambios futuros en el código de GitHub no generen fallas en este instructivo).

  1. En el menú de Azure DevOps, selecciona Repositorios > Etiquetas.
  2. En la lista de etiquetas, expande rel y, luego, haz clic derecho en 2.0.0.
  3. Selecciona Nueva rama.
  4. Ingresa testing como nombre de la rama y, luego, haz clic en Create branch (Crear rama) para confirmar tus selecciones.

    Captura de pantalla del cuadro de diálogo "Crear una rama" en Azure Pipelines

Según la configuración predeterminada, Azure Pipelines espera que tu código resida en la rama master. A fin de que pueda utilizar la rama testing, debes cambiar la rama predeterminada.

  1. En el menú de Azure DevOps, selecciona Configuración del proyecto.
  2. Selecciona Código > Repositorios.
  3. En la lista de repositorios, selecciona el repositorio de Git que importaste anteriormente. Debería tener el mismo nombre que tu proyecto de Azure DevOps.
  4. Expande la lista de ramas; para ello, haz clic en la flecha que se encuentra junto a Ramas.
  5. Selecciona la rama de prueba.

    Aparecerá un botón junto al nombre de la rama.

  6. Haz clic en y selecciona Establecer como rama predeterminada.

Compilar el código

Una vez que has creado la rama, puedes comenzar a automatizar la compilación. Debido a que MusicStore es una aplicación de ASP.NET Core, la compilación incluye cuatro pasos:

  • Descargar y, luego, instalar dependencias
  • Compilar el código
  • Ejecutar pruebas de unidades
  • Publicar los resultados de la compilación

Más adelante, agregarás pasos adicionales para implementar en GKE. Debido a que GKE es un entorno basado en Linux, configurarás que todo el proceso de compilación se ejecute en agentes de compilación basados en Linux.

  1. En el menú de Azure DevOps, selecciona Canalizaciones > Compilaciones y, a continuación, Nuevas canalizaciones.
  2. Selecciona Repositorios de Azure como la ubicación del código.
  3. Selecciona el repositorio de Git que importaste anteriormente. Debería tener el mismo nombre que tu proyecto de Azure DevOps.
  4. Selecciona Canalización de inicio.
  5. Quita el código de ejemplo que se generó para azure-pipelines.yml y copia el siguiente código en el editor:

    resources:
    - repo: self
      fetchDepth: 1
    queue:
      name: Hosted Ubuntu 1604
    variables:
      TargetFramework: 'netcoreapp2.0'
      RestoreBuildProjects: 'samples/**/*.csproj'
      TestProjects: 'test/MusicStore.Test/*.csproj'
      BuildConfiguration: 'Release'
      DockerImageName: '[PROJECT-NAME]/musicstore'
    steps:
    - task: DotNetCoreCLI@2
      displayName: Restore
      inputs:
        command: restore
        projects: '$(RestoreBuildProjects)'
        feedsToUse: config
        nugetConfigPath: NuGet.config
    - task: DotNetCoreCLI@2
      displayName: Build
      inputs:
        projects: '$(RestoreBuildProjects)'
        arguments: '--configuration $(BuildConfiguration) --framework=$(TargetFramework)'
    - task: DotNetCoreCLI@2
      displayName: Test
      inputs:
        command: test
        projects: '$(TestProjects)'
        arguments: '--configuration $(BuildConfiguration) --framework=$(TargetFramework)'
    - task: DotNetCoreCLI@2
      displayName: Publish
      inputs:
        command: publish
        publishWebProjects: True
        arguments: '--configuration $(BuildConfiguration) --framework=$(TargetFramework)'
        zipAfterPublish: false
        modifyOutputPath: false
    
  6. En la selección variables, reemplaza [PROJECT_NAME] con el nombre de tu proyecto de GCP.

  7. Haz clic en Guardar y ejecutar.

  8. Si lo deseas, ingresa un mensaje de confirmación personalizado, y para confirmar, haz clic en Guardar y ejecutar.

    De esta manera, azure-pipelines.yml quedará confirmado en la rama testing de tu repositorio y activará una compilación. Cualquier cambio adicional en la definición de compilación deberá realizarse mediante una modificación en el archivo en el repositorio de Git.

Publicar imágenes de Docker

Para implementar la aplicación MusicStore en GKE, esta debe estar empaquetada como un contenedor de Docker y publicada en Container Registry. Ahora extenderás la definición de compilación a fin de automatizar estos pasos.

Configurar una cuenta de servicio para publicar imágenes

La conexión a Container Registry requiere que Azure Pipelines pueda autenticarse con GCP. Para poder hacerlo, crea una cuenta de servicio en GCP dedicada a este propósito.

  1. Cambia a tu proyecto en GCP Console y abre Cloud Shell.

    Abrir Cloud Shell

  2. Para ahorrar tiempo cuando escribes el ID del proyecto y las opciones de la zona de Compute Engine, establece los valores de configuración predeterminados; para ello, ejecuta los siguientes comandos:

    gcloud config set project [PROJECT_NAME]
    gcloud config set compute/zone [ZONE]

    Reemplaza [PROJECT_NAME] con el nombre de tu proyecto de GCP y reemplaza [ZONE] con el nombre de la zona que utilizarás para crear recursos. Si no sabes qué zona elegir, utiliza us-central1-a.

    Ejemplo:

    gcloud config set project azure-pipelines-test-project-12345
    gcloud config set compute/zone us-central1-a
  3. Habilita la API de Container Registry para tu proyecto:

    gcloud services enable containerregistry.googleapis.com
  4. Crea una cuenta de servicio para que Azure Pipelines publique las imágenes de Docker:

    gcloud iam service-accounts create azure-pipelines-publisher --display-name "Azure Pipelines Publisher"
  5. Asigna la función de IAM del Administrador de almacenamiento a la cuenta de servicio:

    PROJECT_NUMBER=$(gcloud projects describe \
        $(gcloud config get-value core/project) \
        --format='value(projectNumber)')
    
    AZURE_PIPELINES_PUBLISHER=$(gcloud iam service-accounts list \
        --filter="displayName:Azure Pipelines Publisher" \
        --format='value(email)')
    
    gcloud projects add-iam-policy-binding \
        $(gcloud config get-value core/project) \
        --member serviceAccount:$AZURE_PIPELINES_PUBLISHER \
        --role roles/storage.admin
    
  6. Genera una clave de cuenta de servicio:

    gcloud iam service-accounts keys create \
        azure-pipelines-publisher.json --iam-account $AZURE_PIPELINES_PUBLISHER
    tr -d '\n' < azure-pipelines-publisher.json > azure-pipelines-publisher-oneline.json
  7. Inicia Code Editor; para ello, haz clic en el botón que se encuentra en la esquina superior derecha de Cloud Shell:

    Captura de pantalla del ícono "Editor de código de lanzamiento" en la barra de menú de Cloud Shell

  8. Abre el archivo denominado azure-pipelines-publisher-oneline.json. Necesitarás el contenido de este archivo en uno de los próximos pasos.

Conecta Azure Pipelines a Container Registry

Una vez creada la cuenta de servicio, puedes conectar Azure Pipelines a Container Registry.

  1. En el menú de Azure DevOps, selecciona Configuración del proyecto y, a continuación, selecciona Canalizaciones > Conexiones de servicio.
  2. Haz clic en Nueva conexión de servicio.
  3. De la lista, selecciona Registro de Docker.
  4. En el diálogo, ingresa valores para los siguientes campos:

    • Nombre de la conexión: gcr-tutorial
    • Registro de Docker: https://gcr.io/[PROJECT-NAME], según el cual [PROJECT_NAME] es el nombre de tu proyecto de GCP.

      Ejemplo: https://gcr.io/azure-pipelines-test-project-12345

    • ID de Docker: _json_key

    • Contraseña: El contenido de azure-pipelines-publisher-oneline.json

  5. Haz clic en Aceptar para crear la conexión.

Explorar el proyecto en Visual Studio

A fin de crear un Dockerfile que defina el contenido de la imagen de Docker, primero debes exportar el código:

  1. En Visual Studio, abre Team Explorer.
  2. En el menú, haz clic en el ícono Administrar conexiones.
  3. Selecciona Manage Connections (Administrar conexiones) > Connect to a Project (Conectarse a un proyecto).

    Captura de pantalla de la opción "Conectar a un proyecto" en el panel de Team Explorer de Visual Studio

  4. En el siguiente cuadro de diálogo, selecciona el repositorio de Git Music Store y, a continuación, haz clic en Clone (Clonar).

    Captura de pantalla del repositorio de Git "Music Store" seleccionado en el cuadro de diálogo "Conectar a un proyecto" en Visual Studio

Crear un Dockerfile

Una vez que hayas exportado el código, puedes configurar el Dockerfile.

  1. En Visual Studio, abre Solution Explorer.
  2. En la raíz de la solución, crea un nuevo archivo denominado Dockerfile.
  3. Copia el siguiente código y pégalo en el archivo; a continuación, guarda el archivo:

    FROM microsoft/aspnetcore:2.0.0
    WORKDIR /app
    COPY samples/MusicStore/bin/Release/netcoreapp2.0/publish /app/
    ENTRYPOINT ["dotnet", "MusicStore.dll"]
  4. En la raíz de la solución, crea un nuevo archivo denominado deployment.yaml. Por ahora, deja el archivo vacío.

  5. Abre Team Explorer y haz clic en el ícono Página principal en la parte superior izquierda para cambiar la vista de la Página principal.

  6. Haz clic en Cambios.

  7. Ingresa un mensaje de confirmación, como Add Dockerfile and placeholder for the Kubernetes manifest.

  8. Haz clic en Confirmar todo.

Expandir la definición de compilación para compilar una imagen de Docker

Con todos los archivos necesarios ingresados, ahora puedes extender la definición de compilación.

  1. En Visual Studio, abre azure-pipelines.yml.
  2. Extiende la definición de compilación; para ello, agrega el siguiente fragmento de código al archivo:

    - task: CmdLine@1
      displayName: 'Lock image version in deployment.yaml'
      inputs:
        filename: /bin/bash
        arguments: '-c "awk ''{gsub(\"MUSICSTORE_IMAGE\", \"gcr.io/$(DockerImageName):$(Build.BuildId)\", $0); print}'' deployment.yaml > $(build.artifactstagingdirectory)/deployment.yaml"'
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
        PathtoPublish: '$(build.artifactstagingdirectory)'
    - task: Docker@0
      displayName: 'Build image'
      inputs:
        containerregistrytype: 'Container Registry'
        dockerRegistryConnection: 'gcr-tutorial'
        imageName: '$(DockerImageName):$(Build.BuildId)'
    - task: Docker@0
      displayName: 'Publish image'
      inputs:
        containerregistrytype: 'Container Registry'
        dockerRegistryConnection: 'gcr-tutorial'
        action: 'Push an image'
        imageName: '$(DockerImageName):$(Build.BuildId)'
    

Para confirmar y enviar los cambios a Azure DevOps, sigue estos pasos:

  1. En Visual Studio, abre Team Explorer.
  2. Haz clic en el ícono de Página principal en la parte superior izquierda para cambiar a la vista de Página principal.
  3. Haz clic en Cambios.
  4. Ingresa un mensaje de confirmación, como Extend build definition to build Docker image.
  5. Haz clic en Confirmar todo y enviar.
  6. En el menú de Azure DevOps, selecciona Canalizaciones > Compilar.

    Nota que se ha activado automáticamente una nueva compilación. La compilación podría tardar cerca de dos minutos en completarse.

    Si ocurre un problema con la compilación y se muestra el mensaje de error Step input dockerRegistryConnection references service connection gcr-tutorial which could not be found, podrías tener que volver a guardar tu canalización.

  7. A fin de verificar que la imagen se haya publicado en Container Registry, cambia a GCP Console, selecciona Container Registry > Imágenes y, a continuación, haz clic en musicstore.

    Nota que hay una sola imagen y que la etiqueta de esta imagen se corresponde con el ID numérico de la compilación ejecutada en Azure Pipelines.

    Captura de pantalla de la lista de imágenes en Container Registry

Cómo hacer implementaciones continuas

Gracias a que Azure Pipelines compila automáticamente tu código y publica las imágenes de Docker para cada confirmación, ahora puedes enfocarte en tu implementación.

A diferencia de otros sistemas de integración continua, Azure Pipelines distingue entre implementación y compilación, y brinda un conjunto de herramientas especializadas etiquetadas como Administración de versiones para todas las tareas relacionadas con la implementación.

La Administración de versiones de Azure Pipelines se basa en los siguientes conceptos:

  • Una versión hace referencia a un conjunto de artefactos que componen una versión específica de tu aplicación y que, por lo general, son el resultado de un proceso de compilación.
  • La implementación se refiere al proceso de tomar una versión y, luego, implementarla en un entorno específico.
  • Una implementación realiza un conjunto de tareas, que se pueden agrupar en trabajos.
  • Las etapas permiten que segmentes tu canalización, y se las puede utilizar para organizar implementaciones en entornos múltiples, por ejemplo, entornos de desarrollo y pruebas.

El artefacto principal que produce el proceso de compilación de MusicStore es la imagen de Docker. Sin embargo, debido a que la imagen de Docker se publica en Container Registry, la imagen está fuera del alcance de Azure Pipelines. Por ende, la imagen no funciona bien como definición de una versión.

Para implementar en Kubernetes, también necesitas un manifiesto, que se parece a una factura de materiales. El manifiesto no solamente define los recursos que se supone que Kubernetes creará y administrará, sino que, además, especifica la versión exacta de la imagen de Docker que se utilizará. El manifiesto de Kubernetes es adecuado para funcionar como el artefacto que define la versión en la Administración de versiones de Azure Pipelines.

Cómo configurar la implementación de Kubernetes

Para ejecutar MusicStore en Kubernetes, necesitarás los siguientes recursos:

  • Una implementación que defina un solo pod que ejecute la imagen de Docker producida por la compilación
  • Un servicio NodePort que vuelve al pod accesible para el balanceador de cargas
  • Un Ingress que exponga la aplicación a la Internet pública mediante un balanceador de cargas Cloud HTTP(S)

Con la aplicación MusicStore, puedes utilizar tanto SQL Server como una base de datos incorporada y almacenada localmente. En pos de la simplicidad, utiliza la configuración predeterminada que depende de la base de datos incorporada, aunque tiene dos restricciones:

  • Solo se puede ejecutar una copia del pod a la vez. De lo contrario, los usuarios podrían ver datos diferentes según el pod que les entregue.
  • Cualquier cambio en los datos se pierde cuando se reinicia el pod, a menos que modifiques la implementación para que use volúmenes persistentes. (No trataremos este caso en el instructivo).

Para definir estos recursos de Kubernetes, realiza los siguientes pasos:

  1. En Visual Studio, abre Solution Explorer.
  2. Abre deployment.yaml y pega el siguiente código; a continuación, guarda el archivo:

    apiVersion: v1
    kind: Service
    metadata:
      name: musicstore
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
        name: http
      selector:
        app: musicstore
      type: NodePort
    
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: musicstore
    spec:
      backend:
        serviceName: musicstore
        servicePort: 80
    
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: musicstore
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: musicstore
        spec:
          containers:
          - name: musicstore
            image: MUSICSTORE_IMAGE
            ports:
              - containerPort: 80
            livenessProbe:      # Used by deployment controller
              httpGet:
                path: /
                port: 80
              initialDelaySeconds: 5
              periodSeconds: 5
            readinessProbe:     # Used by Ingress/GCLB
              httpGet:
                path: /
                port: 80
              initialDelaySeconds: 3
              periodSeconds: 5
            resources:
              limits:
                memory: 1024Mi
              requests:
                memory: 768Mi
    
  3. Abre Team Explorer y cambia a la vista de Página principal.

  4. Haz clic en Cambios.

  5. Ingresa un mensaje de confirmación, como Add Kubernetes manifest.

  6. Haz clic en Confirmar todo y enviar.

Cómo configurar los entornos de desarrollo y producción

Antes de volver a la Administración de versiones de Azure Pipelines, deberás crear el clúster de GKE.

Cómo crear clústeres de GKE

  1. En GCP, abre una instancia de Cloud Shell.
  2. A fin de ahorrar tiempo cuando escribes el ID del proyecto y las opciones de la zona de Compute Engine, establece los valores de configuración predeterminados; para ello, ejecuta los siguientes comandos:

    gcloud config set project [PROJECT_NAME]
    gcloud config set compute/zone [ZONE]

    Ejemplo:

    gcloud config set project azure-pipelines-test-project-12345
    gcloud config set compute/zone us-central1-a
  3. Habilita la API de GKE para tu proyecto:

    gcloud services enable container.googleapis.com
  4. Crea el clúster de desarrollo; para ello, utiliza el siguiente comando. Ten en cuenta que puede tardar unos minutos en completarse:

    gcloud container clusters create azure-pipelines-cicd-dev
  5. Crea el clúster de producción mediante el siguiente comando. Ten en cuenta que puede tardar unos minutos en completarse:

    gcloud container clusters create azure-pipelines-cicd-prod

Cómo conectar Azure Pipelines con el clúster de desarrollo

Así como puedes utilizar Azure Pipelines para conectarte con un registro externo de Docker, como Container Registry, Azure Pipelines admite la integración de clústeres de Kubernetes externos.

Es posible la autenticación con Container Registry mediante una cuenta de servicio de GCP; no obstante, el uso de cuentas de servicios de GCP no es compatible con Azure Pipelines para la autenticación con GKE. En su lugar, debes utilizar una cuenta de servicios de Kubernetes.

Para conectar Azure Pipelines a tu clúster de desarrollo, debes crear una cuenta de servicio de Kubernetes primero.

  1. En Cloud Shell, conéctate al clúster de desarrollo:

    gcloud container clusters get-credentials azure-pipelines-cicd-dev
  2. Crea una cuenta de servicio de Kubernetes para Azure Pipelines:

    kubectl create serviceaccount azure-pipelines-deploy
  3. Asigna la función cluster-admin a la cuenta de servicio; para ello, crea una función de clúster que vincule lo siguiente:

    kubectl create clusterrolebinding azure-pipelines-deploy --clusterrole=cluster-admin --serviceaccount=default:azure-pipelines-deploy
  4. Define la dirección IP del clúster:

    gcloud container clusters describe azure-pipelines-cicd-dev --format=value\(endpoint\)
    

    Necesitarás esta dirección en un momento.

  5. En el menú de Azure DevOps, selecciona Configuración del proyecto y, a continuación, selecciona Canalizaciones > Conexiones de servicio.

  6. Haz clic en Nueva conexión de servicio y selecciona Kubernetes.

  7. Establece la siguiente configuración:

    • Seleccionar autenticación: Cuenta de servicio.
    • Nombre de la conexión: azure-pipelines-cicd-dev.
    • URL del servidor: https://[MASTER-IP]/. Remplaza [MASTER-IP] con la dirección IP que determinaste anteriormente.
    • Token: Ejecuta el siguiente comando en Cloud Shell y copia el resultado:
      kubectl get secret $(kubectl get secret -o custom-columns=":metadata.name" | grep azure-pipelines-deploy-) -o jsonpath="{.data.token}{'\n'}"
    • Certificado: Ejecuta el siguiente comando en Cloud Shell y copia el resultado:
      kubectl get secret $(kubectl get secret -o custom-columns=":metadata.name" | grep azure-pipelines-deploy-) -o jsonpath="{.data['ca\.crt']}{'\n'}"
  8. Haz clic en Aceptar.

Cómo conectar Azure Pipelines al clúster de producción

Para conectar Azure Pipelines a tu clúster de producción, puedes seguir el mismo enfoque.

  1. En Cloud Shell, conéctate al clúster de producción:

    gcloud container clusters get-credentials azure-pipelines-cicd-prod
  2. Crea una cuenta de servicio de Kubernetes para Azure Pipelines:

    kubectl create serviceaccount azure-pipelines-deploy
  3. Asigna la función cluster-admin a la cuenta de servicio; para ello, crea una función de clúster que vincule lo siguiente:

    kubectl create clusterrolebinding azure-pipelines-deploy --clusterrole=cluster-admin --serviceaccount=default:azure-pipelines-deploy
  4. Define la dirección IP del clúster:

    gcloud container clusters describe azure-pipelines-cicd-prod --format=value\(endpoint\)
    

    Necesitarás esta dirección en un momento.

  5. En el menú de Azure DevOps, selecciona Configuración del proyecto y, a continuación, selecciona Canalizaciones > Conexiones de servicio.

  6. Haz clic en Nueva conexión de servicio y selecciona Kubernetes.

  7. Establece la siguiente configuración:

    • Seleccionar autenticación: Cuenta de servicio.
    • Nombre de la conexión: azure-pipelines-cicd-prod.
    • URL del servidor: https://[MASTER-IP]/. Remplaza [MASTER-IP] con la dirección IP que determinaste anteriormente.
    • Token: Ejecuta el siguiente comando en Cloud Shell y copia el resultado:
      kubectl get secret $(kubectl get secret -o custom-columns=":metadata.name" | grep azure-pipelines-deploy-) -o jsonpath="{.data.token}{'\n'}"
    • Certificado: Ejecuta el siguiente comando en Cloud Shell y copia el resultado:
      kubectl get secret $(kubectl get secret -o custom-columns=":metadata.name" | grep azure-pipelines-deploy-) -o jsonpath="{.data['ca\.crt']}{'\n'}"
  8. Haz clic en Aceptar.

Cómo configurar la canalización de la versión

Una vez configurada la infraestructura de GKE, vuelve a Azure Pipelines a fin de automatizar la implementación, que incluye las siguientes acciones:

  • Implementar en el entorno de desarrollo
  • Solicitar aprobación manual antes de iniciar una implementación en el entorno de producción
  • Implementar en el entorno de producción

Cómo crear una definición de la versión

Como primer paso, crea una nueva definición de la versión.

  1. En el menú de Azure DevOps, selecciona Canalizaciones > Versiones.
  2. Haz clic en Nueva canalización.
  3. Desde la lista de plantillas, selecciona Vaciar trabajo.
  4. Cuando se te solicite un nombre para la etapa, ingresa Dev.
  5. En la parte superior de la pantalla, nombra la versión MusicStore-KubernetesEngine.
  6. En el diagrama de la canalización, junto a Artefactos, haz clic en Agregar.
  7. Selecciona Compilar y agrega la siguiente configuración:

    • Fuente: Selecciona el repositorio de Git que contiene el archivo azure-pipelines.yml.
    • Versión predeterminada: Latest
    • Alias de fuente: manifest
  8. Haz clic en Agregar.

  9. En el cuadro Artefacto, haz clic en el ícono del rayo para agregar un activador de implementación.

  10. En Activador de implementación continua, establece la opción como Habilitado.

  11. Haz clic en Guardar.

  12. Si lo deseas, ingresa un comentario y, luego, haz clic en Guardar para confirmarlo.

La canalización ahora se ve de la siguiente manera:

Captura de pantalla de la canalización actualizada en Azure Pipelines

Cómo implementar en el clúster de desarrollo

Tras haber creado la definición de la versión, ahora puedes configurar la implementación en el clúster de desarrollo de GKE.

  1. En el menú de la canalización, pasa a la pestaña Tareas.
  2. Haz clic en Trabajo de agente.
  3. Cambia el grupo de agentes a Hosted Ubuntu 1604.
  4. Junto a Trabajo de agente, haz clic en el ícono + para agregar un paso a la fase.
  5. Selecciona la tarea Implementar en Kuberetes y haz clic en Agregar.
  6. Haz clic en la tarea recién agregada y establece la siguiente configuración:

    • Nombre visible: Deploy
    • Tipo de conexión de servicio: Kubernetes Service Connection
    • Conexión de servicio de Kubernetes: azure-pipelines-cicd-dev
    • Comando: apply
    • Uso de archivos de configuración: Habilitado
    • Archivo de configuración: manifest/drop/deployment.yaml
  7. Haz clic en Guardar.

  8. Si lo deseas, ingresa un comentario y, luego, haz clic en Aceptar para confirmar.

Cómo implementar en el clúster de producción

Por último, configura la implementación en el clúster de producción de GKE.

  1. En el menú, pasa a la pestaña Canalización.
  2. En la casilla Etapas, selecciona Agregar > Nueva etapa.
  3. Desde la lista de plantillas, selecciona Vaciar trabajo.
  4. Cuando se te solicite un nombre para la etapa, ingresa Prod.
  5. Haz clic en el ícono el rayo de la etapa recién creada.
  6. Establece la siguiente configuración:

    • Seleccionar activador: After stage
    • Etapas: Dev
    • Aprobaciones previas a la implementación: (habilitado)
    • Aprobaciones: Selecciona tu nombre de usuario o grupo.

    La canalización ahora se ve de la siguiente manera:

    Captura de pantalla de la canalización actualizada en Azure Pipelines

  7. Pasa a la pestaña Tareas.

  8. Mantén el mouse sobre la pestaña Tareas y selecciona Tareas > Prod.

  9. Haz clic en Trabajo de agente.

  10. Cambia el grupo de agentes a Hosted Ubuntu 1604.

  11. Haz clic en el ícono + para agregar un paso a la fase.

  12. Selecciona la tarea Implementar en Kuberetes y haz clic en Agregar.

  13. Haz clic en la tarea recién agregada y establece la siguiente configuración:

    • Nombre visible: Deploy
    • Tipo de conexión de servicio: Kubernetes Service Connection
    • Conexión de servicio de Kubernetes: azure-pipelines-cicd-prod
    • Comando: apply
    • Uso de archivos de configuración: Habilitado
    • Archivo de configuración: manifest/drop/deployment.yaml
  14. Haz clic en Guardar.

  15. Si lo deseas, ingresa un comentario y, luego, haz clic en Aceptar para confirmar.

Cómo ejecutar la canalización

Ahora que ya configuraste toda la canalización, es momento de ponerla a prueba mediante un cambio en el código fuente.

  1. En Visual Studio, abre el archivo samples\MusicStore\config.json.
  2. En la línea 3, cambia la configuración SiteTitle a ASP.NET MVC Music Store running on Google Kubernetes Engine.
  3. Abre Team Explorer y cambia a la vista de Página principal.
  4. Haz clic en Cambios.
  5. Ingresa un mensaje de confirmación, como Change site title.
  6. Haz clic en Confirmar todo y enviar.
  7. En el menú de Azure DevOps, selecciona Compilación y versión > Compilaciones; observa que se activó automáticamente una compilación:

    Captura de pantalla en la que se muestra la lista de compilaciones en curso, con la compilación de Music Store en progreso

    Podría tardar cerca de dos minutos en que el estado cambie a Correcto.

  8. Cuando se termine la compilación, selecciona Pipelines (Canalizaciones) > Releases (Versiones); observa que se inició un proceso de actualización:

    Captura de pantalla en la que se muestra que el proceso de actualización ha comenzado

  9. Haz clic en Release-1 (Versión-1) para abrir la página de detalles y espera que el estado de la etapa Dev cambie a Correcto. Podrías tener que actualizar el estado; para ello, haz clic en el botón Actualizar en el menú, o vuelve a cargar al página del navegador.

  10. En GCP Console, selecciona Kubernetes Engine > Servicios.

  11. Ubica el servicio Ingress para el clúster azure-pipelines-cicd-dev y espera a que su estado cambie a Ok. Esto podría tardar varios minutos.

  12. Copia la URL del vínculo etiquetado como */* dentro de la misma fila y quita el asterisco final.

  13. Abre la URL en una nueva pestaña del navegador. Es posible que, al principio, te encuentres con un error debido a que el balanceador de cargas tarda unos minutos en estar disponible. Cuando esté listo, verás que Music Store se implementó y está usando el título personalizado:

    Captura de pantalla en la que se muestra la ejecución de la aplicación Music Store en una página del navegador

  14. En Azure Pipelines, Approve (Aprueba) la promoción de la implementación en el entorno de producción:

    Captura de pantalla en la que se muestra la página de actualizaciones y un mensaje "Una aprobación previa a la implementación está pendiente…Aprobar o rechazar"

    Si no ves una barra sombreada en amarillo, es posible que primero tengas que aprobar o rechazar una versión anterior.

  15. Si lo deseas, ingresa un comentario y, luego, haz clic en Approve (Aprobar) para confirmarlo.

  16. Espera a que el estado del entorno Prod cambie a Succeeded (Correcto). Es posible que tengas que actualizar manualmente la página en tu navegador.

  17. En GCP Console, actualiza la página Servicios.

  18. Ubica el servicio Ingress para el clúster azure-pipelines-cicd-prod y espera a que su estado cambie a Ok. Esto podría tardar varios minutos.

  19. Copia la URL del vínculo etiquetado como */* dentro de la misma fila y quita el asterisco final.

  20. Abre la URL en una nueva pestaña del navegador. Nuevamente, es posible que, al principio, te encuentres con un error debido a que el balanceador de cargas tarda unos minutos en estar disponible. Cuando esté listo, verás la aplicación MusicStore con el título personalizado nuevamente; esta vez, se estará ejecutando en el clúster de producción.

Limpieza

A fin de evitar incurrir en costos adicionales una vez que hayas completado este instructivo, borra las entidades que has creado.

Borrar el proyecto de Azure Pipelines

Borra el proyecto en Azure Pipelines. Ten en cuenta que esto ocasionará también que todos los cambios realizados en el código fuente se pierdan.

Borrar el proyecto de GCP

  1. In the GCP Console, go to the Projects page.

    Go to the Projects page

  2. In the project list, select the project you want to delete and click Delete .
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

¿Qué sigue?

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...