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 popular metodología 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.
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 , ve a la página Permisos de settings GKE:
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!”.