2017-05-15 4 views
0

Unsere Anwendung erfordert die Verwendung von HAProxy zum Lastenausgleich und Routenverkehr (eine pro AZ), ALBs und ELBs sind nicht konfigurierbar genug für unsere Zwecke. Bei der Bereitstellung von neuem Code über AWS CodeDeploy möchten wir, dass die gepatchten Instanzen in den Wartungsmodus versetzt werden (aus dem Lastenausgleich entfernt, Verbindungen abgebaut). Wir haben die standardmäßigen CodeDeploy-Lebenszyklus-Bash-Skripts so geändert, dass sie die Instanzen aus ihren jeweiligen HAProxy-Instanzen entfernen, indem sie einen SSM-Ausführungsbefehl von den betreffenden Instanzen an HAProxy senden. Derzeit funktioniert diese Änderung nicht und der Grund für den Fehler ist unbekannt. Das Skript funktioniert bei der manuellen Ausführung Schritt für Schritt (zumindest bis zum aktuellen Fehlerpunkt). Der Teil, der fehlschlägt, ist entweder der Test, der "$ INSTANCE_ID scheint nicht in einem AZ mit einer HAProxy-Instanz zu sein, die Deregistrierung überspringt.", Oder die Einstellung von $ HAPROXY_ID, von der der vorher erwähnte Test abhängt. Das Skript läuft bis zu diesem Punkt einwandfrei, wird aber an diesem Punkt beendet, da die HAProxy-Instanz-ID nicht gefunden werden kann.Entfernen von Instanzen von HAProxy während AWS CodeDeploy

Ich habe IAM Rollenberechtigungen/Berechtigungsnachweise, Umgebungsvariablen und Dateiberechtigungen überprüft, die alle korrekt zu sein scheinen. Normalerweise würde ich mehr Logging in das Skript legen, um zu debuggen, aber die Implementierungen sind zu wenig und weit genug, um das praktisch zu machen.

Meine Frage: Gibt es einen besseren Weg, dies zu tun? Ich kann nur raten, dass wir nicht die einzigen sind, die HAProxy mit CodeDeploy verwenden, und dazu muss es eine zuverlässige Methode geben. Im Folgenden wird der aktuelle Code verwendet, der nicht funktioniert.

#!/bin/bash 
# 
# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved. 
# 
# Licensed under the Apache License, Version 2.0 (the "License"). 
# You may not use this file except in compliance with the License. 
# A copy of the License is located at 
# 
# http://aws.amazon.com/apache2.0 
# 
# or in the "license" file accompanying this file. This file is distributed 
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
# express or implied. See the License for the specific language governing 
# permissions and limitations under the License. 

. $(dirname $0)/common_functions.sh 

if [[ "$DEPLOYMENT_GROUP_NAME" != "redacted" ]]; then 
    msg "ELB Deregistration doesn't need to happen when not on redacted." 
    exit 
fi 

msg "Running AWS CLI with region: $(get_instance_region)" 

# get this instance's ID 
INSTANCE_ID=$(get_instance_id) 
if [ $? != 0 -o -z "$INSTANCE_ID" ]; then 
    error_exit "Unable to get this instance's ID; cannot continue." 
fi 

# Get current time 
msg "Started $(basename $0) at $(/bin/date "+%F %T")" 
start_sec=$(/bin/date +%s.%N) 

msg "Checking if instance $INSTANCE_ID is part of an AutoScaling group" 
asg=$(autoscaling_group_name $INSTANCE_ID) 
if [ $? == 0 -a -n "${asg}" ]; then 
    msg "Found AutoScaling group for instance $INSTANCE_ID: ${asg}" 

    msg "Checking that installed CLI version is at least at version required for AutoScaling Standby" 
    check_cli_version 
    if [ $? != 0 ]; then 
     error_exit "CLI must be at least version ${MIN_CLI_X}.${MIN_CLI_Y}.${MIN_CLI_Z} to work with AutoScaling Standby" 
    fi 

    msg "Attempting to put instance into Standby" 
    autoscaling_enter_standby $INSTANCE_ID "${asg}" 
    if [ $? != 0 ]; then 
     error_exit "Failed to move instance into standby" 
    else 
     msg "Instance is in standby" 
    fi 
fi 

msg "Instance is not part of an ASG, continuing..." 

## Get the instanceID of the HAProxy instance in this AZ and ENVIRONMENT - Will there ever be more than one??? 

HAPROXY_ID=$(/usr/local/bin/aws ec2 describe-instances --region us-east-1 --filters "Name=availability-zone,Values=$(/usr/bin/curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)" "Name=tag:deployment_group,Values=haproxy.$ENVIRONMENT" --output text | \ 
grep INSTANCES | \ 
awk '{print $8}') 

HAPROXY_IP=$(/usr/local/bin/aws ec2 describe-instances --region us-east-1 --filters "Name=availability-zone,Values=$(/usr/bin/curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)" "Name=tag:deployment_group,Values=haproxy.$ENVIRONMENT" --output text | \ 
grep INSTANCES | \ 
awk '{print $13}') 

if test -z "$HAPROXY_ID"; then 
    msg "$INSTANCE_ID doesn't seem to be in an AZ with a HAProxy instance, skipping deregistration." 
    exit 
fi 

## Put the current instance into MAINT mode with the HAProxy instance via SSM 

msg "Deregistering $INSTANCE_ID from HAProxy $HAPROXY_ID" 

DEREGCMD="{\"commands\":[\"haproxyctl disable server bk_app_servers/$INSTANCEID\"],\"executionTimeout\":[\"3600\"]}" 

/usr/local/bin/aws ssm send-command \ 
--document-name "AWS-RunShellScript" \ 
--instance-ids "$HAPROXY_ID" \ 
--parameters "$DEREGCMD" \ 
--timeout-seconds 600 \ 
--output-s3-bucket-name "redacted" \ 
--output-s3-key-prefix "haproxy-codedeploy/deregister" \ 
--region us-east-1 

if [ $? != 0 ]; then 
    error_exit "Failed to send SSM command to deregister instance $INSTANCE_ID from HAProxy $HAPROXY_ID" 
fi 

## Wait for all connections to drain from instance 

SESS_COUNT=$(/usr/bin/curl -s "http://$HAPROXY_IP:<portredacted>/<urlredacted>" | grep $INSTANCEID | awk -F "," '{print $5}') 
DRAIN_TIME=60 

msg "Initial session count: $SESS_COUNT" 

while [[ "$SESS_COUNT" -gt 0 ]]; do 
    if [[ "$COUNTER" -gt "$DRAIN_TIME" ]]; then 
     msg "Instance failed to drain all connections within $DRAIN_TIME seconds. Continuing to deploy anyway." 
     break 
    fi 
    msg $SESS_COUNT 
    sleep 1 
    COUNTER=$(($COUNTER + 1)) 
    SESS_COUNT=$(/usr/bin/curl -s "http://$HAPROXY_IP:<portredacted>/<urlredacted>" | grep $INSTANCEID | awk -F "," '{print $5}') 
done 

msg "Finished $(basename $0) at $(/bin/date "+%F %T")" 

end_sec=$(/bin/date +%s.%N) 
elapsed_seconds=$(echo "$end_sec - $start_sec" | /usr/bin/bc) 

msg "Elapsed time: $elapsed_seconds" 

Antwort

0

Im Moment für Sie ist die einzige Option mehr Protokollierung hinzuzufügen und ein Deployment führen Sie dieses Skript zu testen, und dann bei der Bereitstellung Protokolle aussehen. Es klingt, als wüsstest du nicht, warum es scheitert und nur die Protokolle können dir das sagen.

Versuchen Sie, Protokollierung hinzuzufügen und zu sehen, was passiert. Wir sollten nur Ihr Skript ausführen, so ist es sollte nicht anders handeln, aber es ist schwer zu sagen, ohne die Protokolle zu sehen.

Viel Glück, - Asaf

Verwandte Themen