En esta página se explica cómo crear un flujo de procesamiento de integración y entrega continuas (CI/CD) en Google Cloud usando únicamente productos alojados y la popular metodología de GitOps.
Los ingenieros de Google llevan mucho tiempo almacenando archivos de configuración y de implementación en nuestro repositorio de código fuente principal. Esta metodología se describe en el capítulo 8 del libro Site Reliability Engineering (Beyer et al., 2016) y Kelsey Hightower lo demostró en su ponencia inaugural de Google Cloud Next '17.
Una parte fundamental de GitOps es la idea de "entornos como código": describir los despliegues de manera declarativa usando archivos (por ejemplo, archivos de manifiesto de Kubernetes) almacenados en un repositorio de Git.
En este tutorial, crearás un flujo de procesamiento de CI/CD que compila automáticamente una imagen de contenedor a partir del código confirmado, almacena la imagen en Artifact Registry, actualiza un manifiesto de Kubernetes en un repositorio de Git y despliega la aplicación en Google Kubernetes Engine (GKE) mediante ese manifiesto.
En este tutorial se usan dos repositorios de Git:
- Repositorio de la aplicación: contiene el código fuente de la aplicación.
- Repositorio env: contiene los manifiestos de la implementación de Kubernetes.
Cuando envías un cambio al repositorio app, la canalización de Cloud Build ejecuta pruebas, crea una imagen de contenedor y la envía a Artifact Registry. Después de enviar la imagen, Cloud Build actualiza el manifiesto de Deployment y lo envía al repositorio env. De esta forma, se activa otra canalización de Cloud Build que aplica el manifiesto al clúster de GKE y, si se completa correctamente, almacena el manifiesto en otra rama del repositorio env.
Mantenemos los repositorios app y env separados porque tienen ciclos de vida y usos diferentes. Los principales usuarios del repositorio de la aplicación son personas reales y este repositorio está dedicado a una aplicación específica. Los principales usuarios del repositorio env son sistemas automatizados (como Cloud Build) y es posible que varias aplicaciones compartan este repositorio. El repositorio env puede tener varias ramas, cada una de las cuales se asigna a un entorno específico (en este tutorial solo se usa el entorno de producción) y hace referencia a una imagen de contenedor específica, mientras que el repositorio app no.
Cuando termines este tutorial, tendrás un sistema con el que podrás hacer lo siguiente fácilmente:
- Para distinguir entre las implementaciones fallidas y las correctas, consulta el historial de Cloud Build.
- Accede al manifiesto que se está usando actualmente consultando la rama production del repositorio env.
- Vuelve a cualquier versión anterior volviendo a ejecutar la compilación de Cloud Build correspondiente.
Acerca de este tutorial
En este tutorial se usa Cloud Source Repositories para alojar repositorios de Git, pero puedes obtener los mismos resultados con otros productos de terceros, como GitHub, Bitbucket o GitLab.
Esta canalización no implementa un mecanismo de validación antes de la implementación. Si usas GitHub, Bitbucket o GitLab, puedes modificar la canalización para usar una solicitud de extracción con este fin.
Aunque recomendamos Spinnaker a los equipos que quieran implementar patrones de implementación avanzados (azul/verde, análisis canary, multicloud, etc.), puede que no necesiten su conjunto de funciones para llevar a cabo una estrategia de CI/CD eficaz en organizaciones y proyectos más pequeños. En este tutorial, aprenderás a crear un flujo de procesamiento de CI/CD adecuado para aplicaciones alojadas en GKE con herramientas.
Para simplificar las cosas, en este tutorial se usa un único entorno (producción) en el repositorio env, pero puedes ampliarlo para desplegarlo en varios entornos si es necesario.
Objetivos
- Crea repositorios de Git en Cloud Source Repositories.
- Crea una imagen de contenedor con Cloud Build y almacénala en Artifact Registry.
- Crea un flujo de procesamiento de CI.
- Crea un flujo de procesamiento de CD.
- Prueba el flujo de procesamiento de CI/CD.
Costes
En este documento, se utilizan los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costes basada en el uso previsto,
utiliza la calculadora de precios.
Cuando termines las tareas que se describen en este documento, puedes evitar que se te siga facturando eliminando los recursos que has creado. Para obtener más información, consulta la sección Limpiar.
Antes de empezar
Selecciona o crea un Google Cloud proyecto.
Habilita la facturación de tu proyecto.
Abre Cloud Shell para ejecutar los comandos que se indican en este tutorial. Cloud Shell es un entorno de shell interactivo para Google Cloud que te permite gestionar tus proyectos y recursos desde el navegador web.
Si el comando
gcloud config get-value project
no devuelve el ID del proyecto que has seleccionado, configura Cloud Shell para que use tu proyecto.gcloud config set project [PROJECT_ID]
En Cloud Shell, habilita las APIs necesarias.
gcloud services enable container.googleapis.com \ cloudbuild.googleapis.com \ sourcerepo.googleapis.com \ artifactregistry.googleapis.com
Crea un repositorio de Docker de Artifact Registry llamado
my-repository
en la regiónus-central1
para almacenar tus imágenes de contenedor.gcloud artifacts repositories create my-repository \ --repository-format=docker \ --location=us-central1
En Cloud Shell, crea un clúster de GKE que usarás para desplegar la aplicación de ejemplo de este tutorial.
Autopilot
Crea un clúster de Autopilot llamado
hello-cloudbuild
:gcloud container clusters create-auto hello-cloudbuild \ --location us-central1
Estándar
Crea un clúster Estándar de un solo nodo llamado
hello-cloudbuild
:gcloud container clusters create hello-cloudbuild \ --num-nodes 1 --location us-central1
Si nunca has usado Git en Cloud Shell, configúralo con tu nombre y tu dirección de correo electrónico. Git los usará para identificarte como autor de las confirmaciones que crearás en Cloud Shell.
git config --global user.email "YOUR_EMAIL_ADDRESS" git config --global user.name "YOUR_NAME"
Cuando termines este tutorial, puedes evitar que se te siga facturando eliminando los recursos que has creado. Consulta la sección Limpieza para obtener más información.
Crear los repositorios de Git en Cloud Source Repositories
En esta sección, crearás los dos repositorios de Git (app y env) que se usan en este tutorial e inicializarás el repositorio app con código de ejemplo.
En Cloud Shell, crea los dos repositorios de Git.
gcloud source repos create hello-cloudbuild-app gcloud source repos create hello-cloudbuild-env
Clona el código de ejemplo de GitHub.
cd ~ git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd ~/kubernetes-engine-samples/management/gitops-style-delivery/
Configura Cloud Source Repositories como remoto.
PROJECT_ID=$(gcloud config get-value project) git remote add google \ "https://source.developers.google.com/p/${PROJECT_ID}/r/hello-cloudbuild-app"
El código que has clonado contiene una aplicación "Hello World".
Crear una imagen de contenedor con Cloud Build
El código que has clonado contiene el siguiente Dockerfile.
Con este Dockerfile, puedes crear una imagen de contenedor con Cloud Build y almacenarla en Artifact Registry.
En Cloud Shell, crea una compilación de Cloud Build basada en la última confirmación con el siguiente comando.
cd ~/kubernetes-engine-samples/management/gitops-style-delivery/ COMMIT_ID="$(git rev-parse --short=7 HEAD)" gcloud builds submit --tag="us-central1-docker.pkg.dev/${PROJECT_ID}/my-repository/hello-cloudbuild:${COMMIT_ID}" .
Cloud Build transmite los registros generados por la creación de la imagen de contenedor a tu terminal cuando ejecutas este comando.
Una vez que se haya completado la compilación, comprueba que la nueva imagen de contenedor esté disponible en Artifact Registry.
Crear el flujo de procesamiento de integración continua
En esta sección, configurarás Cloud Build para que ejecute automáticamente una pequeña prueba unitaria, compile la imagen de contenedor y, a continuación, la envíe a Artifact Registry. Al enviar una nueva confirmación a Cloud Source Repositories, se activa automáticamente esta canalización. El archivo cloudbuild.yaml
incluido en el código es la configuración de la canalización.
Abre la página Activadores de Cloud Build.
Haz clic en Crear activador.
Rellena las siguientes opciones:
- En el campo Nombre, escribe
hello-cloudbuild
. - En Evento, selecciona Enviar a una rama.
- En Source (Origen), selecciona
hello-cloudbuild-app
como Repository (Repositorio) y^master$
como Branch (Rama). - En Configuración de compilación, selecciona Archivo de configuración de Cloud Build.
- En el campo Ubicación del archivo de configuración de Cloud Build, escribe
cloudbuild.yaml
después de/
.
- En el campo Nombre, escribe
Haz clic en Crear para guardar el activador de compilación.
Nota: Si necesitas crear activadores de compilación para muchos proyectos, puedes usar la API Build Triggers.
En Cloud Shell, envía el código de la aplicación a Cloud Source Repositories para activar la canalización de integración continua en Cloud Build.
cd ~/kubernetes-engine-samples/management/gitops-style-delivery/ git push google master
Abre la consola de Cloud Build.
Se mostrarán las compilaciones que hayas ejecutado y completado recientemente. Puedes hacer clic en una compilación para seguir su ejecución y examinar sus registros.
Crear el flujo de procesamiento de entrega continua
Cloud Build también se usa en el flujo de procesamiento de entrega continua. La pipeline se ejecuta cada vez que se inserta una confirmación en la rama candidate del repositorio hello-cloudbuild-env. La canalización aplica la nueva versión del manifiesto al clúster de Kubernetes y, si se realiza correctamente, copia el manifiesto en la rama production. Este proceso tiene las siguientes propiedades:
- La rama candidate es un historial de los intentos de implementación.
- La rama production es un historial de las implementaciones correctas.
- Tiene una vista de las implementaciones correctas y fallidas en Cloud Build.
- Puedes volver a cualquier implementación anterior volviendo a ejecutar la compilación correspondiente en Cloud Build. Una reversión también actualiza la rama producción para reflejar con precisión el historial de los despliegues.
Modificarás la canalización de integración continua para actualizar la rama candidate del repositorio hello-cloudbuild-env, lo que activará la canalización de entrega continua.
Conceder acceso de Cloud Build a GKE
Para desplegar la aplicación en tu clúster de Kubernetes, Cloud Build necesita el rol de gestión de identidades y accesos Desarrollador de Kubernetes Engine.
Shell
En Cloud Shell, ejecuta el siguiente comando:
PROJECT_NUMBER="$(gcloud projects describe ${PROJECT_ID} --format='get(projectNumber)')" gcloud projects add-iam-policy-binding ${PROJECT_NUMBER} \ --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role=roles/container.developer
Consola
-
En la Google Cloud consola, ve a la página Permisos de settingsGKE:
Define el estado del rol Desarrollador de Kubernetes Engine como Habilitar.
Inicializar el repositorio hello-cloudbuild-env
Debes inicializar el repositorio hello-cloudbuild-env con dos ramas (production y candidate) y un archivo de configuración de Cloud Build que describa el proceso de implementación.
En Cloud Shell, clona el repositorio hello-cloudbuild-env y crea la rama production.
cd ~ gcloud source repos clone hello-cloudbuild-env cd ~/kubernetes-engine-samples/management/gitops-style-delivery/ git checkout -b production
Copia el archivo
cloudbuild-delivery.yaml
disponible en el repositorio hello-cloudbuild-app y confirma el cambio.cd ~/kubernetes-engine-samples/management/gitops-style-delivery/ cp ~/hello-cloudbuild-app/cloudbuild-delivery.yaml ~/kubernetes-engine-samples/management/gitops-style-delivery/cloudbuild.yaml git add . git commit -m "Create cloudbuild.yaml for deployment"
El archivo
cloudbuild-delivery.yaml
describe el proceso de implementación que se va a ejecutar en Cloud Build. Tiene dos pasos:Cloud Build aplica el manifiesto en el clúster de GKE.
Si se realiza correctamente, Cloud Build copia el manifiesto en la rama production.
Crea una rama candidata e inserta ambas ramas para que estén disponibles en Cloud Source Repositories.
git checkout -b candidate git push origin production git push origin candidate
Concede el rol de IAM Escritor de repositorio de origen a la cuenta de servicio de Cloud Build para el repositorio hello-cloudbuild-env.
PROJECT_NUMBER="$(gcloud projects describe ${PROJECT_ID} \ --format='get(projectNumber)')" cat >/tmp/hello-cloudbuild-env-policy.yaml <<EOF bindings: - members: - serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com role: roles/source.writer EOF gcloud source repos set-iam-policy \ hello-cloudbuild-env /tmp/hello-cloudbuild-env-policy.yaml
Crear el activador del flujo de procesamiento de entrega continua
En esta sección, configurarás Cloud Build para que se active cuando se envíe contenido a la rama candidate del repositorio hello-cloudbuild-env.
Abre la página Activadores de Cloud Build.
Haz clic en Crear activador.
Rellena las siguientes opciones:
- En el campo Nombre, escribe
hello-cloudbuild-deploy
. - En Evento, selecciona Enviar a una rama.
- En Source (Origen), selecciona
hello-cloudbuild-env
como Repository (Repositorio) y^candidate$
como Branch (Rama). - En Configuration (Configuración), selecciona Cloud Build configuration file (yaml or json) (Archivo de configuración de Cloud Build [yaml o json]).
- En el campo Ubicación del archivo de configuración de Cloud Build, escribe
cloudbuild.yaml
después de/
.
- En el campo Nombre, escribe
Haz clic en Crear.
Modificar la canalización de integración continua para activar la canalización de entrega continua
En esta sección, se añaden algunos pasos al flujo de procesamiento de integración continua que genera una nueva versión del manifiesto de Kubernetes y la envía al repositorio hello-cloudbuild-env para activar el flujo de procesamiento de entrega continua.
Sustituye el archivo
cloudbuild.yaml
por el ejemplo ampliado del archivocloudbuild-trigger-cd.yaml
.cd ~/kubernetes-engine-samples/management/gitops-style-delivery/ cp cloudbuild-trigger-cd.yaml cloudbuild.yaml
El archivo
cloudbuild-trigger-cd.yaml
es una versión ampliada del archivocloudbuild.yaml
. Añade pasos para generar el nuevo manifiesto de Kubernetes y activar el flujo de procesamiento de entrega continua.Confirma las modificaciones y envíalas a Cloud Source Repositories.
cd ~/kubernetes-engine-samples/management/gitops-style-delivery/ git add cloudbuild.yaml git commit -m "Trigger CD pipeline" git push google master
De esta forma, se activa la canalización de integración continua en Cloud Build.
Examina la compilación de integración continua.
Aparecerán las compilaciones que hayas ejecutado y completado recientemente del repositorio hello-cloudbuild-app. Puedes hacer clic en una compilación para seguir su ejecución y examinar sus registros. El último paso de esta canalización envía el nuevo manifiesto al repositorio hello-cloudbuild-env, lo que activa la canalización de entrega continua.
Examina la compilación de entrega continua.
Aparecerán las compilaciones que has ejecutado y completado recientemente del repositorio hello-cloudbuild-env. Puedes hacer clic en una compilación para seguir su ejecución y examinar sus registros.
Probar todo el flujo de procesamiento
El flujo de procesamiento de CI/CD completo ya está configurado. En esta sección, la probarás de principio a fin.
Ve a la página Servicios de GKE.
Ir a Servicios de Google Kubernetes Engine
La lista contiene un único servicio llamado hello-cloudbuild creado por la compilación de entrega continua que se ha completado recientemente.
Haz clic en el endpoint del servicio hello-cloudbuild. Aparecerá el mensaje "Hello World!". Si no hay ningún endpoint o aparece un error del balanceador de carga, es posible que tengas que esperar unos minutos para que el balanceador de carga se inicialice por completo. Si es necesario, haga clic en Actualizar para actualizar la página.
En Cloud Shell, sustituye "Hello World" por "Hello Cloud Build" tanto en la aplicación como en la prueba unitaria.
cd ~/kubernetes-engine-samples/management/gitops-style-delivery/ sed -i 's/Hello World/Hello Cloud Build/g' app.py sed -i 's/Hello World/Hello Cloud Build/g' test_app.py
Confirma y sube el cambio a Cloud Source Repositories.
git add app.py test_app.py git commit -m "Hello Cloud Build" git push google master
De esta forma, se activará todo el flujo de procesamiento de CI/CD.
Al cabo de unos minutos, vuelve a cargar la aplicación en el navegador. Aparecerá el mensaje "Hello Cloud Build!".
Probar la restauración
En esta sección, volverás a la versión de la aplicación que decía "Hello World!".
Abre la consola de Cloud Build del repositorio hello-cloudbuild-env.
Haz clic en la segunda compilación más reciente disponible.
Haz clic en Recompilar.
Cuando termine la compilación, vuelve a cargar la aplicación en el navegador. Vuelve a aparecer "Hello World!".
Limpieza
Para evitar que los recursos utilizados en este tutorial se cobren en tu cuenta de Google Cloud, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Eliminar los recursos
Si quieres conservar el Google Cloud proyecto que has usado en este tutorial, elimina los recursos:
Elimina los repositorios de Git locales.
cd ~ rm -rf ~/hello-cloudbuild-app rm -rf ~/hello-cloudbuild-env
Elimina los repositorios de Git en Cloud Source Repositories.
gcloud source repos delete hello-cloudbuild-app --quiet gcloud source repos delete hello-cloudbuild-env --quiet
Elimina los activadores de Cloud Build.
Abre la página Activadores de Cloud Build.
En cada activador, haz clic en Más more_vert y, a continuación, en Eliminar.
Elimina el repositorio de Docker en Artifact Registry.
gcloud artifacts repositories delete my-repository \ --location=us-central1
Quita el permiso concedido a Cloud Build para conectarse a GKE.
PROJECT_NUMBER="$(gcloud projects describe ${PROJECT_ID} \ --format='get(projectNumber)')" gcloud projects remove-iam-policy-binding ${PROJECT_NUMBER} \ --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role=roles/container.developer
Elimina el clúster de GKE.
gcloud container clusters delete hello-cloudbuild \ --location us-central1
Siguientes pasos
- Consulta más funciones avanzadas de Cloud Build: Configurar el orden de los pasos de compilación, Compilar, probar y desplegar artefactos, Crear pasos de compilación personalizados.
- Consulta cómo replicar un repositorio de GitHub o Bitbucket en Cloud Source Repositories.
- Conectar Cloud Build directamente a tu repositorio de GitHub