Canalizaciones de entrega continua con Spinnaker y Google Kubernetes Engine

En este instructivo, se muestra cómo crear una canalización de entrega continua a través de Google Kubernetes Engine, Cloud Source Repositories, Cloud Build y Spinnaker. Una vez que creaste una aplicación de muestra, debes configurar estos servicios para compilarla, probarla y, luego, implementarla automáticamente. Cuando modificas el código de la aplicación, los cambios activan la canalización de entrega continua para que la nueva versión se vuelva a compilar, a probar y a implementar de forma automática.

Arquitectura de la canalización

arquitectura de la canalización

A fin de brindar una entrega continua de actualizaciones de la aplicación a tus usuarios, necesitas un proceso automatizado que compile, pruebe y actualice tu software de forma confiable. Los cambios de código deberían transmitirse automáticamente a través de una canalización que incluya la creación de artefactos, pruebas de unidades, pruebas funcionales y puesta en funcionamiento en producción. En algunos casos, querrás que una actualización de código se aplique solo a un subconjunto de tus usuarios, de modo que se emplee de forma realista antes de enviarla a la base de usuarios completa. Si uno de estos lanzamientos canary resulta insatisfactorio, tu proceso automatizado debe ser capaz de revertir rápidamente los cambios del software.

Con GKE y Spinnaker, puedes crear una transmisión de entrega sólida y constante que te ayude a asegurarte de que el software se entregue en cuanto se desarrolle y valide. A pesar de que tu objetivo final es la iteración rápida, primero debes asegurarte de que cada revisión de la aplicación pase por una serie de validaciones automatizadas antes de convertirse en candidata para la implementarse en producción. Si un cambio determinado fue aprobado automáticamente, también puedes validar la aplicación de forma manual y realizar más pruebas previas al lanzamiento.

Una vez que tu equipo decida que la aplicación está lista para producción, un miembro del equipo puede aprobar su implementación en producción.

Canalización de entrega de aplicaciones

En este instructivo, compilarás la canalización de entrega continua que se muestra en el siguiente diagrama.

Canalización de entrega de aplicaciones

Objetivos

  • Iniciar Cloud Shell, crear un clúster de GKE y configurar tu identidad y el esquema de administración de usuarios para configurar tu entorno
  • Descargar una aplicación de muestra, crear un repositorio de Git y subirlo a Cloud Source Repositories
  • Implementar Spinnaker en GKE a través de Helm
  • Crear una imagen de Docker
  • Generar activadores para crear imágenes de Docker cada vez que tu aplicación sufra cambios
  • Configurar una canalización de Spinnaker para implementar tu aplicación en GKE de forma confiable y continua
  • Implementar un cambio de código que active la canalización y mirar cómo se pone en funcionamiento en producción

Costos

En este instructivo, se usan componentes facturables de Google Cloud Platform (GCP), incluidos los siguientes:

  • GKE
  • Cloud Load Balancing
  • Cloud Build

Utiliza la calculadora de precios para generar una estimación de los costos según el uso previsto.

Los usuarios nuevos de GCP pueden ser aptos para una prueba gratuita.

Antes de comenzar

  1. Accede a tu Cuenta de Google.

    Si todavía no tienes una cuenta, regístrate para obtener una nueva.

  2. Selecciona o crea un proyecto de GCP.

    Ir a la página Administrar recursos

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

    Descubre cómo puedes habilitar la facturación

  4. Habilita las GKE, Cloud Build y Cloud Source Repositories API necesarias.

    Habilita las API

Configura tu entorno

En esta sección, configurarás la infraestructura y las identidades requeridas para completar este instructivo.

Inicia una instancia de Cloud Shell y crea un clúster de GKE

Ejecuta todos los comandos de terminal en este instructivo desde Cloud Shell.

  1. Abre Cloud Shell:

    ABRIR Cloud Shell

  2. Crea un clúster de GKE para implementar Spinnaker y la aplicación de muestra con los siguientes comandos.

    gcloud config set compute/zone us-central1-f
    
    gcloud container clusters create spinnaker-tutorial \
        --machine-type=n1-standard-2
    

Configura la administración de identidades y accesos

Debes crear una cuenta de servicio de administración de identidades y accesos de Cloud (Cloud IAM) para delegarle permisos a Spinnaker y, así, permitirle almacenar datos en Cloud Storage. Spinnaker almacena los datos de la canalización en Cloud Storage para garantizar su confiabilidad y resiliencia. Si tu implementación de Spinnaker falla inesperadamente, puedes crear una implementación idéntica en pocos minutos que cuente con acceso a los mismos datos de canalización que la original.

  1. Crea la cuenta de servicio:

    gcloud iam service-accounts create  spinnaker-account \
        --display-name spinnaker-account
    
  2. Almacena la dirección de correo electrónico de la cuenta de servicio y su ID del proyecto actual en variables del entorno para utilizarlas en comandos posteriores:

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:spinnaker-account" \
        --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')
    
  3. Vincula la función storage.admin a tu cuenta de servicio:

    gcloud projects add-iam-policy-binding \
        $PROJECT --role roles/storage.admin --member serviceAccount:$SA_EMAIL
    
  4. Descarga la clave de la cuenta de servicio. Necesitarás esta clave más adelante para instalar Spinnaker y subir la clave a GKE.

    gcloud iam service-accounts keys create spinnaker-sa.json --iam-account $SA_EMAIL
    

Configura Cloud Pub/Sub para activar las canalizaciones de Spinnaker

  1. Crea el tema de Cloud Pub/Sub para las notificaciones desde Container Registry. Este comando puede mostrar el mensaje de error “El recurso ya existe en el proyecto”, lo que significa que el tema ya fue creado.

    gcloud beta pubsub topics create projects/$PROJECT/topics/gcr
    
  2. Crea una suscripción que Spinnaker pueda leer para recibir las notificaciones de las imágenes que se envíen.

    gcloud beta pubsub subscriptions create gcr-triggers \
        --topic projects/${PROJECT}/topics/gcr
    
  3. Otórgale permisos a la cuenta de servicio de Spinnaker para que lea desde la suscripción gcr-triggers.

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:spinnaker-account" \
        --format='value(email)')
    gcloud beta pubsub subscriptions add-iam-policy-binding gcr-triggers \
        --role roles/pubsub.subscriber --member serviceAccount:$SA_EMAIL
    

Cómo implementar Spinnaker con Helm

En esta sección, utilizarás Helm para implementar Spinnaker desde el repositorio de Charts. Helm es un administrador de paquetes que puedes utilizar para configurar y, luego, implementar aplicaciones de Kubernetes.

Instala Helm

  1. Descarga y, luego, instala el objeto binario de helm:

    wget https://storage.googleapis.com/kubernetes-helm/helm-v2.10.0-linux-amd64.tar.gz
    
  2. Descomprime el archivo en tu sistema local:

    tar zxfv helm-v2.10.0-linux-amd64.tar.gz
    
    cp linux-amd64/helm .
    
  3. Otorga a Tiller, el lado del servidor de Helm, la función de administrador de clústeres en tu clúster:

    kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
    kubectl create serviceaccount tiller --namespace kube-system
    kubectl create clusterrolebinding tiller-admin-binding --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
    
  4. Otórgale a Spinnaker la función de cluster-admin para que pueda implementar recursos a través de todos los espacios de nombres:

    kubectl create clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:default spinnaker-admin
    
  5. Inicializa Helm para instalar Tiller en tu clúster:

    ./helm init --service-account=tiller
    ./helm update
  6. Ejecuta el siguiente comando para asegurarte de que Helm esté bien instalado. Si Helm está correctamente instalado, v2.10.0 aparecerá para el cliente y el servidor.

    ./helm version
    Client: &version.Version{SemVer:"v2.10.0", GitCommit:"9ad53aac42165a5fadc6c87be0dea6b115f93090", GitTreeState:"clean"}
    Server: &version.Version{SemVer:"v2.10.0", GitCommit:"9ad53aac42165a5fadc6c87be0dea6b115f93090", GitTreeState:"clean"}
    

Configura Spinnaker

  1. Crea un depósito en el que Spinnaker almacene su configuración de canalización:

    export PROJECT=$(gcloud info \
        --format='value(config.project)')
    export BUCKET=$PROJECT-spinnaker-config
    gsutil mb -c regional -l us-central1 gs://$BUCKET
  2. Crea el archivo (spinnaker-config.yaml) y describe la configuración con la que Spinnaker debe instalarse:

    export SA_JSON=$(cat spinnaker-sa.json)
    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-spinnaker-config
    cat > spinnaker-config.yaml <<EOF
    gcs:
      enabled: true
      bucket: $BUCKET
      project: $PROJECT
      jsonKey: '$SA_JSON'
    
    dockerRegistries:
    - name: gcr
      address: https://gcr.io
      username: _json_key
      password: '$SA_JSON'
      email: 1234@5678.com
    
    # Disable minio as the default storage backend
    minio:
      enabled: false
    
    # Configure Spinnaker to enable GCP services
    halyard:
      spinnakerVersion: 1.10.2
      image:
        tag: 1.12.0
      additionalScripts:
        create: true
        data:
          enable_gcs_artifacts.sh: |-
            \$HAL_COMMAND config artifact gcs account add gcs-$PROJECT --json-path /opt/gcs/key.json
            \$HAL_COMMAND config artifact gcs enable
          enable_pubsub_triggers.sh: |-
            \$HAL_COMMAND config pubsub google enable
            \$HAL_COMMAND config pubsub google subscription add gcr-triggers \
              --subscription-name gcr-triggers \
              --json-path /opt/gcs/key.json \
              --project $PROJECT \
              --message-format GCR
    EOF
    

Implementa el gráfico de Spinnaker

  1. Utiliza la interfaz de línea de comandos de Helm para implementar el gráfico con tu conjunto de configuración. Este comando tarda entre cinco y diez minutos en completarse.

    ./helm install -n cd stable/spinnaker -f spinnaker-config.yaml --timeout 600 \
        --version 1.1.6 --wait
  2. Una vez que el comando se complete, ejecuta el siguiente comando para configurar la redirección de puertos hacia la IU de Spinnaker desde Cloud Shell:

    export DECK_POD=$(kubectl get pods --namespace default -l "cluster=spin-deck" \
        -o jsonpath="{.items[0].metadata.name}")
    kubectl port-forward --namespace default $DECK_POD 8080:9000 >> /dev/null &
    
  3. Para abrir la interfaz de usuario de Spinnaker, haz clic en Web Preview (Vista previa en la Web) en Cloud Shell y haz clic en Preview on port8080 (Vista previa en el puerto 8080).

    port8080

  4. Deberías ver la pantalla de bienvenida, seguida de la IU de Spinnaker:

    hello

    spinui

Compila la imagen de Docker

En esta sección, configurarás Cloud Build para detectar cambios en el código fuente de tu aplicación, compilar una imagen de Docker y publicarla a Container Registry.

Crea tu repositorio de código fuente

  1. En Cloud Shell, descarga el código fuente de muestra:

    wget https://gke-spinnaker.storage.googleapis.com/sample-app-v2.tgz
    
  2. Descomprime el código fuente:

    tar xzfv sample-app-v2.tgz
    
  3. Cambia al directorio del código fuente:

    cd sample-app
    
  4. Configura el nombre de usuario y la dirección de correo electrónico para tu confirmación de Git en este repositorio. Reemplaza [EMAIL_ADDRESS] por tu dirección de correo electrónico de Git y [USERNAME] por tu nombre de usuario de Git:

    git config --global user.email "[EMAIL_ADDRESS]"
    git config --global user.name "[USERNAME]"
    
  5. Realiza la confirmación inicial de tu repositorio de código fuente:

    git init
    git add .
    git commit -m "Initial commit"
    
  6. Crea un repositorio para alojar tu código:

    gcloud source repos create sample-app
    git config credential.helper gcloud.sh
    
  7. Agrega tu nuevo repositorio como remoto:

    export PROJECT=$(gcloud info --format='value(config.project)')
    git remote add origin https://source.developers.google.com/p/$PROJECT/r/sample-app
    
  8. Envía tu código a la rama principal del nuevo repositorio:

    git push origin master
  9. Verifica que se vea el código fuente en la consola:

    IR A LA PÁGINA DEL CÓDIGO FUENTE

Configura el activador de compilación

En esta sección, configurarás Cloud Build para compilar y enviar tus imágenes de Docker cada vez que envíes las etiquetas de Git a tu repositorio de código fuente. Cloud Build verifica tu código fuente, compila la imagen de Docker desde Dockerfile en tu repositorio y extrae esa imagen a Container Registry de forma automática.

Flujo de trabajo de Spinnaker

  1. En GCP Console, ve a la sección de Cloud Build y haz clic en Activadores de compilación.

    IR A LA PÁGINA DE ACTIVADORES DE COMPILACIÓN

  2. Selecciona Cloud Source Repository y haz clic en Continuar.

  3. Selecciona tu repositorio sample-app recién creado desde la lista y haz clic en Continuar.

  4. Establece la siguiente configuración de activación:

    • Name (Nombre): sample-app-tags
    • Trigger Type (Tipo de activador): Tag
    • Tad (regex) (Etiqueta [regex]): v.*
    • Build configuration (Configuración de la compilación): cloudbuild.yaml
    • cloudbuild.yaml location (Ubicación de cloudbuild.yaml): cloudbuild.yaml
  5. Haz clic en Create trigger (Crear activador).

    Crea un activador

De ahora en más, cada vez que envíes una etiqueta de Git con la letra “v” como prefijo hacia tu repositorio de código fuente, Cloud Build compilará y enviará tu aplicación de forma automática como una imagen de Docker hacia Container Registry.

Prepara tus manifiestos de Kubernetes para utilizar en Spinnaker

Spinnaker requiere contar con acceso a tus manifiestos de Kubernetes para implementarlos en tus clústeres. En esta sección, se crea un depósito de Cloud Storage al que se propagarán los manifiestos durante el proceso de IC en Cloud Build. Una vez que tus manifiestos se encuentran en Cloud Storage, Spinnaker puede descargarlos y aplicarlos durante la ejecución de tu canalización.

  1. Crea un depósito.

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb -l us-central1 gs://$PROJECT-kubernetes-manifests
    
  2. Habilita el control de versiones en el depósito para tener un historial de tus manifiestos.

    gsutil versioning set on gs://$PROJECT-kubernetes-manifests
    
  3. Configura el ID del proyecto correcto en tus manifiestos de implementación de kubernetes:

    sed -i s/PROJECT/$PROJECT/g k8s/deployments/*
    
  4. Confirma los cambios en el repositorio:

    git commit -a -m "Set project ID"
    

Compila tu imagen

Envía tu primera imagen con los siguientes pasos:

  1. Ve a tu carpeta de código fuente en Cloud Shell.
  2. Crea una etiqueta de Git:

    git tag v1.0.0
  3. Envía la etiqueta:

    git push --tags
  4. En Cloud Build, haz clic en Build History (Historial de compilaciones) para comprobar que la compilación se haya activado. De no ser así, verifica que el activador se haya configurado de forma correcta en la sección anterior.

    IR AL HISTORIAL DE COMPILACIONES

    historial de compilaciones

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

Una vez que tus imágenes se hayan compilado automáticamente, debes implementarlas en el clúster de Kubernetes.

Debes implementarlas en un entorno de escala reducida para realizar pruebas de integración. Una vez superadas las pruebas de integración, debes aprobar los cambios de forma manual para implementar el código en los servicios de producción.

configura la canalización de la implementación

Instala el spin de CLI para administrar Spinnaker

spin es una utilidad de línea de comandos que sirve para administrar las aplicaciones y canalizaciones de Spinnaker.

  1. Descarga la última versión de spin.

    curl -LO https://storage.googleapis.com/spinnaker-artifacts/spin/$(curl -s https://storage.googleapis.com/spinnaker-artifacts/spin/latest)/linux/amd64/spin
    
  2. Haz que spin sea ejecutable.

    chmod +x spin
    

Crea la canalización de implementación

  1. Utiliza spin para crear una aplicación en Spinnaker.

    ./spin application save --application-name sample \
                            --owner-email example@example.com \
                            --cloud-providers kubernetes \
                            --gate-endpoint http://localhost:8080/gate
    

A continuación, crea la canalización de entrega continua. En este instructivo, la canalización se configura para detectar el momento en que llega una imagen de Docker con una etiqueta con el prefijo “v” a tu Container Registry.

  1. En una pestaña nueva de Cloud Shell, ejecuta el siguiente comando en el directorio del código fuente para subir una canalización de muestra a tu instancia de Spinnaker:

    export PROJECT=$(gcloud info --format='value(config.project)')
    sed s/PROJECT/$PROJECT/g spinnaker/pipeline-deploy.json > pipeline.json
    ./spin pipeline save --gate-endpoint http://localhost:8080/gate -f pipeline.json
    

Visualiza la ejecución de tu canalización

La configuración que acabas de crear utiliza las notificaciones de las imágenes recién etiquetadas que se envían con el fin de activar una canalización de Spinnaker. En uno de los pasos anteriores, se envió una etiqueta hacia Cloud Source Repositories que hizo que Cloud Build compilara y enviara tu imagen a Container Registry. Ahora puedes verificar la canalización que se activó.

  1. Haz clic en Canalizaciones para regresar a la página de canalizaciones.

  2. Haz clic en Detalles para ver más información sobre el progreso de la canalización. En esta sección, se muestra el estado de la canalización de implementación y sus pasos. Los pasos en color azul son los que se encuentran en ejecución; los verdes se completaron con éxito, y los rojos fallaron. Haz clic en una etapa para ver sus detalles.

    Luego de 3 a 5 minutos, la fase de pruebas de integración se completa, y se debe aprobar la canalización de forma manual para continuar con la implementación.

  3. Desplázate sobre el ícono de "persona" amarillo y haz clic en Continue (Continuar).

    enviar a producción

    Tu implementación continúa con el frontend de producción y con las implementaciones de backend. Tarda unos minutos en completarse.

  4. Para visualizar la aplicación, selecciona Infrastructure (Infraestructura) > Load Balancers (Balanceador de cargas) en la parte superior de la IU de Spinnaker.

    balanceador de cargas

  5. Desplázate hacia abajo en la lista del balanceador de cargas y haz clic en Default (Predeterminado), debajo de sample-frontend-production.

    Balanceador de cargas predeterminado

  6. Desplázate hacia abajo en el panel de detalles, a la derecha, y haz clic en el botón del portapapeles del IP de Ingress (Entrada) para copiar la dirección IP de tu aplicación.

    Copia la dirección IP de tu aplicación

  7. Pega la dirección en tu navegador para visualizar la versión de producción de la aplicación.

    backend

    Ya activaste la canalización de forma manual para compilar, realizar pruebas y, luego, implementar tu aplicación.

Cómo activar la canalización mediante cambios de código

En esta sección, realizarás pruebas a la canalización de extremo a extremo a través de un cambio en el código y del envío de una etiqueta de Git, y mirarás cómo se ejecuta la canalización en respuesta a esto. Cuando envías una etiqueta de Git que comienza con “v”, Cloud Build se activa para compilar una nueva imagen de Docker y enviarla a Container Registry. Spinnaker detecta que la nueva etiqueta de la imagen comienza con “v” y activa una canalización para implementar la imagen en canaries, ejecutar pruebas y desplegar la misma imagen en todos los pods de la implementación.

  1. Cambia el color de la aplicación de naranja a azul:

    sed -i 's/orange/blue/g' cmd/gke-info/common-service.go
    
  2. Etiqueta tu cambio y envíalo al repositorio de código fuente:

    git commit -a -m "Change color to blue"
    git tag v1.0.1
    git push --tags
    
  3. Observa cómo la nueva compilación aparece en Build History (Historial de compilaciones) de Cloud Build.

  4. Haz clic en Pipelines (Canalizaciones) para ver cómo la canalización comienza a implementar la imagen.

  5. Observa las implementaciones Canary. Cuando la implementación se encuentre pausada, en espera para implementarse en producción, debes comenzar a actualizar la pestaña que contiene tu aplicación. Cuatro de tus backend ejecutan la versión anterior de tu aplicación y solo uno de los backend ejecuta las pruebas Canary. La nueva versión debería aparecer en color azul luego de, aproximadamente, unas diez veces después de actualizar la pestaña.

  6. Cuando se complete la etapa de pruebas, vuelve a la pestaña de Spinnaker y aprueba la implementación.

  7. Cuando la canalización se complete, tu aplicación lucirá como la siguiente captura de pantalla. Ten en cuenta que el color cambió a azul por el cambio en el código, y que en el campo de Version (Versión) ahora se muestra v1.0.1.

    backend de la aplicación

    ¡Ya implementaste con éxito tu aplicación en todo tu entorno de producción!

  8. Además, tienes la opción de volver a tu confirmación anterior para revertir los cambios anteriores. Las reversiones agregan una etiqueta nueva (v1.0.2) y la envían de vuelta a través de la misma canalización que utilizaste para implementar v1.0.1:

    git revert v1.0.1
    git tag v1.0.2
    git push --tags

Limpieza

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud Platform por los recursos que usaste en este instructivo:

  1. Borra la instalación de Spinnaker:

    ../helm delete --purge cd
    
  2. Borra los servicios de la aplicación de muestra:

    kubectl delete -f k8s/services
    
  3. Borra la cuenta de servicio:

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:spinnaker-storage-account" --format='value(email)')
    gcloud iam service-accounts delete $SA_EMAIL
    
  4. Borra el clúster de GKE:

    gcloud container clusters delete spinnaker-tutorial
    
  5. Borra el repositorio:

    gcloud source repos delete sample-app
    
  6. Borra el depósito:

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-spinnaker-config
    gsutil -m rm -r gs://$BUCKET
    
  7. Borra tus imágenes de contenedor:

    export PROJECT=$(gcloud info --format='value(config.project)')
    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.0
    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.1
    
  8. Si durante el paso opcional de más arriba realizaste una reversión y creaste v1.0.2, borra esa imagen de contenedor:

    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.2
    

¿Qué sigue?

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

Enviar comentarios sobre...