En esta página, se explica cómo crear una canalización de integración y entrega continuas (CI/CD) en Google Cloud con productos alojados y la metodología popular de GitOps.
Desde hace mucho tiempo, los ingenieros de Google almacenan los archivos de configuración y de implementación en nuestro repositorio principal de código fuente. Esta metodología se describe en el libro ingeniería de confiabilidad de sitios, capítulo 8 (Beyer et al., 2016), y Kelsey Hightower la demostró en su presentación de Google Cloud Next '17.
Una parte clave de GitOps es la idea de “entornos como código”, que describen tus implementaciones de forma declarativa con archivos (por ejemplo, los manifiestos de Kubernetes) almacenados en un repositorio de Git.
En este instructivo, crearás una canalización de CI/CD que compila una imagen de contenedor desde el código confirmado, la almacena en Artifact Registry, actualiza un manifiesto de Kubernetes en un repositorio de Git y, luego, implementa la aplicación en Google Kubernetes Engine (GKE) con ese manifiesto de forma automática.
En este instructivo, se usan los dos repositorios de Git siguientes:
- Repositorio app: contiene el código fuente de la aplicación.
- Repositorio env: Contiene los manifiestos para la implementación de Kubernetes.
Cuando envías un cambio al repositorio de app, la canalización de Cloud Build realiza pruebas y compila una imagen de contenedor, que luego envía a Artifact Registry. Después de enviar la imagen, Cloud Build actualiza el manifiesto de implementación y lo envía al repositorio env. Esto activa otra canalización de Cloud Build que aplica el manifiesto al clúster de GKE y, si se aplica correctamente, lo almacena en otra rama del repositorio env.
Los repositorios app y env deben estar separados porque tienen diferentes ciclos de vida y usos. Los usuarios principales del repositorio app son personas reales, y este repositorio está destinado para una aplicación específica. Los usuarios principales del repositorio env son sistemas automatizados (como Cloud Build), y varias aplicaciones pueden compartir este repositorio. El repositorio env puede tener varias ramas y cada una se asigna a un entorno específico (en este instructivo, solo utilizas la rama de producción), y hace referencia a una imagen de contenedor específica, mientras que el repositorio app, no.
Cuando termines este instructivo, obtendrás un sistema en el que fácilmente podrás realizar las siguientes acciones:
- Diferenciar las implementaciones fallidas y correctas mediante una observación del historial de Cloud Build.
- Acceder al manifiesto utilizado en este momento mediante la observación de la rama production del repositorio env.
- Revertir a cualquier versión anterior mediante una nueva ejecución de la compilación correspondiente de Cloud Build
Acerca de este instructivo
En este instructivo se utiliza Cloud Source Repositories para alojar los 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 a fin de usar una solicitud de extracción para este fin.
Si bien recomendamos Spinnaker a los equipos que quieren implementar patrones de implementación avanzada (azul/verde, análisis de versiones canary, múltiples nubes, etc.), es posible que su conjunto de atributos no sea necesario para una estrategia de CI/CD exitosa en organizaciones y proyectos más pequeños. En este instructivo, aprenderás cómo crear una canalización de CI/CD para aplicaciones alojadas en GKE con herramientas.
Para que este instructivo sea más simple, se utiliza solo el entorno de producción en el repositorio env, pero puedes ampliarlo para implementar varios entornos, en caso necesario.
Objetivos
- Crear repositorios de Git en Cloud Source Repositories
- Crear una imagen de contenedor con Cloud Build y almacenarla en Artifact Registry
- Crear una canalización de CI
- Crear una canalización de CD
- Probar la canalización de CI/CD
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
Selecciona o crea un proyecto de Google Cloud.
Habilita la facturación para tu proyecto.
Abre Cloud Shell para ejecutar los comandos detallados en este instructivo. Cloud Shell es un entorno de shell interactivo para Google Cloud que te permite administrar proyectos y recursos desde el navegador web.
Si el comando
gcloud config get-value project
no muestra el ID del proyecto que acabas de seleccionar, configura Cloud Shell para que use tu proyecto.gcloud config set project [PROJECT_ID]
En Cloud Shell, habilita las API requeridas.
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 implementar la aplicación de ejemplo de este instructivo.
Autopilot
Crea un clúster de Autopilot con el nombre
hello-cloudbuild
:gcloud container clusters create-auto hello-cloudbuild \ --region us-central1
Estándar
Crea un clúster estándar de un nodo llamado
hello-cloudbuild
:gcloud container clusters create hello-cloudbuild \ --num-nodes 1 --region us-central1
Si nunca usaste Git en Cloud Shell, configúralo con tu nombre y dirección de correo electrónico. Git usará esos datos para identificarte como el 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 finalices este instructivo, puedes borrar los recursos creados para evitar que se te siga facturando. Consulta Realiza una limpieza para obtener más información.
Crea repositorios de Git en Cloud Source Repositories
En esta sección, crearás dos repositorios de Git (app y env) utilizados en este instructivo y, luego, inicializarás app con algún 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 desde 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 clonaste contiene una aplicación "Hello World".
Crea una imagen de contenedor con Cloud Build
El código que clonaste ya contiene el siguiente Dockerfile.
Con este Dockerfile, puede crear una imagen de contenedor con Cloud Build y guardarla 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 que generó la creación de la imagen de contenedor a tu terminal cuando ejecutas este comando.
Cuando se complete la compilación, verifica que la imagen de contenedor nueva esté disponible en Artifact Registry.
Crea la canalización de integración continua
En esta sección, configurarás Cloud Build para ejecutar automáticamente una prueba de unidades pequeñas, compilar la imagen de contenedor y enviarla a Artifact Registry. Enviar una confirmación nueva a Cloud Source Repositories 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.
Completa las siguientes opciones:
- En el campo Nombre, escribe
hello-cloudbuild
. - En Evento, selecciona Enviar a una rama.
- En Fuente, selecciona
hello-cloudbuild-app
como tu repositorio y^master$
como la rama. - En Configuración de compilación, selecciona Cloud Build configuration file.
- 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.
Sugerencia: Si necesitas crear activadores de compilación para muchos proyectos, puedes usar la API de Build Triggers.
En Cloud Shell, envía el código de la aplicación a Cloud Source Repositories para activar la canalización de IC en Cloud Build.
cd ~/kubernetes-engine-samples/management/gitops-style-delivery/ git push google master
Abre la consola de Cloud Build.
Aparecerán las compilaciones ejecutadas y las que finalizaron recientemente. Puedes hacer clic en la compilación para seguir la ejecución y examinar sus registros.
Crea la canalización de entrega continua
Cloud Build también se usa para la canalización de entrega continua. La canalización se ejecuta cada vez que se envía una confirmación a la rama candidate del repositorio hello-cloudbuild-env. La canalización aplica la versión nueva del manifiesto al clúster de Kubernetes y, si lo hace 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.
- En Cloud Build, tienes una vista de las implementaciones fallidas y correctas.
- Puedes revertir cualquier implementación anterior si vuelves a ejecutar la compilación correspondiente en Cloud Build. Una reversión también actualiza la rama production para reflejar verdaderamente el historial de implementaciones.
Modificarás la canalización de integración continua para actualizar la rama candidate del repositorio hello-cloudbuild-env, lo que activa la canalización de entrega continua.
Otorga acceso de GKE a Cloud Build
Para implementar la aplicación en el clúster de Kubernetes, Cloud Build necesita la función de administración de identidades y accesos de desarrollador de Kubernetes Engine.
Shell
En Cloud Shell, ejecuta el comando siguiente:
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
Console
En la consola de Google Cloud, abre la página Configuración de Cloud Build:
Abre Configuración de Cloud Build
Aparecerá la página Permisos de la cuenta de servicio.
Configura el estado de la función Desarrollador de Kubernetes Engine como Habilitar.
Inicializa 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 ejecutará en Cloud Build. Este tiene dos pasos:Cloud Build aplica el manifiesto en el clúster de GKE.
Si lo hace correctamente, Cloud Build lo copia en la rama production.
Crea la rama candidate y envía ambas ramas para que estén disponibles en Cloud Source Repositories.
git checkout -b candidate git push origin production git push origin candidate
Otorga la función de IAM del escritor del repositorio de código fuente 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
Cómo crear un activador para la canalización de entrega continua
En esta sección, configurarás Cloud Build para que se active con un envío a la rama candidate del repositorio hello-cloudbuild-env.
Abre la página Activadores de Cloud Build.
Haz clic en Crear activador.
Completa las siguientes opciones:
- En el campo Nombre, escribe
hello-cloudbuild-deploy
. - En Evento, selecciona Enviar a una rama.
- En Fuente, selecciona
hello-cloudbuild-env
como tu repositorio y^candidate$
como la rama. - En Configuración de compilación, selecciona 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.
Modifica la canalización de integración continua para activar la canalización de entrega continua
En esta sección, agregarás algunos pasos a la canalización de integración continua que generará una versión nueva del manifiesto de Kubernetes y lo enviará al repositorio hello-cloudbuild-env para activar la canalización de entrega continua.
Reemplaza el archivo
cloudbuild.yaml
por el ejemplo extendido en el archivocloudbuild-trigger-cd.yaml
.cd ~/kubernetes-engine-samples/management/gitops-style-delivery/ cp cloudbuild-trigger-cd.yaml cloudbuild.yaml
cloudbuild-trigger-cd.yaml
es una versión extendida del archivocloudbuild.yaml
. Se agregan pasos para generar el nuevo manifiesto de Kubernetes y activar la canalización de entrega continua.Confirme las modificaciones y envíelas 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
Esto activa la canalización de integración continua en Cloud Build.
Examina la compilación de integración continua.
Aparecerán las compilaciones ejecutadas recientemente y finalizadas para el repositorio hello-cloudbuild-app. Puedes hacer clic en la compilación para seguir la ejecución y examinar sus registros. El último paso de esta canalización envía el manifiesto nuevo al repositorio hello-cloudbuild-env, que activa la canalización de entrega continua.
Examina la compilación de entrega continua.
Aparecerán tus compilaciones recientes y en ejecución para el repositorio hello-cloudbuild-env. Puedes hacer clic en la compilación para seguir la ejecución y examinar sus registros.
Prueba la canalización completa
La canalización de IC/EC ahora está configurada. En esta sección, la probarás de extremo a extremo.
Ve a la página Servicio de GKE.
Ir a Servicios de Google Kubernetes Engine
La lista contiene un solo servicio llamado hello-cloudbuild creado por la compilación de entrega continua que se compiló recientemente.
Haz clic en el extremo del servicio hello-cloudbuild. Se muestra “Hello, World!”. Si no existe el extremo, o si ves un error del balanceador de cargas, es posible que debas esperar algunos minutos para que el balanceador de cargas se inicialice por completo. Haz clic en Actualizar para que la página se actualice, si es necesario.
En Cloud Shell, reemplaza “Hello World” por “Hello Cloud Build” en la aplicación y en la prueba de unidades.
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 envía el cambio a Cloud Source Repositories.
git add app.py test_app.py git commit -m "Hello Cloud Build" git push google master
Esto activa la canalización de IC/EC completa.
Después de unos minutos, vuelve a cargar la aplicación en tu navegador. Se muestra “Hello Cloud Build!”.
Prueba la reversión
En esta sección, revertirás a la versión de la aplicación que decía “Hello World!”.
Abre la consola Cloud Build para el repositorio hello-cloudbuild-env.
Haz clic en la segunda compilación más reciente disponible.
Haz clic en Volver a compilar.
Cuando se termine la compilación, vuelve a cargar la aplicación en tu navegador. Vuelve a aparecer “Hello World!”.
Limpia
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.
- 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.
Borra los recursos
Si deseas conservar el proyecto de Google Cloud que usaste en este instructivo, borra los recursos individuales:
Borra los repositorios de Git locales.
cd ~ rm -rf ~/hello-cloudbuild-app rm -rf ~/hello-cloudbuild-env
Borra los repositorios de Git en Cloud Source Repositories.
gcloud source repos delete hello-cloudbuild-app --quiet gcloud source repos delete hello-cloudbuild-env --quiet
Borra los activadores de Cloud Build.
Abre la página Activadores de Cloud Build.
Para cada activador, haz clic en Más more_vert y, luego, en Borrar.
Borra el repositorio de Docker en Artifact Registry.
gcloud artifacts repositories delete my-repository \ --location=us-central1
Quita el permiso otorgado a Cloud Build para conectarte 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
Borra el clúster de GKE.
gcloud container clusters delete hello-cloudbuild \ --region us-central1
Qué sigue
- Para obtener más información sobre las funciones avanzadas de Cloud Build, consulta las características siguientes: Configura el orden de los pasos de la compilación, Compila, prueba y, también, implementa artefactos y Crea pasos de compilación personalizados.
- Obtén información sobre cómo duplicar un repositorio de GitHub o Bitbucket para Cloud Source Repositories.
- Conecta directamente Cloud Build a tu repositorio de GitHub.