Asegurar la disponibilidad de recursos con reservas de VMs

En este documento se explica cómo crear tareas que se ejecuten en recursos reservados y cómo evitar que las tareas consuman reservas.

Las reservas son una función de Compute Engine. Las reservas ofrecen un nivel de garantía muy alto para obtener capacidad para una o varias máquinas virtuales con la configuración de hardware especificada. Una reserva de una VM conlleva los costes de esa VM desde el momento en que creas la reserva hasta que la eliminas. Sin embargo, mientras consumas esa máquina virtual, el coste total será equivalente al de una máquina virtual sin reserva.

Por lo general, las reservas son útiles cuando la disponibilidad de capacidad es fundamental o para evitar errores al obtener recursos. En el caso de Batch, te recomendamos que uses reservas dedicadas para minimizar el tiempo de programación de las tareas o que intentes usar las reservas que ya tengas cuando no las estés usando. Si tienes reservas infrautilizadas, como las que se requieren para los descuentos por compromiso de uso, puedes configurar trabajos para que intenten consumirlas mientras no se estén usando. De esta forma, podrás optimizar los costes incurridos. Si quieres priorizar la disponibilidad de recursos para otras cargas de trabajo de tu proyecto, puedes bloquear explícitamente que una tarea consuma reservas.

Para obtener más información sobre las reservas, consulta la documentación de Compute Engine sobre reservas.

Antes de empezar

  1. Si no has usado Batch antes, consulta el artículo Empezar a usar Batch y habilita Batch completando los requisitos previos para proyectos y usuarios.
  2. Asegúrate de que tienes los permisos para crear una reserva o ver una reserva que ya exista que quieras que usen las VMs de un trabajo según sea necesario.
  3. Para obtener los permisos que necesitas para crear un trabajo, pide a tu administrador que te conceda los siguientes roles de gestión de identidades y accesos:

    Para obtener más información sobre cómo conceder roles, consulta el artículo Gestionar el acceso a proyectos, carpetas y organizaciones.

    También puedes conseguir los permisos necesarios a través de roles personalizados u otros roles predefinidos.

Restricciones

Además de las restricciones generales de las reservas, Batch también tiene las siguientes restricciones:

  • Las VMs de un trabajo no pueden consumir reservas compartidas.
  • Las VMs de un trabajo no pueden consumir reservas si se especifica una política de emplazamiento compacto.
  • Si creas un trabajo con la consola de Google Cloud , sus VMs consumirán automáticamente las reservas coincidentes. Para usar una reserva o un bloque específicos, o bien para evitar que las VMs usen reservas, debes definir el campo reservation al crear un trabajo con la CLI de gcloud o la API Batch.

Requisitos

En esta sección se resumen los requisitos para que las VMs de un trabajo consuman una reserva. Para obtener más información sobre todos los requisitos, consulta los requisitos generales de las reservas en la documentación de Compute Engine y el procedimiento para planificar tu configuración más adelante en este documento.

  • Para que las VMs de un trabajo puedan consumir una reserva, deben cumplirse todas las condiciones siguientes:

    • El trabajo y la reserva deben especificar propiedades de VM que coincidan exactamente.

    • Debes cumplir todas las restricciones de este documento y todos los demás requisitos generales para las reservas.

  • Para que cada una de las VMs de un trabajo pueda usar una reserva, esta debe tener capacidad disponible durante el tiempo de ejecución de la VM.

    La capacidad no utilizada de una reserva es la diferencia entre el número de VMs y el número de VMs que la están consumiendo en ese momento. Las VMs intentan consumir reservas siempre que tengas capacidad de reserva sin usar. Por lo tanto, una VM puede empezar a consumir una reserva cuando se crea o más adelante durante su tiempo de ejecución. Una VM no deja de consumir una reserva hasta que se detiene o se elimina la reserva.

    En función de la capacidad de reserva total que no hayas usado, es posible que ninguna, algunas o todas las VMs de un trabajo consuman reservas, y la cantidad de VMs reservadas puede variar durante el tiempo de ejecución del trabajo.

Crear y ejecutar un trabajo que pueda consumir VMs reservadas

  1. Planifica tu configuración. Para asegurarte de que tu trabajo y tu reserva son compatibles, sigue estos pasos.

    Si quieres consumir una reserva que ya existe, debes crear un trabajo con la configuración correspondiente. De lo contrario, si tienes previsto crear una reserva, selecciona las opciones de configuración que prefieras.

    1. Determina las propiedades de la reserva. Debido a las restricciones, el tipo de uso compartido debe ser de un solo proyecto, que es la opción predeterminada de una reserva. Determina los valores que quieras usar para las siguientes propiedades de reserva:

      • Tipo de consumo*
      • Número de VMs

      *El tipo de consumo de la reserva (específicamente segmentado o consumido automáticamente) determina qué VMs pueden consumir la reserva.

      El recuento de VMs representa la capacidad total de una reserva. Al decidir este valor, ten en cuenta el número de máquinas virtuales del trabajo.

    2. Determina las propiedades de la VM para el trabajo y la reserva. Debido a las restricciones, ni el trabajo ni la reserva pueden especificar una política de colocación compacta, que es la opción predeterminada tanto para las reservas como para los trabajos. Determina los valores que quieres usar para las siguientes propiedades de la VM, que deben coincidir exactamente con los de la reserva y el trabajo:

      • Proyecto
      • Zona*
      • Tipo de máquina
      • Plataforma de CPU mínima (si procede)
      • Tipo y número de GPUs (si hay alguna)
      • Tipo y número de SSD local (si hay alguna)
      • Afinidad de reserva#

      *Las VMs de trabajo deben estar en la misma zona que las VMs reservadas. Debes incluir esta zona en el campo allowedLocations[] del trabajo o, si omites el campo allowedLocations[], definir la ubicación del trabajo en la región que contiene esta zona.

      La tarea debe definir todas estas propiedades mediante los subcampos policy o una plantilla de instancia de VM. Una tarea no puede especificar una combinación de subcampos policy y una plantilla.

      No se puede definir un campo opcional para un recurso y omitirlo en otro. Define u omite el campo opcional tanto para la reserva como para el trabajo. Si el trabajo especifica una plantilla de instancia de VM, esto también se aplica a los campos de la plantilla especificada.

      #El tipo de consumo de la reserva determina la afinidad de la reserva necesaria para las VMs del trabajo, que debes especificar en el trabajo de la siguiente manera:

      • Si el trabajo usa una plantilla de instancia de VM, la plantilla debe configurar la afinidad de la reserva, tal como se explica en la documentación de reservas.
      • Si el trabajo no usa una plantilla y la reserva está dirigida a un público específico, indica el nombre de la reserva en el campo reservation del trabajo.
      • De lo contrario, si el trabajo no usa una plantilla y la reserva se consume automáticamente, omite el campo reservation del trabajo.
  2. Prepara la reserva. Si aún no lo has hecho, crea la reserva que quieres que usen las VMs del trabajo. Asegúrate de que la reserva tenga las propiedades que habías previsto.

  3. Crea y ejecuta el trabajo. Puedes crear y ejecutar una tarea que consuma máquinas virtuales de la reserva preparada mediante la CLI de gcloud o la API de Batch:

    gcloud

    1. Crea un archivo JSON que especifique los detalles de configuración del trabajo que defina los subcampos recurso de instancia de VM (instances[]) para que coincidan exactamente con las propiedades de la VM de una reserva.

      Por ejemplo, para crear un trabajo de secuencia de comandos básico que consuma máquinas virtuales de una reserva, crea un archivo JSON con el siguiente contenido:

      {
        "taskGroups": [
          {
            "taskSpec": {
              "runnables": [
                {
                  "script": {
                    "text": "echo Hello world from task ${BATCH_TASK_INDEX}"
                  }
                }
              ]
            },
            "taskCount": 3
          }
        ],
        "allocationPolicy": {
          "instances": [
            {
              VM_RESOURCES
            }
          ],
        },
        "logsPolicy": {
          "destination": "CLOUD_LOGGING"
        }
      }
      

      Sustituye VM_RESOURCES por los recursos de VM que coincidan con la reserva que quieras que consuma el trabajo. Para ello, especifica los subcampos instances[] que hayas planificado en los pasos anteriores.

      Por ejemplo, empieza con el siguiente valor de VM_RESOURCES:

      "installGpuDrivers": INSTALL_GPU_DRIVERS,
      "policy": {
        "machineType": "MACHINE_TYPE",
        "minCpuPlatform": "MIN_CPU_PLATFORM",
        "accelerators": [
          {
            "type": "GPU_TYPE",
            "count": GPU_COUNT
          }
        ],
        "disks": [
          {
            "newDisk": {
              "sizeGb": LOCAL_SSD_SIZE,
              "type": "local-ssd"
            },
            "deviceName": "LOCAL_SSD_NAME"
          }
        ],
        "reservation": "SPECIFIC_RESERVATION_NAME"
      }
      

      Para usar este valor, haz todos los cambios siguientes:

      1. ¿Quieres usar una plantilla de instancia?

        • Sí: sustituye el campo policy por el campo instanceTemplate y especifica una plantilla de instancia de VM que coincida con la reserva. Por ejemplo, consulta el código de muestra para usar una plantilla de instancia de máquina virtual. Si la reserva usa GPUs o SSDs locales, también debes configurar los campos installGpuDrivers y volumes[] del trabajo, respectivamente. De lo contrario, omite los cambios restantes.

        • No: sustituye MACHINE_TYPE por el mismo tipo de máquina que la reserva.

      2. ¿La reserva incluye una plataforma de CPU mínima?

        • Sí: sustituye MIN_CPU_PLATFORM por la misma plataforma de CPU mínima.

        • No: elimina el campo minCpuPlatform.

      3. ¿La reserva incluye GPUs?

        • Sí: sustituye INSTALL_GPU_DRIVERS, GPU_TYPE y GPU_COUNT para que coincidan con la reserva. Por ejemplo, consulta el código de muestra para usar GPUs.

        • No: elimina el campo installGpuDrivers y el campo accelerators[].

      4. ¿La reserva incluye SSDs locales?

        • Sí: sustituye LOCAL_SSD_SIZE y LOCAL_SSD_NAME para que coincidan con la reserva y monta los SSD locales añadiendo el campo volumes[] al trabajo. Por ejemplo, consulta el código de muestra para usar SSDs locales.

        • No: elimina el campo disks[].

      5. ¿La reserva usa el tipo de consumo segmentado específicamente?

        • Sí: sustituye SPECIFIC_RESERVATION_NAME por el nombre de la reserva.

        • No: elimina el campo reservation.

      Por ejemplo, supongamos que utilizas una reserva de n2-standard-32 VMs que se consume automáticamente y que no especifica ninguna plataforma de CPU mínima, GPU ni SSD local. Además, no quieres especificar una plantilla de instancia de VM. En ese caso, debes sustituir VM_RESOURCES por el siguiente valor:

      "policy": {
        "machineType": "n2-standard-32"
      }
      
    2. Para crear y ejecutar el trabajo, usa el comando gcloud batch jobs submit:

      gcloud batch jobs submit JOB_NAME \
        --location LOCATION \
        --config JSON_CONFIGURATION_FILE
      

      Haz los cambios siguientes:

      • JOB_NAME: el nombre del puesto.

      • LOCATION: la ubicación del puesto. A menos que el trabajo especifique el campo allowedLocations[], debe ser la región que contenga la zona de la reserva.

      • JSON_CONFIGURATION_FILE: la ruta de un archivo JSON con los detalles de configuración del trabajo.

    API

    Haz una solicitud POST al método jobs.create que defina los subcampos del recurso de instancia de VM (instances[]) para que coincidan exactamente con las propiedades de VM de una reserva.

    Por ejemplo, para crear un trabajo de secuencia de comandos básico que consuma VMs de una reserva, haz la siguiente solicitud:

    POST https://batch.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/jobs?job_id=JOB_NAME
    {
      "taskGroups": [
        {
          "taskSpec": {
            "runnables": [
              {
                "script": {
                  "text": "echo Hello world from task ${BATCH_TASK_INDEX}"
                }
              }
            ]
          },
          "taskCount": 3
        }
      ],
      "allocationPolicy": {
        "instances": [
          {
            VM_RESOURCES
          }
        ],
      },
      "logsPolicy": {
        "destination": "CLOUD_LOGGING"
      }
    }
    

    Haz los cambios siguientes:

    • PROJECT_ID: el ID de proyecto de tu proyecto.

    • LOCATION: la ubicación del puesto. A menos que el trabajo especifique el campo allowedLocations[], debe ser la región que contenga la zona de la reserva.

    • JOB_NAME: el nombre del puesto.

    • VM_RESOURCES: los recursos de VM que coincidan con la reserva que quieras que consuma el trabajo especificando los subcampos instances[] que hayas planificado en los pasos anteriores.

      Por ejemplo, empieza con el siguiente valor de VM_RESOURCES:

      "installGpuDrivers": INSTALL_GPU_DRIVERS,
      "policy": {
        "machineType": "MACHINE_TYPE",
        "minCpuPlatform": "MIN_CPU_PLATFORM",
        "accelerators": [
          {
            "type": "GPU_TYPE",
            "count": GPU_COUNT
          }
        ],
        "disks": [
          {
            "newDisk": {
              "sizeGb": LOCAL_SSD_SIZE,
              "type": "local-ssd"
            },
            "deviceName": "LOCAL_SSD_NAME"
          }
        ],
        "reservation": "SPECIFIC_RESERVATION_NAME"
      }

      Para usar este valor, haz todos los cambios siguientes:

      1. ¿Quieres usar una plantilla de instancia?

        • Sí: sustituye el campo policy por el campo instanceTemplate y especifica una plantilla de instancia de VM que coincida con la reserva. Por ejemplo, consulta el código de muestra para usar una plantilla de instancia de máquina virtual. Si la reserva usa GPUs o SSDs locales, también debes configurar los campos installGpuDrivers y volumes[] del trabajo, respectivamente. De lo contrario, omite los cambios restantes.

        • No: sustituye MACHINE_TYPE por el mismo tipo de máquina que la reserva.

      2. ¿La reserva incluye una plataforma de CPU mínima?

        • Sí: sustituye MIN_CPU_PLATFORM por la misma plataforma de CPU mínima.

        • No: elimina el campo minCpuPlatform.

      3. ¿La reserva incluye GPUs?

        • Sí: sustituye INSTALL_GPU_DRIVERS, GPU_TYPE y GPU_COUNT para que coincidan con la reserva. Por ejemplo, consulta el código de muestra para usar GPUs.

        • No: elimina el campo installGpuDrivers y el campo accelerators[].

      4. ¿La reserva incluye SSDs locales?

        • Sí: sustituye LOCAL_SSD_SIZE y LOCAL_SSD_NAME para que coincidan con la reserva y monta los SSD locales añadiendo el campo volumes[] al trabajo. Por ejemplo, consulta el código de muestra para usar SSDs locales.

        • No: elimina el campo disks[].

      5. ¿La reserva usa el tipo de consumo segmentado específicamente?

        • Sí: sustituye SPECIFIC_RESERVATION_NAME por el nombre de la reserva.

        • No: elimina el campo reservation.

      Por ejemplo, supongamos que utilizas una reserva de n2-standard-32 VMs que se consume automáticamente y que no especifica ninguna plataforma de CPU mínima, GPU ni SSD local. Además, no quieres especificar una plantilla de instancia de VM. En ese caso, debes sustituir VM_RESOURCES por el siguiente valor:

      "policy": {
        "machineType": "n2-standard-32"
      }

Crear y ejecutar un trabajo que no pueda consumir VMs reservadas

Para evitar que un trabajo consuma reservas, asigna el valor NO_RESERVATION al campo reservation. Para obtener más información sobre cómo evitar que se consuman reservas, consulta el artículo Evitar que las instancias de proceso consuman reservas de la documentación de Compute Engine.

Puedes crear y ejecutar una tarea que no pueda consumir ninguna VM reservada mediante la CLI de gcloud o la API Batch.

gcloud

  1. Crea un archivo JSON que especifique los detalles de configuración del trabajo y defina el campo reservation como NO_RESERVATION.

    Por ejemplo, para crear un trabajo de secuencia de comandos básico que no pueda usar reservas, crea un archivo JSON con el siguiente contenido:

    {
      "taskGroups": [
        {
          "taskSpec": {
            "runnables": [
              {
                "script": {
                  "text": "echo Hello world from task ${BATCH_TASK_INDEX}"
                }
              }
            ]
          },
          "taskCount": 3
        }
      ],
      "allocationPolicy": {
        "instances": [
          {
            "policy": {
              "reservation": "NO_RESERVATION"
            }
          }
        ],
      },
      "logsPolicy": {
        "destination": "CLOUD_LOGGING"
      }
    }
    
  2. Para crear y ejecutar el trabajo, usa el comando gcloud batch jobs submit:

    gcloud batch jobs submit JOB_NAME \
      --location LOCATION \
      --config JSON_CONFIGURATION_FILE
    

    Haz los cambios siguientes:

    • JOB_NAME: el nombre del puesto.

    • LOCATION: la ubicación del puesto.

    • JSON_CONFIGURATION_FILE: la ruta de un archivo JSON con los detalles de configuración del trabajo.

API

Haz una solicitud POST al método jobs.create que asigne el valor NO_RESERVATION al campo reservation.

Por ejemplo, para crear un trabajo de script básico que no pueda consumir reservas, haz la siguiente solicitud:

POST https://batch.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/jobs?job_id=JOB_NAME

{
  "taskGroups": [
    {
      "taskSpec": {
        "runnables": [
          {
            "script": {
              "text": "echo Hello world from task ${BATCH_TASK_INDEX}"
            }
          }
        ]
      },
      "taskCount": 3
    }
  ],
  "allocationPolicy": {
    "instances": [
      {
        "policy": {
          "reservation": "NO_RESERVATION"
        }
      }
    ],
  },
  "logsPolicy": {
    "destination": "CLOUD_LOGGING"
  }
}

Haz los cambios siguientes:

Siguientes pasos