Usa Jenkins para realizar compilaciones distribuidas en Compute Engine

En este instructivo, se muestra cómo hacer lo siguiente:

  • Crear un sistema de integración continua de Jenkins para ejecutar tus compilaciones mediante agentes de Jenkins bajo demanda en Compute Engine
  • Almacenar tus artefactos de compilación en Cloud Storage
  • Aplicar una política de ciclo de vida para mover los artefactos de compilación más antiguos en Cloud Storage a opciones de almacenamiento menos costosas.

Arquitectura

En el siguiente diagrama, se describe la arquitectura del instructivo.

Arquitectura en la que se muestra cómo una cuenta de servicio envía los artefactos a Cloud Storage a través de Compute Engine

En el diagrama, se agrega una cuenta de servicio a Jenkins a fin de que pueda crear instancias de agente y enviar artefactos a Cloud Storage para el almacenamiento a largo plazo. Jenkins aprovisiona instancias en el momento a medida que ejecuta las compilaciones. A medida que pasa el tiempo, los artefactos de compilación se mueven a través de varias clases de almacenamiento para limitar su costo de retención.

Objetivos

  • Crear una imagen base con Packer para ejecutar tus compilaciones de Jenkins
  • Aprovisiona Jenkins mediante Cloud Marketplace.
  • Configura Jenkins para implementar agentes de compilación efímeros.
  • Sube artefactos de compilación en Cloud Storage.
  • Configura políticas de ciclo de vida para optimizar tus costos de Cloud Storage.

Costos

En este instructivo, se usan los siguientes componentes facturables de Google Cloud:

  • Compute Engine
  • Cloud Storage

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud sean aptos para obtener una prueba gratuita.

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

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyecto

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

  4. Habilita la API Compute Engine.

    Habilita la API

Configura tu entorno

En esta sección, configurarás la infraestructura y las identidades requeridas para completar este instructivo. Ejecuta el resto del instructivo desde dentro de Cloud Shell.

Abrir Cloud Shell

Configura IAM

Crea una cuenta de servicio de administración de identidades y accesos (IAM) para delegar permisos a Jenkins. Esta cuenta le permite a Jenkins almacenar datos en Cloud Storage y, también, iniciar instancias en Compute Engine. Jenkins ejecuta tus compilaciones en instancias efímeras y almacena los artefactos de compilación en Cloud Storage.

Crea una cuenta de servicio

  1. Crea la cuenta de servicio:

    gcloud iam service-accounts create jenkins --display-name jenkins
  2. Almacena la dirección de correo electrónico de la cuenta de servicio y el ID del proyecto de Google Cloud actual en variables de entorno para que puedas usarlos en comandos posteriores:

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:jenkins" --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')
  3. Vincula las siguientes funciones a tu cuenta de servicio:

    gcloud projects add-iam-policy-binding $PROJECT \
        --role roles/storage.admin --member serviceAccount:$SA_EMAIL
    gcloud projects add-iam-policy-binding $PROJECT --role roles/compute.instanceAdmin.v1 \
        --member serviceAccount:$SA_EMAIL
    gcloud projects add-iam-policy-binding $PROJECT --role roles/compute.networkAdmin \
        --member serviceAccount:$SA_EMAIL
    gcloud projects add-iam-policy-binding $PROJECT --role roles/compute.securityAdmin \
        --member serviceAccount:$SA_EMAIL
    gcloud projects add-iam-policy-binding $PROJECT --role roles/iam.serviceAccountActor \
        --member serviceAccount:$SA_EMAIL

Descarga la clave de la cuenta de servicio

Ahora que le otorgaste a la cuenta de servicio los permisos adecuados, debes crear y descargar su clave. Guarda la clave en un lugar seguro. La usarás más adelante, cuando configures el complemento de JClouds para autenticarse con la API de Compute Engine.

  1. Crea el archivo de claves:

    gcloud iam service-accounts keys create jenkins-sa.json --iam-account $SA_EMAIL
  2. En Cloud Shell, haz clic en Más y, luego, en Descargar archivo.

  3. Tipo jenkins-sa.json.

  4. Haz clic en Descargar para guardar el archivo de forma local.

Crea una imagen de agente de Jenkins

A continuación, creas una imagen reutilizable de Compute Engine que contenga el software y las herramientas necesarias para ejecutar como un ejecutor de Jenkins.

Crea una clave SSH para Cloud Shell

Más adelante en este instructivo, deberás usar Packer para compilar las imágenes, lo que requiere que el comando ssh se comunique con las instancias de compilación. Para habilitar el acceso SSH, crea y sube una clave SSH en Cloud Shell:

  1. Crea un par de Llaves SSH. Si ya existe uno, este comando usa ese par de llaves; de lo contrario, crea uno nuevo:

    ls ~/.ssh/id_rsa.pub || ssh-keygen -N ""
  2. Agrega la Llave SSH pública de Cloud Shell a los metadatos de tu proyecto:

    gcloud compute project-info describe \
        --format=json | jq -r '.commonInstanceMetadata.items[] | select(.key == "ssh-keys") | .value' > sshKeys.pub
    echo "$USER:$(cat ~/.ssh/id_rsa.pub)" >> sshKeys.pub
    gcloud compute project-info add-metadata --metadata-from-file ssh-keys=sshKeys.pub

Crea la imagen de referencia

El paso siguiente es usar Packer a fin de crear una imagen de máquina virtual (VM) de referencia para tus agentes de compilación, que actúan como ejecutores de compilación efímeros en Jenkins. El agente más básico de Jenkins solo requiere que Java esté instalado. Puedes personalizar la imagen si agregas comandos de shell en la sección provisioners de la configuración de Packer o si agregas otros aprovisionadores de Packer.

  1. En Cloud Shell, descarga y descomprime la versión más reciente de Packer. En el siguiente ejemplo, se usa Packer 1.6.6. Puedes consultar el sitio web de Hashicorp para ver si hay una versión más reciente:

    wget https://releases.hashicorp.com/packer/1.6.6/packer_1.6.6_linux_amd64.zip
    unzip packer_1.6.6_linux_amd64.zip
  2. Crea el archivo de configuración para tus compilaciones de imagen de Packer:

    export PROJECT=$(gcloud info --format='value(config.project)')
    cat > jenkins-agent.json <<EOF
    {
      "builders": [
        {
          "type": "googlecompute",
          "project_id": "$PROJECT",
          "source_image_family": "ubuntu-2004-lts",
          "source_image_project_id": "ubuntu-os-cloud",
          "zone": "us-central1-a",
          "disk_size": "10",
          "image_name": "jenkins-agent-{{timestamp}}",
          "image_family": "jenkins-agent",
          "ssh_username": "ubuntu"
        }
      ],
      "provisioners": [
        {
          "type": "shell",
          "inline": ["sudo apt-get update && sudo apt-get install -y default-jdk"]
        }
      ]
    }
    EOF
    
  3. Compila la imagen mediante la ejecución de Packer:

    ./packer build jenkins-agent.json

    Cuando se completa la compilación, el nombre de la imagen de disco se muestra con el formato jenkins-agent-[TIMESTAMP], en el que [TIMESTAMP] es la época en la que se inició la compilación.

    ==> Builds finished. The artifacts of successful builds are:
    --> googlecompute: A disk image was created: jenkins-agent-1612997575
    

Instala Jenkins

En esta sección, usarás Cloud Marketplace para aprovisionar una instancia de Jenkins. Personaliza esta instancia para usar la imagen de agente que creaste en la sección anterior.

  1. Ve a la solución de Cloud Marketplace para Jenkins.

  2. Haz clic en Iniciar.

  3. Cambia el campo Machine type (tipo de máquina) a 4 CPU virtuales 15 GB de memoria, n1-standard-4.

    Selección del tipo de máquina para la implementación de Jenkins

  4. Haz clic en Implementar y espera que termine el aprovisionamiento de tu instancia de Jenkins. Cuando termine, verás el siguiente mensaje:

    Se implementó Jenkins.

  5. Para abrir tu instancia de Jenkins en el navegador, haz clic en el vínculo Dirección del sitio (Site Address).

  6. Accede a Jenkins mediante el Usuario administrador (Admin user) y la Contraseña de administrador (Admin password) que se muestran en el panel de detalles.

    Panel de detalles con credenciales y otros detalles de implementación

La instancia de Jenkins ya está lista para usar.

Configura los complementos de Jenkins

Jenkins requiere complementos para crear agentes bajo demanda en Compute Engine y almacenar artefactos en Cloud Storage. Debes instalar y configurar estos complementos.

Instala complementos

  1. En la IU de Jenkins, selecciona Administrar Jenkins (Manage Jenkins).
  2. Haz clic en Administrar complementos (Manage Plugins).
  3. Haz clic en la pestaña Disponible (Available).
  4. Usa la barra de filtros para encontrar los siguientes complementos y selecciona las casillas junto a ellos:

    • Complemento de Compute Engine (Compute Engine plugin)
    • Complemento de Cloud Storage (Cloud Storage plugin)

    En la siguiente imagen, se muestra el complemento de Cloud Storage seleccionado:

    Complemento de Cloud Storage

  5. Haz clic en Download now and install after restart.

  6. Haz clic en la casilla de verificación de Restart Jenkins when installation is complete and no jobs are running. Jenkins reinicia y completa las instalaciones de complementos.

Crea credenciales de complementos

Debes crear Google Credentials para los complementos nuevos de la siguiente manera:

  1. Vuelve a acceder a Jenkins y haz clic en Jenkins.
  2. Haz clic en Credenciales (Credentials).
  3. Haz clic en Sistema (System).
  4. En el panel principal de la IU, haz clic en Credenciales globales (no restringido) (Global credentials [unrestricted]).
  5. Crea las credenciales de Google:

    1. Haz clic en Agregar credenciales (Add Credentials).
    2. Configura Kind (Tipo) como Google Service Account from private key (Cuenta de servicio de Google desde una clave privada).
    3. En el campo Project Name (Nombre del proyecto), ingresa el ID del proyecto de Google Cloud.
    4. Haz clic en Choose file.
    5. Selecciona el archivo jenkins-sa.json que descargaste antes desde Cloud Shell.
    6. Haz clic en OK.

      Credenciales de clave JSON

  6. Haz clic en Jenkins.

Configura el complemento de Compute Engine

Configura el complemento de Compute Engine con las credenciales que usa para aprovisionar tus instancias de agente.

  1. Haz clic en Administrar Jenkins (Manage Jenkins).
  2. Haz clic en Configurar sistema (Configure System).
  3. Haz clic en Agregar una nueva nube (Add a new Cloud).
  4. Haz clic en Compute Engine.
  5. Establece la siguiente configuración y reemplaza [YOUR_PROJECT_ID] por el ID del proyecto de Google Cloud:

    • Nombre: gce
    • Project ID (ID del proyecto): [YOUR_PROJECT_ID]
    • Límite de la instancia: 8
  6. Elige la cuenta de servicio de la lista desplegable Service Account Credentials. Se muestra como el ID del proyecto de Google Cloud.

Establece las opciones de configuración de la instancia de Jenkins

Ahora que el complemento de Compute Engine está configurado, puedes establecer las opciones de configuración de la instancia de Jenkins para las diversas opciones de configuración de compilación que desees.

  1. En la página Configure System, haz clic en Add para acceder a Instance Configurations.
  2. Ingresa la siguiente configuración general:

    • Name (Nombre): ubuntu-2004
    • Description (Descripción): Ubuntu agent
    • Labels (Etiquetas): ubuntu-2004
  3. Ingresa lo siguiente para la configuración de Location (Ubicación):

    • Region (Región): us-central1
    • Zone (Zona): us-central1-f
  4. Haz clic en Advanced.

  5. Para Configuración de la máquina (Machine Configuration), elige el Tipo de máquina (Machine Type) de n1-standard-1.

  6. En Herramientas de redes (Networking), elige la siguiente configuración:

    • Red (Network): déjalo en la configuración predeterminada.
    • Subred (Subnetwork): déjalo en la configuración predeterminada.
    • Selecciona ¿Adjuntar IP externa? (Attach External IP?).
  7. Selecciona lo siguiente para la configuración del Disco de arranque:

    • En Proyecto de la imagen, elige el proyecto de Google Cloud.
    • En Nombre de la imagen, selecciona la imagen que creaste antes con Packer.
  8. Haz clic en Save (Guardar) para conservar los cambios de configuración.

    Configuración de Compute Engine para Jenkins

Crea un trabajo de Jenkins para probar la configuración

Jenkins está configurado para iniciar una instancia de forma automática cuando se activa un trabajo que requiere un agente con la etiqueta ubuntu-2004. Crea un trabajo que compruebe si la configuración funciona como se espera.

  1. Haz clic en Create new job en la interfaz de Jenkins.
  2. Ingresa test como el nombre del elemento.
  3. Haz clic en Freestyle project y, luego, haz clic en OK.
  4. Selecciona los cuadros Execute concurrent builds if necessary y Restrict where this project can run.
  5. En el campo Expresión de la etiqueta, ingresa ubuntu-2004.
  6. En la sección Compilación, haz clic en Agregar paso de compilación.
  7. Haz clic en Ejecutar Shell.
  8. En el cuadro de comandos, ingresa una string de prueba:

    echo "Hello world!"

    “Hello World” escrito en el cuadro de comandos para Jenkins.

  9. Haz clic en Save (Guardar).

  10. Haz clic en Compilar ahora para iniciar una compilación.

    Compilar ahora.

Sube artefactos de compilación a Cloud Storage

Tal vez quieres almacenar artefactos de compilación para análisis o pruebas futuros. Configura tu trabajo de Jenkins para generar un artefacto y subirlo a Cloud Storage. El registro de compilación se sube al mismo bucket.

  1. En Cloud Shell, crea un bucket de almacenamiento para tus artefactos:

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb gs://$PROJECT-jenkins-artifacts
  2. En la lista de trabajos en la IU de Jenkins, haz clic en probar (test).

  3. Haz clic en Configurar (Configure).

  4. En Compilar (Build), configura el campo de texto Comando (Command) de la siguiente manera:

    env > build_environment.txt
  5. En Acciones posteriores a la compilación (Post-build Actions), haz clic en Agregar acción posterior a la compilación (Add post-build action).

  6. Haz clic en Cloud Storage Plugin.

  7. En el campo Storage Location, ingresa la ruta del artefacto y reemplaza el ID del proyecto de Google Cloud por [YOUR_PROJECT_ID]:

    gs://[YOUR_PROJECT_ID]-jenkins-artifacts/$JOB_NAME/$BUILD_NUMBER
  8. Haz clic en Add Operation.

  9. Haz clic en Classic upload (Carga clásica).

  10. En el campo File Pattern, ingresa build_environment.txt.

  11. En el campo Storage Location, ingresa la ruta de almacenamiento y reemplaza el ID del proyecto de Google Cloud por [YOUR_PROJECT_ID]:

    gs://[YOUR_PROJECT_ID]-jenkins-artifacts/$JOB_NAME/$BUILD_NUMBER

    Acciones posteriores a la compilación para el complemento de Cloud Storage

  12. Haz clic en Save (Guardar).

  13. Haz clic en Compilar ahora (Build Now) para iniciar una nueva compilación. La compilación se ejecuta en la instancia de Compute Engine que aprovisionaste antes. Cuando se completa la compilación, se sube el archivo del artefacto, build_environment.txt, al bucket de Cloud Storage especificado.

  14. En Cloud Shell, puedes ver el artefacto de compilación mediante gsutil:

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil cat gs://$PROJECT-jenkins-artifacts/test/2/build_environment.txt

Configura la administración del ciclo de vida de los objetos

Es posible que accedas a artefactos de compilación recientes. Para ahorrar gastos en objetos a los que se accede con poca frecuencia, usa la Administración del ciclo de vida de los objetos a fin de mover los artefactos de clases de almacenamiento de mayor rendimiento a clases de menor costo y mayor latencia.

  1. En Cloud Shell, crea el archivo de configuración del ciclo de vida para transferir todos los objetos al almacenamiento de Nearline después de 30 días, y los objetos de Nearline al almacenamiento de Coldline después de 365 días.

    cat > artifact-lifecycle.json <<EOF
    {
    "lifecycle": {
      "rule": [
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "NEARLINE"
        },
        "condition": {
          "age": 30,
          "matchesStorageClass": ["MULTI_REGIONAL", "STANDARD", "DURABLE_REDUCED_AVAILABILITY"]
        }
      },
      {
        "action": {
          "type": "SetStorageClass",
          "storageClass": "COLDLINE"
        },
        "condition": {
          "age": 365,
          "matchesStorageClass": ["NEARLINE"]
        }
      }
    ]
    }
    }
    EOF
  2. Sube el archivo de configuración a tu bucket de almacenamiento de artefactos:

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil lifecycle set artifact-lifecycle.json gs://$PROJECT-jenkins-artifacts

Limpieza

  1. Borra cualquier agente de Jenkins que siga en ejecución:

    gcloud compute instances list --filter=metadata.jclouds-group=ubuntu-1604 --uri | xargs gcloud compute instances delete
  2. Borra la instancia de Jenkins con Cloud Deployment Manager:

    gcloud deployment-manager deployments delete jenkins-1
  3. Borra el bucket de Cloud Storage:

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil -m rm -r gs://$PROJECT-jenkins-artifacts
  4. Borra la cuenta de servicio:

    export SA_EMAIL=$(gcloud iam service-accounts list --filter="displayName:jenkins" --format='value(email)')
    gcloud iam service-accounts delete $SA_EMAIL

Pasos siguientes