En este documento, se supone que estás familiarizado con los siguientes productos:
- Entorno de ejecución de Python para Cloud Functions
- Entorno de ejecución de Node.js 8 para Cloud Functions
- Políticas de alertas de Monitoring
- API de RESTful
Objetivos
- Borra las direcciones IP sin usar: en Google Cloud, las direcciones IP estáticas son un recurso gratuito cuando se conectan a una instancia de máquina virtual o balanceador de cargas. Cuando se reserva una dirección IP estática, pero no se utiliza, se acumula un cargo por hora. En las aplicaciones que dependen en gran medida de direcciones IP estáticas y de aprovisionamiento dinámico a gran escala, ese desperdicio puede aumentar de forma significativa con el paso del tiempo.
- Borra discos persistentes huérfanos o sin usar: los discos persistentes no se usan o quedan huérfanos si se crean sin estar conectados a una VM, o si una máquina tiene varios discos y uno o más discos desconectados.
- Migra a clases de almacenamiento menos costosas: Google Cloud ofrece varias clases de almacenamiento de objetos. Usa la clase que mejor se adapte a tus necesidades.
Arquitectura
En el siguiente diagrama, se describe la primera parte de la implementación, en la que programas una función de Cloud Functions para identificar y limpiar las direcciones IP que no se usan.
En el primer ejemplo, se tratan estos objetivos:
- Crear una VM de Compute Engine con una dirección IP externa estática y una dirección IP externa estática separada sin usar
- Implementar una función de Cloud Functions para identificar direcciones sin usar
- Crear un trabajo de Cloud Scheduler para programar la función a fin de que se ejecute con un activador HTTP
En el siguiente diagrama, programa una función de Cloud Functions para identificar y limpiar discos persistentes sin conexión y huérfanos.
En el segundo ejemplo, se tratan estos objetivos:
- Crear una VM de Compute Engine con dos discos persistentes y un disco persistente separado sin conectar. Uno de los discos es huérfano por estar desconectado de la VM
- Implementar una función de Cloud Functions para identificar discos persistentes sin conexión y huérfanos
- Crear un trabajo de Cloud Scheduler para programar la ejecución de la función de Cloud Functions con un activador HTTP
Según el siguiente diagrama, activará una Cloud Function para migrar un bucket de almacenamiento desde una política de alertas de Monitoring hacia una clase de almacenamiento menos costosa.
En el tercer ejemplo, se tratan estos objetivos:
- Crear dos bucket s de almacenamiento, agregar un archivo al bucket de entrega y generar tráfico en él
- Crear un panel de Monitoring para visualizar el uso del bucket
- Implementar una función de Cloud Functions para migrar el bucket inactivo a una clase de almacenamiento menos costosa
- Activar la función mediante una carga útil destinada a simular una notificación recibida de una política de alertas de Monitoring
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
- 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.
-
En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
Habilita las API de Compute Engine, Cloud Functions, and Cloud Storage.
-
En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
Habilita las API de Compute Engine, Cloud Functions, and Cloud Storage.
-
En la consola de Google Cloud, activa Cloud Shell.
En la parte inferior de la consola de Google Cloud, se inicia una sesión de Cloud Shell en la que se muestra una ventana de línea de comandos. Cloud Shell es un entorno de shell con Google Cloud CLI ya instalada y con valores ya establecidos para el proyecto actual. La sesión puede tardar unos segundos en inicializarse.
Ejecuta todos los comandos de este documento desde Cloud Shell.
Configura tu entorno
En esta sección, configurarás la infraestructura y las identidades que se requieren para esta arquitectura.
En Cloud Shell, clona el repositorio y cambia al directorio
gcf-automated-resource-cleanup
:git clone https://github.com/GoogleCloudPlatform/gcf-automated-resource-cleanup.git && cd gcf-automated-resource-cleanup/
Configura las variables de entorno y haz que la carpeta del repositorio sea tu carpeta
$WORKDIR
, en la que ejecutas todos los comandos:export PROJECT_ID=$(gcloud config list \ --format 'value(core.project)' 2>/dev/null) WORKDIR=$(pwd)
Instala Apache Bench, una herramienta de generación de carga de código abierto:
sudo apt-get install apache2-utils
Limpia direcciones IP sin usar
En esta sección, completarás los siguientes pasos:
- Crear dos direcciones IP estáticas
- Crear una VM que use una dirección IP estática
- Revisar el código de Cloud Functions
- Implementará la Cloud Function.
- Usar trabajos de Cloud Scheduler para probar la función de Cloud Functions
Crea direcciones IP
En Cloud Shell, cambia al directorio de
unused-ip
:cd $WORKDIR/unused-ip
Exporta los nombres de las direcciones IP como variables:
export USED_IP=used-ip-address export UNUSED_IP=unused-ip-address
Cree dos direcciones IP estáticas:
gcloud compute addresses create $USED_IP \ --project=$PROJECT_ID --region=us-central1 gcloud compute addresses create $UNUSED_IP \ --project=$PROJECT_ID --region=us-central1
En este ejemplo, se usa la región
us-central1
, pero puedes elegir una región diferente y hacer referencia a ella de manera coherente durante el resto de este documento.Controle que se hayan creado las dos direcciones:
gcloud compute addresses list --filter="region:(us-central1)"
En el resultado, el estado de
RESERVED
significa que las direcciones IP no están en uso:NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS unused-ip-address 35.232.144.85 EXTERNAL us-central1 RESERVED used-ip-address 104.197.56.87 EXTERNAL us-central1 RESERVED
Configura la dirección IP utilizada como una variable de entorno:
export USED_IP_ADDRESS=$(gcloud compute addresses describe $USED_IP \ --region=us-central1 --format=json | jq -r '.address')
Crea una VM
En Cloud Shell, crea una instancia:
gcloud compute instances create static-ip-instance \ --zone=us-central1-a \ --machine-type=n1-standard-1 \ --subnet=default \ --address=$USED_IP_ADDRESS
Confirma que una de las direcciones IP esté en uso:
gcloud compute addresses list --filter="region:(us-central1)"
El resultado es similar a este:
NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS unused-ip-address 35.232.144.85 EXTERNAL us-central1 RESERVED used-ip-address 104.197.56.87 EXTERNAL us-central1 IN_USE
Revisa el código de Cloud Functions
En Cloud Shell, obtén el resultado de la sección principal del código:
cat $WORKDIR/unused-ip/function.js | grep "const compute" -A 31
El resultado es el siguiente:
const compute = new Compute(); compute.getAddresses(function(err, addresses){ // gets all addresses across regions if(err){ console.log("there was an error: " + err); } if (addresses == null) { console.log("no addresses found"); return; } console.log("there are " + addresses.length + " addresses"); // iterate through addresses for (let item of addresses){ // get metadata for each address item.getMetadata(function(err, metadata, apiResponse) { // if the address is not used AND if it's at least ageToDelete days old: if ((metadata.status=='RESERVED') & (calculateAge(metadata.creationTimestamp) >= ageToDelete)){ // delete address item.delete(function(err, operation, apiResponse2){ if (err) { console.log("could not delete address: " + err); } }) } }) } // return number of addresses evaluated res.send("there are " + addresses.length + " total addresses"); }); }
En la muestra de código anterior, presta atención a lo siguiente:
compute.getAddresses(function(err, addresses){ // gets all addresses across regions
Usa el método
getAddresses
para recuperar direcciones IP en todas las regiones del proyecto.// get metadata for each address item.getMetadata(function(err, metadata, apiResponse) { // if the address is not used: if (metadata.status=='RESERVED'){
Obtiene los metadatos de cada dirección IP y verifica su campo
STATUS
.if ((metadata.status=='RESERVED') & (calculateAge(metadata.creationTimestamp) >= ageToDelete)){
Comprueba si la dirección IP está en uso, calcula su antigüedad mediante una función auxiliar y compara su antigüedad con una constante (establecida en
0
para los fines del ejemplo).// delete address item.delete(function(err, operation, apiResponse2){
Borra la dirección IP.
Implementa la función de Cloud Functions
En Cloud Shell, implementa la función de Cloud Functions:
gcloud functions deploy unused_ip_function --trigger-http --runtime=nodejs8
Configura la URL activadora como una variable de entorno:
export FUNCTION_URL=$(gcloud functions describe unused_ip_function \ --format=json | jq -r '.httpsTrigger.url')
Programa y prueba la función de Cloud Functions
En Cloud Shell, crea una tarea de Cloud Scheduler para ejecutar la función de Cloud Functions a las 2:00 a.m. todos los días:
gcloud scheduler jobs create http unused-ip-job \ --schedule="* 2 * * *" \ --uri=$FUNCTION_URL
Activa manualmente el trabajo para probarlo:
gcloud scheduler jobs run unused-ip-job
Controla que se haya borrado la dirección IP sin uso:
gcloud compute addresses list --filter="region:(us-central1)"
El resultado es similar a este:
NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS used-ip-address 104.197.56.87 EXTERNAL us-central1 IN_USE
Limpia discos persistentes sin usar y huérfanos
En esta sección, completarás los siguientes pasos:
- Crear dos discos persistentes
- Crearás una VM que use uno de los discos.
- Desconectarás el disco de la VM.
- Revisarás el código de la Cloud Function.
- Implementarás la Cloud Function.
- Usar trabajos de Cloud Scheduler para probar la función de Cloud Functions
Crea discos persistentes
En Cloud Shell, cambia al directorio de
unattached-pd
:cd $WORKDIR/unattached-pd
Exporta los nombres de los discos como variables de entorno:
export ORPHANED_DISK=orphaned-disk export UNUSED_DISK=unused-disk
Crea los dos discos:
gcloud beta compute disks create $ORPHANED_DISK \ --project=$PROJECT_ID \ --type=pd-standard \ --size=500GB \ --zone=us-central1-a gcloud beta compute disks create $UNUSED_DISK \ --project=$PROJECT_ID \ --type=pd-standard \ --size=500GB \ --zone=us-central1-a
Confirma que se crearon los dos discos:
gcloud compute disks list
El resultado es el siguiente:
NAME LOCATION LOCATION_SCOPE SIZE_GB TYPE STATUS orphaned-disk us-central1-a zone 500 pd-standard READY static-ip-instance us-central1-a zone 10 pd-standard READY unused-disk us-central1-a zone 500 pd-standard READY
Crea una VM e inspecciona los discos
En Cloud Shell, crea la instancia:
gcloud compute instances create disk-instance \ --zone=us-central1-a \ --machine-type=n1-standard-1 \ --disk=name=$ORPHANED_DISK,device-name=$ORPHANED_DISK,mode=rw,boot=no
Inspecciona el disco que se vinculó a la VM:
gcloud compute disks describe $ORPHANED_DISK \ --zone=us-central1-a \ --format=json | jq
El resultado es similar a este:
{ "creationTimestamp": "2019-06-12T12:21:25.546-07:00", "id": "7617542552306904666", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "lastAttachTimestamp": "2019-06-12T12:24:53.989-07:00", "name": "orphaned-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/orphaned-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "users": [ "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/instances/disk-instance" ], "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
En la muestra de código anterior, presta atención a lo siguiente:
users
identifica la VM a la que está conectado el disco.lastAttachTimestamp
identifica cuándo se conectó el disco por última vez a una VM.
Inspecciona el disco que no se conectó a una VM:
gcloud compute disks describe $UNUSED_DISK \ --zone=us-central1-a \ --format=json | jq
El resultado es similar a este:
{ "creationTimestamp": "2019-06-12T12:21:30.905-07:00", "id": "1313096191791918677", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "name": "unused-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/unused-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
Estos son los aspectos importantes de la muestra de código anterior:
- El disco no tiene
users
en la lista porque no una VM no lo usa actualmente. - El disco no tiene
lastAttachedTimestamp
porque nunca se usó.
- El disco no tiene
Desconecta el disco persistente huérfano de la VM:
gcloud compute instances detach-disk disk-instance \ --device-name=$ORPHANED_DISK \ --zone=us-central1-a
Inspecciona el disco huérfano:
gcloud compute disks describe $ORPHANED_DISK \ --zone=us-central1-a \ --format=json | jq
El resultado es similar a este:
{ "creationTimestamp": "2019-06-12T12:21:25.546-07:00", "id": "7617542552306904666", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "lastAttachTimestamp": "2019-06-12T12:24:53.989-07:00", "lastDetachTimestamp": "2019-06-12T12:34:56.040-07:00", "name": "orphaned-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/orphaned-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
Estos son los aspectos importantes de la muestra de código anterior:
- El disco no tiene
users
en la lista, lo que indica que no está en uso actualmente. - Ahora hay una entrada
lastDetachTimestamp
que indica cuándo se desconectó el disco por última vez de una VM y, por lo tanto, cuándo se usó por última vez. - El campo
lastAttachTimestamp
todavía está presente.
- El disco no tiene
Revisa el código de Cloud Functions
En Cloud Shell, obtén el resultado de la sección del código que recupera todos los discos persistentes del proyecto:
cat $WORKDIR/unattached-pd/main.py | grep "(request)" -A 12
El resultado es el siguiente:
def delete_unattached_pds(request): # get list of disks and iterate through it: disksRequest = compute.disks().aggregatedList(project=project) while disksRequest is not None: diskResponse = disksRequest.execute() for name, disks_scoped_list in diskResponse['items'].items(): if disks_scoped_list.get('warning') is None: # got disks for disk in disks_scoped_list['disks']: # iterate through disks diskName = disk['name'] diskZone = str((disk['zone'])).rsplit('/',1)[1] print (diskName) print (diskZone)
La función usa el método
aggregatedList
para obtener todos los discos persistentes en el proyecto de Google Cloud en el que se ejecuta y repite cada uno de ellos.Obtén el resultado de la sección del código que verifica el campo
lastAttachTimestamp
y borra el disco si no existe:cat $WORKDIR/unattached-pd/main.py | grep "handle never" -A 11
El resultado es el siguiente:
# handle never attached disk - delete it # lastAttachedTimestamp is not present if disk.get("lastAttachTimestamp") is None: print ("disk " + diskName + " was never attached - deleting") deleteRequest = compute.disks().delete(project=project, zone=diskZone, disk=diskName) deleteResponse = deleteRequest.execute() waitForZoneOperation(deleteResponse, project, diskZone) print ("disk " + diskName + " was deleted") Continue
Esta sección borra el disco si
lastAttachTimestamp
no está presente, lo que significa que este disco nunca estuvo en uso.Obtén el resultado de la sección del código que calcula la antigüedad del disco si es huérfano, crea una instantánea y lo borra:
cat $WORKDIR/unattached-pd/main.py | grep "handle detached" -A 32
El resultado es el siguiente:
# handle detached disk - snapshot and delete # lastAttachTimestamp is present AND users is not present AND it meets the age criterium if disk.get("users") is None \ and disk.get("lastDetachTimestamp") is not None \ and diskAge(disk['lastDetachTimestamp'])>=deleteAge: print ("disk " + diskName + " has no users and has been detached") print ("disk meets age criteria for deletion") # take a snapshot snapShotName = diskName + str(int(time.time())) print ("taking snapshot: " + snapShotName) snapshotBody = { "name": snapShotName } snapshotRequest = compute.disks().createSnapshot(project=project, zone=diskZone, disk=diskName, body=snapshotBody) snapshotResponse = snapshotRequest.execute() waitForZoneOperation(snapshotResponse, project, diskZone) print ("snapshot completed") # delete the disk print ("deleting disk " + diskName) deleteRequest = compute.disks().delete(project=project, zone=diskZone, disk=diskName) deleteResponse = deleteRequest.execute() waitForZoneOperation(deleteResponse, project, diskZone) print ("disk " + diskName + " was deleted") continue
Esta sección de código se usa cuando el disco tiene
users
ylastDetachTimestamp
está presente, lo que significa que el disco no está en uso actualmente, pero se usó en algún momento. En este caso, la función de Cloud Functions crea una instantánea del disco para retener los datos y, luego, lo borra.
Implementa la función de Cloud Functions
En Cloud Shell, implemente la Cloud Function:
gcloud functions deploy delete_unattached_pds \ --trigger-http --runtime=python37
Establece la URL activadora de la función de Cloud Functions como una variable de entorno:
export FUNCTION_URL=$(gcloud functions describe delete_unattached_pds \ --format=json | jq -r '.httpsTrigger.url')
Programa y prueba la función de Cloud Functions
En Cloud Shell, crea una tarea de Cloud Scheduler para ejecutar la función de Cloud Functions a las 2:00 a.m. todos los días:
gcloud scheduler jobs create http unattached-pd-job \ --schedule="* 2 * * *" \ --uri=$FUNCTION_URL
Prueba el trabajo:
gcloud scheduler jobs run unattached-pd-job
Controla que se haya creado la instantánea del disco huérfano:
gcloud compute snapshots list
El resultado es similar a este:
NAME DISK_SIZE_GB SRC_DISK STATUS orphaned-disk1560455894 500 us-central1-a/disks/orphaned-disk READY
Controla que se hayan borrado el disco sin uso y el huérfano:
gcloud compute disks list
El resultado es el siguiente:
NAME LOCATION LOCATION_SCOPE SIZE_GB TYPE STATUS disk-instance us-central1-a zone 10 pd-standard READY static-ip-instance us-central1-a zone 10 pd-standard READY
Migra depósitos de almacenamiento a clases de almacenamiento menos costosas
Google Cloud proporciona reglas de ciclo de vida de objetos de almacenamiento que puedes usar para mover objetos automáticamente a diferentes clases de almacenamiento según un conjunto de atributos, como su fecha de creación o estado. Sin embargo, estas reglas no identifican si se accedió a los objetos. A veces, es posible que quieras mover objetos más nuevos a Nearline Storage si no se accedió a ellos durante un tiempo determinado.
En esta sección, completarás los siguientes pasos:
- Crear dos depósitos de Cloud Storage
- Agregar un objeto a uno de los depósitos
- Configurar Monitoring para observar el acceso a los objetos del bucket
- Revisar el código de Cloud Functions que migra los objetos de un bucket de Regional Storage a un bucket de Nearline Storage
- Implementará la Cloud Function.
- Probar la función de Cloud Functions con una alerta de Monitoring
Crea depósitos de Cloud Storage y agrega un archivo
En Cloud Shell, cambia al directorio de
migrate-storage
:cd $WORKDIR/migrate-storage
Crea el depósito de Cloud Storage
serving-bucket
que se usará más adelante para cambiar las clases de almacenamiento:export PROJECT_ID=$(gcloud config list \ --format 'value(core.project)' 2>/dev/null) gsutil mb -c regional -l us-central1 gs://${PROJECT_ID}-serving-bucket
Configura el bucket como público:
gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket
Agrega un archivo de texto al bucket:
gsutil cp $WORKDIR/migrate-storage/testfile.txt \ gs://${PROJECT_ID}-serving-bucket
Configura el archivo como público:
gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket/testfile.txt
Confirma que puedas acceder al archivo:
curl http://storage.googleapis.com/${PROJECT_ID}-serving-bucket/testfile.txt
El resultado es el siguiente:
this is a test
Crea un segundo depósito llamado
idle-bucket
que no entregue ningún dato:gsutil mb -c regional -l us-central1 gs://${PROJECT_ID}-idle-bucket
Configura un lugar de trabajo de Cloud Monitoring
En esta sección, configurarás Cloud Monitoring para observar el uso del bucket a fin de comprender cuándo no se usan los objetos del bucket. Cuando no se usa el bucket de entrega, una función de Cloud Functions migra el bucket de la clase Regional Storage a la clase Nearline Storage.
En la consola de Google Cloud, ve a Monitoring.
Haz clic en Nuevo espacio de trabajo y, luego, en Agregar.
Espera a que se complete la configuración inicial.
Crea un panel de Cloud Monitoring
En Monitoring, ve a Paneles y, luego, haz clic en Crear panel.
Haz clic en Agregar gráfico.
En el campo Nombre, ingresa
Bucket Access
.Para encontrar la métrica de contenido de la solicitud del depósito de Cloud Storage, en el campo Find resource and metric, ingresa
request
y, luego, selecciona la métrica Recuento de solicitudes para el recursogcs_bucket
.Para agrupar las métricas por nombre de depósito, en la lista desplegable Agrupar por, haz clic en
bucket_name
.Para filtrar por el nombre del método, en el campo Filtro, ingresa ReadObject y haz clic en Aplicar.
Haz clic en Guardar.
En el campo Nombre, ingresa
Bucket Usage
.Para confirmar que se puede acceder al panel, mantén el puntero sobre Paneles y verifica que aparezca Bucket Usage.
Configuraste Monitoring para observar el acceso a objetos en tus depósitos. El gráfico no muestra ningún dato porque los depósitos de Cloud Storage no están recibiendo tráfico.
Genera carga en el bucket de entrega
Ahora que ya configuraste la supervisión, usa Apache Bench para enviar tráfico al bucket de entrega.
En Cloud Shell, envíe solicitudes al objeto en el bucket de entrega:
ab -n 10000 \ http://storage.googleapis.com/$PROJECT_ID-serving-bucket/testfile.txt
En la consola de Google Cloud, ve a Monitoring.
Para seleccionar el panel Bucket Usage, mantén el puntero sobre Paneles y selecciona Bucket Usage. Confirma que el tráfico se envíe solo al bucket de entrega. La serie temporal
request_count metric
solo se muestra para el depósito de entrega, ya que el depósito inactivo no tiene tráfico.
Revisa e implementa la función de Cloud Functions
En Cloud Shell, obtén el resultado del código que usa la función de Cloud Functions para migrar un bucket de almacenamiento a la clase de Nearline Storage:
cat $WORKDIR/migrate-storage/main.py | grep "migrate_storage(" -A 15
El resultado es el siguiente:
def migrate_storage(request): # process incoming request to get the bucket to be migrated: request_json = request.get_json(force=True) # bucket names are globally unique bucket_name = request_json['incident']['resource_name'] # create storage client storage_client = storage.Client() # get bucket bucket = storage_client.get_bucket(bucket_name) # update storage class bucket.storage_class = "NEARLINE" bucket.patch()
La función de Cloud Functions usa el nombre del bucket que se pasa en la solicitud para cambiar su clase de almacenamiento a Nearline Storage.
Implemente la Cloud Function:
gcloud functions deploy migrate_storage --trigger-http --runtime=python37
Configura la URL del activador como una variable de entorno que usarás en la siguiente sección:
export FUNCTION_URL=$(gcloud functions describe migrate_storage \ --format=json | jq -r '.httpsTrigger.url')
Prueba y valida la automatización de alertas
Establezca el nombre del bucket inactivo:
export IDLE_BUCKET_NAME=$PROJECT_ID-idle-bucket
Envía una notificación de prueba a la función de Cloud Functions que implementaste con el archivo
incident.json
:envsubst < $WORKDIR/migrate-storage/incident.json | curl -X POST \ -H "Content-Type: application/json" $FUNCTION_URL -d @-
El resultado es el siguiente:
OK
El resultado no termina con un salto de línea y, por lo tanto, lo sigue de inmediato el símbolo del sistema.
Confirma que el bucket inactivo se migró a Nearline Storage:
gsutil defstorageclass get gs://$PROJECT_ID-idle-bucket
El resultado es el siguiente:
gs://automating-cost-optimization-idle-bucket: NEARLINE
Consideraciones para un entorno de producción
Cuando automatices las optimizaciones de costos en tu propio entorno de Google Cloud, ten en cuenta estos puntos:
- Consideraciones generales: Debes aumentar la seguridad de las funciones de Cloud Functions que tienen el poder de modificar o borrar recursos de Google Cloud.
- Identificación de desperdicios: En este documento, se explican algunos gastos innecesarios.
Existen muchos otros ejemplos que generalmente se clasifican en una de tres categorías:
- Recursos aprovisionados en exceso: recursos aprovisionados a fin de que sean más grandes de lo necesario para una carga de trabajo determinada, como VM con más capacidad de CPU y memoria de las necesarias
- Recursos inactivos: recursos que no se usan por completo
- Recursos inactivos a tiempo parcial: recursos que solo se usan durante el horario de atención
- Automatización de limpieza: en este documento, se necesitó un proceso de varios pasos con varias operaciones asíncronas para generar una instantánea y borrar el disco. Otros recursos de Google Cloud, como las direcciones IP sin usar, pueden usar operaciones síncronas.
- Implementación a gran escala: en este documento, el ID del proyecto de Google Cloud se define en el código de Cloud Functions. Para implementar una solución de este tipo a gran escala, considera usar las APIs de Facturación de Cloud o Cloud Resource Manager para obtener la lista de proyectos con una cuenta de facturación o una organización. Luego, pasa esos IDs del proyecto de Google Cloud como variables a una función. En esta configuración, debes agregar la cuenta de servicio de Cloud Functions a los proyectos en los que puede limpiar o borrar recursos. Recomendamos usar un framework de implementación automatizado, como Cloud Deployment Manager o Terraform.
- Automatización de alertas: en este documento, se muestra cómo usar una carga útil simulada de una alerta de Monitoring para activar la migración de la clase de almacenamiento. Las políticas de alertas de Monitoring se pueden evaluar en un máximo de 23 horas y 59 minutos. En un entorno de producción, es posible que esta restricción no sea lo suficientemente larga como para considerar un bucket inactivo antes de migrar su clase de almacenamiento. Considera habilitar los registros de auditoría de acceso a datos en el bucket de Cloud Storage y crear una canalización que consuma estos registros de auditoría para evaluar si se usó un bucket en los últimos 30 días. Para obtener más información, consulta cómo comprender los registros de auditoría y considera crear un receptor agregado para enviar registros a Pub/Sub y una canalización de Dataflow a fin de procesarlos.
Realiza una limpieza
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.
Borra el proyecto
- En la consola de Google Cloud, ve a la página Administrar recursos.
- En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.
¿Qué sigue?
- Mira videos sobre la administración de costos.
- Visita la página principal de administración de costos.
- Revisa la documentación de Facturación de Cloud.
- Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.