Kostenoptimierungen mit Cloud Functions, Cloud Scheduler und Cloud Monitoring automatisieren


In diesem Dokument erfahren Sie, wie Sie Cloud Functions verwenden, um nicht genutzte Cloudressourcen zu identifizieren und zu bereinigen, wie Sie Funktionen planen, um sie mit Cloud Scheduler auszuführen, und wie Sie Benachrichtigungsrichtlinien von Cloud Monitoring basierend auf der beobachteten Nutzung anwenden. Dieses Dokument richtet sich an Entwickler, SREs, Cloud-Architekten und Cloudinfrastruktur-Administratoren, die überflüssige Cloudausgaben mit einem systematischen und automatisierten Ansatz identifizieren und reduzieren möchten.

In diesem Dokument wird davon ausgegangen, dass Sie mit Folgendem vertraut sind:

Ziele

  • Nicht verwendete IP-Adressen löschen: In Google Cloud sind statische IP-Adressen eine kostenlose Ressource, wenn sie zu einer Load-Balancer- oder VM-Instanz (virtuelle Maschine) gehören. Für statische IP-Adressen, die reserviert sind, aber nicht verwendet werden, fällt eine stundenweise Gebühr an. Bei Anwendungen, die in hohem Maße auf statische IP-Adressen und umfangreiche dynamische Bereitstellungen angewiesen sind, können dadurch im Laufe der Zeit erhebliche Kosten entstehen.
  • Verwaiste oder ungenutzte nichtflüchtige Speicher löschen: Nichtflüchtige Speicher gelten als ungenutzt oder verwaist, wenn sie noch nie an eine VM angehängt wurden oder wenn ein oder mehrere Speicher von Maschinen mit mehreren Speichern getrennt wurden.
  • Zu kostengünstigeren Speicherklassen migrieren: Google Cloud bietet mehrere Klassen von Objektspeichern. Verwenden Sie die Klasse, die Ihren Anforderungen am besten entspricht.

Architektur

Im folgenden Diagramm wird der erste Teil der Bereitstellung beschrieben, in dem Sie eine Cloud Functions-Funktion planen, um nicht verwendete IP-Adressen zu identifizieren und zu bereinigen.

Architektur einer Cloud Functions-Funktion, die nicht verwendete IP-Adressen identifiziert und bereinigt

Im ersten Beispiel behandelte Aufgaben:

  • Compute Engine-VM mit zwei statischen externen IP-Adresse erstellen, von denen eine nicht verwendet wird
  • Cloud Functions-Funktion bereitstellen, um nicht verwendete Adressen zu identifizieren
  • Cloud Scheduler-Job erstellen, mit dem die Ausführung der Funktion mit einem HTTP-Trigger geplant wird

Im folgenden Diagramm wird gezeigt, wie Sie in Cloud Functions eine Funktion planen, die nicht angehängte oder verwaiste nichtflüchtige Datenspeicher identifiziert und bereinigt.

Architektur einer Cloud Functions-Funktion, die nicht verwendete nichtflüchtige Speicher identifiziert und bereinigt

Im zweiten Beispiel behandelte Aufgaben:

  • Compute Engine-VM mit zwei nichtflüchtigen Speichern und einem separaten nichtflüchtigen Speicher erstellen, der nicht angehängt ist. Einer der Speicher ist verwaist, da er von der VM getrennt ist.
  • In Cloud Functions eine Funktion bereitstellen, die nicht angehängte und verwaiste nichtflüchtige Speicher identifiziert
  • Cloud Scheduler-Job erstellen, mit dem die Ausführung der Cloud Functions-Funktion mit einem HTTP-Trigger geplant wird

Im folgenden Diagramm wird gezeigt, wie Sie von einer Monitoring-Benachrichtigungsrichtlinie eine Cloud Functions-Funktion auslösen, die einen Storage-Bucket in eine kostengünstigere Speicherklasse migriert.

Architektur einer Cloud Functions-Funktion, die einen Storage-Bucket migriert

Im dritten Beispiel behandelte Aufgaben:

  • Zwei Storage-Buckets erstellen, dem Serving-Bucket eine Datei hinzufügen und Traffic generieren
  • Monitoring-Dashboard erstellen, um die Bucket-Nutzung zu visualisieren
  • Eine Cloud Functions-Funktion bereitstellen, die den inaktiven Bucket in eine kostengünstigere Speicherklasse migriert
  • Funktion mithilfe einer Nutzlast auslösen, die eine von einer Monitoring-Benachrichtigungsrichtlinie eingegangene Benachrichtigung simulieren soll

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweise

  1. Melden Sie sich bei Ihrem Google Cloud-Konto an. Wenn Sie mit Google Cloud noch nicht vertraut sind, erstellen Sie ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  3. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  4. Compute Engine, Cloud Functions, and Cloud Storage APIs aktivieren.

    Aktivieren Sie die APIs

  5. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  6. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  7. Compute Engine, Cloud Functions, and Cloud Storage APIs aktivieren.

    Aktivieren Sie die APIs

  8. Aktivieren Sie Cloud Shell in der Google Cloud Console.

    Cloud Shell aktivieren

    Unten in der Google Cloud Console wird eine Cloud Shell-Sitzung gestartet und eine Eingabeaufforderung angezeigt. Cloud Shell ist eine Shell-Umgebung, in der das Google Cloud CLI bereits installiert ist und Werte für Ihr aktuelles Projekt bereits festgelegt sind. Das Initialisieren der Sitzung kann einige Sekunden dauern.

  9. Sie führen alle Befehle in diesem Dokument über Cloud Shell aus.

Umgebung einrichten

In diesem Abschnitt konfigurieren Sie die für diese Architektur erforderliche Infrastruktur und die benötigten Identitäten.

  1. Klonen Sie in Cloud Shell das Repository und wechseln Sie in das Verzeichnis gcf-automated-resource-cleanup:

    git clone https://github.com/GoogleCloudPlatform/gcf-automated-resource-cleanup.git && cd gcf-automated-resource-cleanup/
    
  2. Legen Sie die Umgebungsvariablen fest und legen Sie den Repository-Ordner als $WORKDIR-Ordner fest, in dem Sie alle Befehle ausführen:

    export PROJECT_ID=$(gcloud config list \
        --format 'value(core.project)' 2>/dev/null)
        WORKDIR=$(pwd)
    
  3. Installieren Sie Apache Bench, ein Open Source-Tool zur Lastgenerierung:

    sudo apt-get install apache2-utils
    

Nicht verwendete IP-Adressen bereinigen

In diesem Abschnitt führen Sie die folgenden Schritte aus:

  • Zwei statische IP-Adressen erstellen
  • Eine VM erstellen, die eine statische IP-Adresse verwendet
  • Den Cloud Functions-Code überprüfen
  • Die Cloud Functions-Funktion bereitstellen
  • Die Cloud Functions-Funktion mithilfe von Cloud Scheduler-Jobs testen

IP-Adressen erstellen

  1. Wechseln Sie in Cloud Shell zum Verzeichnis unused-ip:

    cd $WORKDIR/unused-ip
    
  2. Exportieren Sie die Namen der IP-Adressen als Variablen:

    export USED_IP=used-ip-address
    export UNUSED_IP=unused-ip-address
    
  3. Erstellen Sie zwei statische IP-Adressen:

    gcloud compute addresses create $USED_IP \
        --project=$PROJECT_ID --region=us-central1
    gcloud compute addresses create $UNUSED_IP \
        --project=$PROJECT_ID --region=us-central1
    

    In diesem Beispiel wird die Region us-central1 verwendet. Sie können jedoch auch eine andere Region auswählen, auf die Sie sich im weiteren Verlauf dieses Dokuments konsistent beziehen.

  4. Prüfen Sie, ob zwei Adressen erstellt wurden:

    gcloud compute addresses list --filter="region:(us-central1)"
    

    In der Ausgabe weist der Status RESERVED darauf hin, dass die IP-Adressen nicht verwendet werden:

    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
    
  5. Legen Sie die verwendete IP-Adresse als Umgebungsvariable fest:

    export USED_IP_ADDRESS=$(gcloud compute addresses describe $USED_IP \
        --region=us-central1 --format=json | jq -r '.address')
    

VM erstellen

  1. Erstellen Sie in Cloud Shell eine Instanz:

    gcloud compute instances create static-ip-instance \
        --zone=us-central1-a \
        --machine-type=n1-standard-1 \
        --subnet=default \
        --address=$USED_IP_ADDRESS
    
  2. Prüfen Sie, ob eine der IP-Adressen gerade verwendet wird:

    gcloud compute addresses list --filter="region:(us-central1)"
    

    Die Ausgabe sieht etwa so aus:

    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
    

Cloud Functions-Code prüfen

  • Geben Sie in Cloud Shell den Hauptteil des Codes aus:

    cat $WORKDIR/unused-ip/function.js | grep "const compute" -A 31
    

    Die Ausgabe sieht so aus:

    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");
      });
    }
    

    Achten Sie im vorhergehenden Codebeispiel auf Folgendes:

    • compute.getAddresses(function(err, addresses){ // gets all addresses across regions
      

      Ruft mit der Methode getAddresses IP-Adressen aus allen Regionen des Projekts ab.

    • // get metadata for each address
      item.getMetadata(function(err, metadata, apiResponse) {
         // if the address is not used:
             if (metadata.status=='RESERVED'){
      

      Ruft die Metadaten für jede IP-Adresse ab und überprüft das Feld STATUS.

    • if ((metadata.status=='RESERVED') &
      (calculateAge(metadata.creationTimestamp) >= ageToDelete)){
      

      Überprüft, ob die IP-Adresse verwendet wird, berechnet mit einer Hilfsfunktion das Alter der Adresse und vergleicht es mit einer Konstanten (0 für die Zwecke dieser Anleitung).

    • // delete address
      item.delete(function(err, operation, apiResponse2){
      

      Löscht die IP-Adresse.

Cloud Functions-Funktion bereitstellen

  1. Stellen Sie in Cloud Shell die Cloud Functions-Funktion bereit:

    gcloud functions deploy unused_ip_function --trigger-http --runtime=nodejs8
    
  2. Legen Sie die Trigger-URL als Umgebungsvariable fest:

    export FUNCTION_URL=$(gcloud functions describe unused_ip_function \
        --format=json | jq -r '.httpsTrigger.url')
    

Cloud Functions-Funktion planen und testen

  1. Erstellen Sie in Cloud Shell eine Cloud Scheduler-Aufgabe, die die Cloud Functions-Funktion täglich um 2:00 Uhr morgens ausführt:

    gcloud scheduler jobs create http unused-ip-job \
        --schedule="* 2 * * *" \
        --uri=$FUNCTION_URL
    
  2. Testen Sie den Job durch manuelles Auslösen:

    gcloud scheduler jobs run unused-ip-job
    
  3. Prüfen Sie, ob die nicht verwendete IP-Adresse gelöscht wurde:

    gcloud compute addresses list --filter="region:(us-central1)"
    

    Die Ausgabe sieht etwa so aus:

    NAME             ADDRESS/RANGE  TYPE      REGION       SUBNET  STATUS
    used-ip-address  104.197.56.87  EXTERNAL  us-central1          IN_USE
    

Ungenutzte und verwaiste nichtflüchtige Speicher bereinigen

In diesem Abschnitt führen Sie die folgenden Schritte aus:

  • Zwei nichtflüchtige Speicher erstellen
  • Virtuelle Maschine (VM) erstellen, die einen der Speicher verwendet
  • Den Speicher von der VM trennen
  • Den Cloud Functions-Code prüfen
  • Die Cloud Functions-Funktion bereitstellen
  • Die Cloud Functions-Funktion mithilfe von Cloud Scheduler-Jobs testen

Nichtflüchtige Speicher erstellen

  1. Wechseln Sie in Cloud Shell zum Verzeichnis unattached-pd:

    cd $WORKDIR/unattached-pd
    
  2. Exportieren Sie die Namen der Speicher als Umgebungsvariablen:

    export ORPHANED_DISK=orphaned-disk
    export UNUSED_DISK=unused-disk
    
  3. Erstellen Sie die zwei Speicher:

    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
    
  4. Bestätigen Sie, dass die beiden Speicher erstellt wurden:

    gcloud compute disks list
    

    Die Ausgabe sieht so aus:

    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
    

VM erstellen und die Speicher untersuchen

  1. Erstellen Sie in Cloud Shell die Instanz:

    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
    
  2. Untersuchen Sie den an die VM angeschlossenen Speicher:

    gcloud compute disks describe $ORPHANED_DISK \
        --zone=us-central1-a \
        --format=json | jq
    

    Die Ausgabe sieht etwa so aus:

    {
      "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"
    }
    

    Achten Sie im vorhergehenden Codebeispiel auf Folgendes:

    • users identifiziert die VM, an die der Speicher angehängt ist.
    • lastAttachTimestamp gibt an, wann der Speicher zuletzt an eine VM angehängt wurde.
  3. Untersuchen Sie den Speicher, der keiner VM angehängt wurde:

    gcloud compute disks describe $UNUSED_DISK \
        --zone=us-central1-a \
        --format=json | jq
    

    Die Ausgabe sieht etwa so aus:

    {
      "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"
    }
    

    Im vorhergehenden Codebeispiel ist Folgendes wichtig:

    • Für das Laufwerk werden keine users aufgeführt, da es aktuell nicht von einer VM verwendet wird.
    • Für das Laufwerk gibt es keinen lastAttachedTimestamp-Zeitstempel, weil es noch nie verwendet wurde.
  4. Trennen Sie den verwaisten nichtflüchtigen Speicher von der VM:

    gcloud compute instances detach-disk disk-instance \
        --device-name=$ORPHANED_DISK \
        --zone=us-central1-a
    
  5. Untersuchen Sie den verwaisten Speicher:

    gcloud compute disks describe $ORPHANED_DISK \
        --zone=us-central1-a \
        --format=json | jq
    

    Die Ausgabe sieht etwa so aus:

    {
      "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"
    }
    

    Im vorhergehenden Codebeispiel ist Folgendes wichtig:

    • Für das Laufwerk werden keine users aufgeführt, was darauf hinweist, dass er derzeit nicht verwendet wird.
    • Der in diesem Beispiel vorhandene lastDetachTimestamp-Eintrag gibt an, wann das Laufwerk zuletzt von einer VM getrennt wurde und dementsprechend auch zuletzt verwendet wurde.
    • Das Feld lastAttachTimestamp ist noch vorhanden.

Cloud Functions-Code prüfen

  1. Geben Sie in Cloud Shell den Teil des Codes aus, der alle nichtflüchtigen Speicher im Projekt abruft:

    cat $WORKDIR/unattached-pd/main.py | grep "(request)" -A 12
    

    Die Ausgabe sieht so aus:

    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)
    

    Die Funktion ruft mit der Methode aggregatedList alle nichtflüchtigen Speicher im Google Cloud-Projekt ab und durchläuft all diese Laufwerke.

  2. Geben Sie den Abschnitt des Codes aus, der das Feld lastAttachTimestamp prüft und das Laufwerk löscht, falls kein Zeitstempel vorhanden ist:

    cat $WORKDIR/unattached-pd/main.py | grep "handle never" -A 11
    

    Die Ausgabe sieht so aus:

    # 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
    

    Durch diesen Abschnitt wird das Laufwerk gelöscht, falls lastAttachTimestamp fehlt, was bedeutet, dass das Laufwerk nie verwendet wurde.

  3. Geben Sie den Codeabschnitt aus, der das Alter des Speichers berechnet, wenn er verwaist ist, einen Snapshot davon erstellt und den Speicher löscht:

    cat $WORKDIR/unattached-pd/main.py | grep "handle detached" -A 32
    

    Die Ausgabe sieht so aus:

    # 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
    

    Dieser Codeabschnitt wird verwendet, wenn für das Laufwerk users aufgelistet sind und lastDetachTimestamp vorhanden ist. Dies weist darauf hin, dass das Laufwerk derzeit nicht verwendet wird, aber früher bereits verwendet wurde. In diesem Fall erstellt die Cloud Functions-Funktion einen Snapshot des Speichers, um die Daten aufzubewahren, und löscht dann den Speicher.

Cloud Functions-Funktion bereitstellen

  1. Stellen Sie in Cloud Shell die Cloud Functions-Funktion bereit:

    gcloud functions deploy delete_unattached_pds \
        --trigger-http --runtime=python37
    
  2. Legen Sie die Trigger-URL der Cloud Functions-Funktion als Umgebungsvariable fest:

    export FUNCTION_URL=$(gcloud functions describe delete_unattached_pds \
        --format=json | jq -r '.httpsTrigger.url')
    

Cloud Functions-Funktion planen und testen

  1. Erstellen Sie in Cloud Shell eine Cloud Scheduler-Aufgabe, die die Cloud Functions-Funktion täglich um 2:00 Uhr morgens ausführt:

    gcloud scheduler jobs create http unattached-pd-job \
        --schedule="* 2 * * *" \
        --uri=$FUNCTION_URL
    
  2. Testen Sie den Job:

    gcloud scheduler jobs run unattached-pd-job
    
  3. Prüfen Sie, ob ein Snapshot des verwaisten Speichers erstellt wurde:

    gcloud compute snapshots list
    

    Die Ausgabe sieht etwa so aus:

    NAME                     DISK_SIZE_GB  SRC_DISK                           STATUS
    orphaned-disk1560455894  500           us-central1-a/disks/orphaned-disk  READY
    
  4. Prüfen Sie, ob der ungenutzte und der verwaiste Speicher gelöscht wurden:

    gcloud compute disks list
    

    Die Ausgabe sieht so aus:

    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
    

Storage-Buckets in kostengünstigere Speicherklassen migrieren

In Google Cloud gibt es Lebenszyklusregeln für Storage-Objekte, mit denen Sie Objekte auf der Grundlage von Attributen wie Erstellungsdatum oder Livestatus automatisch in verschiedene Speicherklassen verschieben können. Diese Regeln erkennen jedoch nicht, ob auf die Objekte zugegriffen wurde. In manchen Situationen kann es jedoch sinnvoll sein, neuere Objekte in Nearline Storage zu verschieben, wenn über einen bestimmten Zeitraum kein Zugriff auf sie erfolgt ist.

In diesem Abschnitt führen Sie die folgenden Schritte aus:

  • Zwei Cloud Storage-Buckets erstellen
  • Einem der Buckets ein Objekt hinzufügen
  • Monitoring so konfigurieren, dass der Zugriff auf das Objekt überwacht wird
  • Cloud Functions-Code überprüfen, mit dem Objekte von einem Regional Storage-Bucket in einen Nearline Storage-Bucket migriert werden
  • Die Cloud Functions-Funktion bereitstellen
  • Cloud Functions-Funktion mit einer Monitor-Benachrichtigung testen

Cloud Storage-Buckets erstellen und eine Datei hinzufügen

  1. Wechseln Sie in Cloud Shell zum Verzeichnis migrate-storage:

    cd $WORKDIR/migrate-storage
    
  2. Erstellen Sie den Cloud Storage-Bucket serving-bucket, der später zum Ändern der Speicherklasse benötigt wird:

    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
    
  3. Veröffentlichen Sie den Bucket:

    gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket
    
  4. Fügen Sie dem Bucket eine Textdatei hinzu:

    gsutil cp $WORKDIR/migrate-storage/testfile.txt  \
        gs://${PROJECT_ID}-serving-bucket
    
  5. Veröffentlichen Sie die Datei:

    gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket/testfile.txt
    
  6. Prüfen Sie, ob Sie auf die Datei zugreifen können:

    curl http://storage.googleapis.com/${PROJECT_ID}-serving-bucket/testfile.txt
    

    Die Ausgabe sieht so aus:

    this is a test
    
  7. Erstellen Sie einen zweiten Bucket namens idle-bucket, der keine Daten bereitstellt:

    gsutil mb -c regional -l us-central1 gs://${PROJECT_ID}-idle-bucket
    

Cloud Monitoring-Arbeitsbereich einrichten

In diesem Abschnitt konfigurieren Sie Cloud Monitoring so, dass die Bucket-Nutzung überwacht wird. Sie möchten ermitteln, welche Bucket-Objekte nicht verwendet werden. Wenn der Serving-Bucket nicht verwendet wird, wird er von einer Cloud Functions-Funktion von der Regional Storage-Klasse in die Nearline Storage-Klasse migriert.

  1. Wechseln Sie in der Google Cloud Console zu Monitoring:

    Zu Cloud Monitoring

  2. Klicken Sie auf New Workspace (Neuer Arbeitsbereich) und dann auf Add (Hinzufügen).

    Warten Sie, bis die Erstkonfiguration abgeschlossen ist.

Cloud Monitoring-Dashboard erstellen

  1. Rufen Sie in Monitoring Dashboards auf und klicken Sie auf Create Dashboard (Dashboard erstellen).

  2. Klicken Sie auf Diagramm hinzufügen.

  3. Geben Sie im Feld Name Bucket Access ein.

  4. Im nächsten Schritt ermitteln Sie den Messwert des Anfrageinhalts für den Cloud Storage-Bucket. Geben Sie dafür im Feld Find resource and metric request ein, und wählen Sie den Messwert Anzahl der Anfragen für die Ressource gcs_bucket aus.

  5. Gruppieren Sie dann die Messwerte anhand des Bucket-Namens. Klicken Sie dafür in der Drop-down-Liste Gruppieren nach auf bucket_name.

  6. Filtern Sie nun die Ergebnisse nach dem Methodennamen. Geben Sie im Feld Filter ReadObject ein und klicken Sie auf Übernehmen.

  7. Klicken Sie auf Speichern.

  8. Geben Sie im Feld "Name" den Wert Bucket Usage ein.

  9. Prüfen Sie im nächsten Schritt, ob der Zugriff auf das Dashboard möglich ist. Halten Sie den Mauszeiger über Dashboards und prüfen Sie, ob Bucket Usage (Bucket-Nutzung) angezeigt wird.

    Sie haben Monitoring so konfiguriert, dass der Objektzugriff in Ihren Buckets überwacht wird. Im Diagramm werden keine Daten angezeigt, da kein Traffic zu den Cloud Storage-Buckets stattfindet.

Last für den Serving-Bucket generieren

Monitoring ist nun konfiguriert. Im nächsten Schritt senden Sie Traffic mit Apache Bench an den Serving-Bucket.

  1. Senden Sie in Cloud Shell Anforderungen an das Objekt im Serving-Bucket:

    ab -n 10000 \
        http://storage.googleapis.com/$PROJECT_ID-serving-bucket/testfile.txt
    
  2. Wechseln Sie in der Google Cloud Console zu Monitoring:

    Zu Cloud Monitoring

  3. Halten Sie den Mauszeiger über Dashboards und wählen Sie Bucket Usage (Bucket-Verwendung), um das Dashboard für die Bucket-Verwendung auszuwählen. Prüfen Sie, ob nur der Serving-Bucket Daten empfängt. Die Zeitachse des Messwerts request_count metric wird nur für den Serving-Bucket angezeigt, da an den inaktiven Bucket kein Traffic gesendet wird.

Cloud Functions-Funktion prüfen und bereitstellen

  1. Geben Sie in Cloud Shell den Code aus, der mit der Cloud Functions-Funktion einen Speicher-Bucket in die Nearline Storage-Klasse migriert:

    cat $WORKDIR/migrate-storage/main.py | grep "migrate_storage(" -A 15
    

    Die Ausgabe sieht so aus:

    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()
    

    Die Cloud Functions-Funktion verwendet den an die Anforderung übergebenen Bucket-Namen, um die Speicherklasse in Nearline Storage zu ändern.

  2. Stellen Sie die Cloud Functions-Funktion bereit:

    gcloud functions deploy migrate_storage --trigger-http --runtime=python37
    
  3. Legen Sie die Trigger-URL als Umgebungsvariable fest. Sie wird im nächsten Abschnitt verwendet:

    export FUNCTION_URL=$(gcloud functions describe migrate_storage \
        --format=json | jq -r '.httpsTrigger.url')
    

Benachrichtigungsautomatisierung testen und validieren

  1. Legen Sie den Namen des inaktiven Buckets fest:

    export IDLE_BUCKET_NAME=$PROJECT_ID-idle-bucket
    
  2. Senden Sie mithilfe der Datei incident.json eine Testbenachrichtigung an die bereitgestellte Cloud Functions-Funktion:

    envsubst < $WORKDIR/migrate-storage/incident.json | curl -X POST \
        -H "Content-Type: application/json" $FUNCTION_URL -d @-
    

    Die Ausgabe sieht so aus:

    OK
    

    Die Ausgabe wird nicht mit einem Zeilenumbruch beendet. Daher folgt die Eingabeaufforderung unmittelbar.

  3. Prüfen Sie, ob der inaktive Bucket in Nearline Storage migriert wurde:

    gsutil defstorageclass get gs://$PROJECT_ID-idle-bucket
    

    Die Ausgabe sieht so aus:

    gs://automating-cost-optimization-idle-bucket: NEARLINE
    

Überlegungen zur Produktionsumgebung

Beachten Sie die folgenden Aspekte, wenn Sie in Ihrer eigenen Google Cloud-Umgebung Kostenoptimierungen automatisieren:

  • Allgemeine Überlegungen: Erhöhen Sie die Sicherheit für Cloud Functions-Funktionen, mit denen sich Google Cloud-Ressourcen ändern oder löschen lassen.
  • Überflüssige Ausgaben ermitteln: In diesem Dokument wurden einige Beispiele für überflüssige Ausgaben beschrieben. Es lassen sich viele weitere Beispiele nennen, die sich im Allgemeinen einer der folgenden drei Kategorien zuordnen lassen:
    • Übermäßig bereitgestellte Ressourcen: Ressourcen, die für eine bestimmte Arbeitslast größer als erforderlich bereitgestellt werden. Beispiel: VMs mit mehr CPU-Leistung und Arbeitsspeicher als erforderlich.
    • Inaktive Ressourcen: Ressourcen, die niemals verwendet werden.
    • Teilweise inaktive Ressourcen: Ressourcen, die nur während der Geschäftszeiten verwendet werden.
  • Bereinigung automatisieren: In diesem Dokument war ein Prozess mit mehreren Schritten und mehreren asynchronen Vorgängen erforderlich, um den Speicher zu löschen und vorher einen Snapshot zu erstellen. Für andere Google Cloud-Ressourcen, z. B. nicht verwendete IP-Adressen, können synchrone Vorgänge verwendet werden.
  • In passendem Umfang bereitstellen: In diesem Dokument wird die Google Cloud-Projekt-ID im Code der Cloud Functions-Funktion definiert. Möchten Sie eine solche Lösung in großem Maßstab bereitstellen, können Sie die Cloud Billing oder Cloud Resource Manager APIs verwenden. Damit können Sie die Liste der Projekte mit einem Abrechnungskonto oder einer Organisation abrufen und dann die Google Cloud-Projekt-IDs als Variablen an eine Funktion übergeben. In einer solchen Konfiguration müssen Sie den Projekten das Dienstkonto von Cloud Functions hinzufügen, das Ressourcen bereinigen oder löschen kann. Wir empfehlen die Verwendung eines automatisierten Bereitstellungsframeworks wie Cloud Deployment Manager oder Terraform.
  • Benachrichtigungsautomatisierung: In diesem Dokument erfahren Sie, wie Sie mit einer von Monitoring simulierten Nutzlast die Migration in eine andere Speicherklasse auslösen. Benachrichtigungsrichtlinien von Monitoring können über einen Zeitraum von maximal 23 Stunden und 59 Minuten ausgewertet werden. In einer Produktionsumgebung reicht diese Einschränkung möglicherweise nicht aus, um einen inaktiven Bucket zu ermitteln und die Speicherklasse zu wechseln. Sie könnten jedoch Audit-Logs zum Datenzugriff im Cloud Storage-Bucket aktivieren und eine Pipeline erstellen, die diese Logs auswertet und feststellt, ob ein Bucket in den letzten 30 Tagen zur Bereitstellung von Daten herangezogen wurde. Weitere Informationen finden Sie unter Audit-Logs verstehen. Sie können auch eine aggregierte Senke erstellen, um Logs zur Verarbeitung an Pub/Sub und eine Dataflow-Pipeline zu senden.

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

Projekt löschen

  1. Wechseln Sie in der Google Cloud Console zur Seite Ressourcen verwalten.

    Zur Seite „Ressourcen verwalten“

  2. Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf Löschen.
  3. Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Shut down (Beenden), um das Projekt zu löschen.

Nächste Schritte