Acceder a recursos en un JFrog Artifactory privado con grupos privados

En esta página se explica cómo usar grupos privados de Cloud Build para acceder a recursos de una red de nube privada virtual privada.

En este tutorial, crearás un JFrog Artifactory en Compute Engine alojado en una red VPC privada y, a continuación, configurarás una compilación que se ejecute en un grupo privado para acceder a los datos de ese Artifactory. Jfrog Artifactory es un gestor de repositorios binarios de código abierto.

Crea el Artifactory privado

  1. Crea una instancia de Compute Engine a partir de un contenedor:

    gcloud compute instances create-with-container jfrog \
    --container-image docker.bintray.io/jfrog/artifactory-jcr:latest \
    --zone us-central1-a
    
  2. Accede a la instancia mediante SSH. El contenedor puede tardar un par de minutos en inicializarse.

    gcloud compute ssh --zone us-central1-a jfrog
    
  3. Prueba la conexión ejecutando el siguiente comando. Una vez que el contenedor esté listo, responderá con un código HTTP 200, seguido de una página HTML.

    curl -i http://localhost:8081
    
  4. Para crear un repositorio en Artifactory, debes firmar el ALUF (Acuerdo de Licencia de Usuario Final) de JFrog:

    curl -XPOST -vu admin:password http://localhost:8081/artifactory/ui/jcr/eula/accept
    

    Verá un resultado similar al siguiente:

        *   Trying 127.0.0.1:8081...
        * Connected to localhost (127.0.0.1) port 8081 (#0)
        * Server auth using Basic with user 'admin'
        > POST /artifactory/ui/jcr/eula/accept HTTP/1.1
        > Host: localhost:8081
        > Authorization: Basic ….
        > User-Agent: curl/7.74.0
        > Accept: */*
        >
        * Mark bundle as not supporting multiuse
        < HTTP/1.1 200 OK
        < X-JFrog-Version: Artifactory/7.19.9 71909900
        < X-Artifactory-Id: ….
        < X-Artifactory-Node-Id: jfrog2
        < SessionValid: false
        < Content-Length: 0
        < Date: Fri, 25 Jun 2021 19:08:10 GMT
    
        * Connection #0 to host localhost left intact
    

Subir un archivo a Artifactory

  1. Crea un archivo txt para subirlo a Artifactory:

    echo "Hello world" >> helloworld.txt
    
  2. JFrog incluye un repositorio de ejemplo predeterminado. Sube el contenido al repositorio con las credenciales predeterminadas:

    curl -u admin:password -X PUT \
    "http://localhost:8081/artifactory/example-repo-local/helloworld.txt" \
    -T helloworld.txt
    

    Debería devolver lo siguiente:

        {
        "repo" : "example-repo-local",
        "path" : "/helloworld.txt",
        "created" : "2021-06-25T19:08:24.176Z",
        "createdBy" : "admin",
        "downloadUri" : "http://localhost:8081/artifactory/example-repo-local/helloworld.txt",
        "mimeType" : "text/plain",
        "size" : "12",
        "checksums" : {
          "sha1" : "...",
          "md5" : "...",
          "sha256" : "..."
        },
        "originalChecksums" : {
          "sha256" : "..."
        },
        "uri" : "http://localhost:8081/artifactory/example-repo-local/helloworld.txt"
        }
    
  3. Finaliza la sesión SSH escribiendo exit.

  4. Quita la dirección IP externa para que solo se pueda acceder a Artifactory desde fuentes internas privadas.

    gcloud compute instances delete-access-config --zone us-central1-a jfrog
    

Prueba a acceder a los datos desde Artifactory

  1. Define variables de entorno para almacenar el ID y el número de tu proyecto:

    PROJECT_ID=$(gcloud config list --format='value(core.project)')
    PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
  2. Concede el rol Lector de Compute Engine a la cuenta de servicio que estés usando para que la compilación pueda ver la dirección IP interna de tu instancia de JFrog:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member=serviceAccount:SERVICE_ACCOUNT \
        --role=roles/compute.viewer
    

    Donde SERVICE_ACCOUNT es el correo de la cuenta de servicio.

  3. Crea un archivo llamado cloudbuild.yaml que contenga el siguiente código para leer de Artifactory. Este es el archivo de configuración de compilación.

    En el primer paso se obtiene la dirección IP interna del Artifactory que has creado. En el segundo paso, se envía una solicitud a esa dirección para leer el archivo helloworld.txt que has creado. Los pasos se han separado para que sea más fácil aislar los errores de permisos y de redes. Si el primer paso falla, se debe a un error de permisos y tendrás que asegurarte de que la cuenta de servicio de compilación tenga acceso a los recursos de Compute Engine, tal como se muestra en el paso anterior. Si el segundo paso falla, se debe a un error de red. El resto de este tutorial trata sobre las configuraciones de red.

    steps:
      - id: Get Private Artifactory Address
        name: gcr.io/cloud-builders/gcloud
        entrypoint: /bin/bash
        args: 
          - -c
          - |
            gcloud compute instances describe jfrog \
            --zone us-central1-a \
            --format="value(networkInterfaces.networkIP)" >> _INTERNAL_IP_ADDRESS
    
      - id: Pull from Private Artifactory
        name: gcr.io/cloud-builders/curl
        entrypoint: /bin/bash
        args:
          - -c
          - |
            curl -u admin:password --connect-timeout 10.00 \
            http://$(cat _INTERNAL_IP_ADDRESS):8081/artifactory/example-repo-local/helloworld.txt
  4. Inicia una compilación con el archivo de configuración de compilación.

    De forma predeterminada, cuando ejecutas una compilación en Cloud Build, esta se ejecuta en un entorno alojado seguro con acceso a Internet público. Cada compilación se ejecuta en su propio trabajador y está aislada de otras cargas de trabajo. El grupo predeterminado tiene límites en cuanto a la personalización del entorno, sobre todo en lo que respecta al acceso a redes privadas. En este ejemplo, intentas acceder a una red privada desde un trabajador público.

    Ejecuta cloudbuild.yaml con el siguiente comando. Debería fallar.

    gcloud builds submit --no-source
    

    La salida será similar a la siguiente:

    BUILD
    Starting Step #0 - "Get Private Artifactory Address"
    Step #0 - "Get Private Artifactory Address": Already have image (with digest): gcr.io/cloud-builders/gcloud
    Finished Step #0 - "Get Private Artifactory Address"
    Starting Step #1 - "Pull from Private Artifactory"
    Step #1 - "Pull from Private Artifactory": Already have image (with digest): gcr.io/cloud-builders/curl
    Step #1 - "Pull from Private Artifactory":   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
    Step #1 - "Pull from Private Artifactory":                                  Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:--  0:02:09 --:--:--     0curl: (7) Failed to connect to 10.128.0.2 port 8081: Connection timed out
    Finished Step #1 - "Pull from Private Artifactory"
    ERROR
    ERROR: build step 1 "gcr.io/cloud-builders/curl" failed: step exited with non-zero status: 7
    

    Puedes ver que Cloud Build no puede acceder a la dirección IP interna por el tiempo de espera de la conexión. Para acceder a este recurso privado, debes usar grupos privados de Cloud Build.

Crea una conexión privada entre la red de VPC de Artifactory y la red del productor de servicios

  1. Primero, asegúrate de que tu red de VPC permita el acceso. Crea una regla de cortafuegos para permitir el tráfico interno entrante a la red con la instancia jfrog. El intervalo 10.0.0.0/16 está en un espacio de direcciones privadas, que usarás para los grupos privados de Cloud Build en los pasos siguientes.

    gcloud compute firewall-rules create allow-private-pools --direction=INGRESS \
    --priority=1000 --network=default --action=ALLOW --rules=all --source-ranges=10.0.0.0/16
    
  2. Crea un intervalo reservado para que el grupo privado de Cloud Build lo utilice para los trabajadores. El intervalo reservado debe estar en la red en la que se encuentre tu Artifactory. En este caso, se trata de la red informática default.

    Tienes dos opciones al definir tus intervalos reservados. Puedes especificar el intervalo de forma explícita proporcionando --addresses y --prefix-length, o bien permitir que Google Cloud aprovisione un intervalo disponible en función de un prefix-length proporcionado.

    En el ejemplo siguiente, se definen explícitamente las direcciones para que coincidan con la regla de cortafuegos que ha creado. El grupo privado usará este espacio de direcciones y el tráfico entrante no se bloqueará.

    gcloud compute addresses create jfrog-ranges --global --purpose=VPC_PEERING \
    --addresses=10.0.0.0 --prefix-length=16 --network=default
    
  3. Empareja la red de VPC con la API Service Networking.

    Los grupos privados de Cloud Build ejecutan los workers mediante la API Service Networking. Esto te permite ofrecer tus servicios gestionados en direcciones IP internas. Para ello, se empareja la VPC gestionada por Google que ejecuta los trabajadores del grupo privado de Cloud Build con tu propia VPC. Este proceso puede tardar unos minutos en completarse.

    gcloud services vpc-peerings connect --service=servicenetworking.googleapis.com \
    --ranges=jfrog-ranges --network=default
    

Crear el grupo privado

  1. La red de VPC default ya se puede usar con grupos privados de Cloud Build. Crea el grupo privado y empareja la red de VPC.

     gcloud builds worker-pools create jfrog-pool --region us-central1 \
     --peered-network=projects/${PROJECT_ID}/global/networks/default
    
  2. Para ejecutar la compilación con el nuevo grupo privado, puedes usar la marca --worker-pool con el comando gcloud o actualizar la configuración de cloudbuild.yaml para asegurarte de que siempre se usa el grupo privado. En este tutorial, actualiza el cloudbuild.yaml añadiendo la siguiente opción:

    options:
      pool:
        name: 'projects/${PROJECT_ID}/locations/us-central1/workerPools/jfrog-pool'
  3. El archivo completo tendrá este aspecto:

    steps:
      - id: Get Private Artifactory Address
        name: gcr.io/cloud-builders/gcloud
        entrypoint: /bin/bash
        args: 
          - -c
          - |
            gcloud compute instances describe jfrog \
            --zone us-central1-a \
            --format="value(networkInterfaces.networkIP)" >> _INTERNAL_IP_ADDRESS
    
      - id: Pull from Private Artifactory
        name: gcr.io/cloud-builders/curl
        entrypoint: /bin/bash
        args:
          - -c
          - |
            curl -u admin:password --connect-timeout 10.00 \
            http://$(cat _INTERNAL_IP_ADDRESS):8081/artifactory/example-repo-local/helloworld.txt
    
    options:
      pool:
        name: 'projects/${PROJECT_ID}/locations/us-central1/workerPools/jfrog-pool'
  4. Inicia la compilación:

     gcloud builds submit --no-source
    
  5. La compilación usará el nuevo grupo privado, emparejado con la red de VPC, lo que le permitirá acceder a la dirección IP interna de Artifactory. La salida será correcta y Step #1 debería imprimir "Hello world".