Vorbereitung

Vorbereitung

Ich möchte eine konstante Anzahl funktionsfähiger Instanzen am Laufen halten. Aber manchmal ist die Anwendung fehlerhaft und ihre Ressourcenauslastungsrate wird so niedrig, dass sie nur durch die CloudWatch-Metriken bestimmt werden könnte. Dann möchte ich natürlich, dass diese Instanzen automatisch ersetzt werden. Aber ich kann nicht herausfinden, wie das geht. Das Beste, was mir einfällt, ist die automatische Skalierung, aber lautStandard-Kündigungsrichtlinie, all diese Optionen scheinen nichts mit der Metrik einer bestimmten Instanz zu tun zu haben.

Ich habe ein AMI erstellt, das startbereit ist. Ich muss nur dafür sorgen, dass fehlerhafte Instanzen automatisch beendet und durch eine neue ersetzt werden. Wie kann ich das also machen? Jede Hilfe ist willkommen.

Antwort1

Benutzerdefinierte Instanz-Integritätsprüfungen(unten auf der Seite) ist eine Möglichkeit.

Sie würden einen separaten Code auf der Maschine (oder eigentlich auf jeder Maschine) ausführen, der den Zustand überwacht und den API-Aufruf ausführt, der die Instanz auf ungesund setzt

Ich habe noch eine andere halbfertige Idee, aber ich bin mir nicht ganz sicher, wie ich diese umsetzen soll. Ich war der Architekt eines On-Premise-Systems, bei dem wir den Load Balancer in einen separaten Webserver auf der Instanz aufgerufen haben, in unserem Fall war es ein kleiner benutzerdefinierter Java-Webserver mit etwa 50 Codezeilen. Er gab HTTP-Statuscodes zurück, 200 (OK), wenn alles in Ordnung ist, oder 500 (FEHLER), wenn er beendet werden muss. Ich vermute, dass so etwas in die automatische Skalierung integriert werden könnte, aber ich habe das schon lange nicht mehr gemacht und bin mir nicht sicher, wie man das in die automatische Skalierung integrieren würde.

Hier ist der Befehl aus der ersten Idee oben

aws autoscaling set-instance-health --instance-id i-123abc45d --health-status Unhealthy

Antwort2

Für alle, die diese Frage sehen:

Obwohl ich glaube, dass AWS eine solche Funktion in CloudWatch hätte integrieren sollen, kann ich leider keine Informationen finden, die darauf hindeuten, dass dies verfügbar ist. Daher habe ich ein Bash-Skript erstellt, das die CloudWatch-API abfragt, um die Metriken für den Ressourcenverbrauch zu ermitteln und dann den Instanzzustand entsprechend einzustellen, wie von vorgeschlagenTim:

Vorbereitung

  1. Wenn Sie dies noch nicht getan haben,Installieren Sie die AWS-Befehlszeilenschnittstelle. Auch erhältlich über yumoder apt.
  2. Konfigurieren der AWS CLIGeben Sie durch Ausführen aws configureIhren API-Schlüssel und andere Einstellungen ein.Wichtig: Wenn Sie das folgende Skript wie ich als Root ausführen möchten, müssen Sie diesen Konfigurationsbefehl als Root ausführen. Andernfalls schlägt das Skript fehl.

/root/mein-health-check.sh

#!/bin/bash
# retrieve metrics starting from 20 minutes ago (3 data points)
# Note: Sometimes CloudWatch failed to gather data for a specific period,
# then the number of data points returned could be less than what we expect.
# Also, when the instance just started, there will be no data point.
start_time=$(date -d "-20 minutes" -u +"%Y-%m-%dT%H:%M:%SZ")
# retrieve metrics up to now
end_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# get current instance ID [1]
instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
# get current region [2]
# This is only needed if you have multiple regions to manage, otherwise just
# specify a region via `aws configure`.
region=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/\(.*\)[a-z]/\1/')
# save data retrieved for processing [3]
# Here I used an example of retrieving "NetworkIn" of "AWS/EC2" namespace,
# with metric resolution set to 300 (5 minutes).
# For a list of available metrics, run `aws cloudwatch list-metrics`
datapoints=$(aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name NetworkIn --dimensions Name=InstanceId,Value=$instance_id --statistics Average --start-time $start_time --end-time $end_time --period 300 --region $region --output text | awk '{ print $2 }')
# custom handler
# In this example, the health check will fail if all data points fall below
# my threshold. The health check will not fail if there is no data.
healthy=0
hasdata=0
THRESHOLD=300000
for i in $datapoints; do
    # In this case, the metric(NetworkIn) is not integer.
    if (( $(echo "$i $THRESHOLD" | awk '{print ($1 > $2)}') )); then
        healthy=1
    fi
    hasdata=1
done
if [ $hasdata -eq 1 ]; then
    if [ $healthy -eq 0 ]; then
        aws autoscaling set-instance-health --instance-id $instance_id --health-status Unhealthy --region $region
    fi
fi

Der Rest

  1. Lassen Sie das Skript regelmäßig ausführen
$ chmod +x /root/my-health-check.sh
# run the script at 0, 5, 10, 15 ... 55 of every hour
$ echo "*/5 * * * * root /root/my-health-check.sh 2>&1 | /usr/bin/logger -t ec2_health_check" >> /etc/crontab
  1. Schalten Sie die Instanz aus und erstellen Sie ein AMI. Erstellen Sie anschließend eine neue Auto-Scaling-Gruppe mit dem AMI. Jetzt sollte es sich selbst beenden und eine neue starten, wenn die Metrik den einwandfreien Zustand nicht erfüllt. Voilà!

Verweise:

[1]:Metadaten der EC2-Instanz

[2]:Aktuelle Region in AWS abrufen – StackOverflow

[3]:CloudWatch - Metrikstatistiken abrufen

verwandte Informationen