12

Sto cercando di ottenere AutoScalingRollingUpdate a lavorare sul mio gruppo autoscaling, portando nuovi in ​​linea casi, quindi solo una volta la nuova istanza (s) stanno accettando il traffico, terminando le vecchie istanze. Sembra che AutoScalingRollingUpdate sia progettato per questo scopo.AWS AutoScalingGroup HealthCheckType 'ELB' considera istanza "InService" prematuramente

Ho il HealthCheckType del mio AutoScalingGroup impostato su "ELB". Ho anche il HealthCheck sul set ELB di richiedere:

  • 3 richieste riuscite a/a "sano"
  • 10 richieste non riuscite a/per "non sano"
  • senza periodo di grazia (zero, 0)

Ora, dal punto di vista dell'ELB, quando le nuove istanze arrivano online, non sono InService per diversi minuti, che è quello che mi aspetto. Tuttavia, dal punto di vista di AutoScalingGroup, sono quasi immediatamente considerati InService e, come tale, il mio AutoScalingGroup sta mettendo fuori servizio delle istanze sane prima che le nuove istanze siano effettivamente pronte a ricevere traffico. Sono confuso perché l'ASG pensa che le istanze siano in buona salute prima che l'ELB lo faccia, quando HealthCheckType è impostato esplicitamente su "ELB".

Ho provato a impostare un periodo di prova, ma questo non cambia nulla. In effetti, ho rimosso il periodo di prova di 300 secondi perché pensavo che forse le istanze fossero implicitamente "InService" durante il periodo di prova o qualcosa del genere.

so di poter impostare un pausetime sulla politica di aggiornamento a rotazione, ma che è fragile, perché a volte gli errori accadono quando i casi sono in linea e ottengono Nuked e sostituiti prima che possano finire di provisioning, quindi volte, la finestra pausetime può essere superato Inoltre, mi piacerebbe ridurre al minimo la quantità di tempo in cui la mia app esegue due versioni diverse allo stesso tempo.

... ELB stuff ... 

    "HealthCheck": { 
     "HealthyThreshold": "3", 
     "UnhealthyThreshold": "10", 
     "Interval": "30", 
     "Timeout": "15", 
     "Target": { 
     "Fn::Join": [ 
      "", 
      [ 
      {"Fn::Join": [":", ["HTTP", {"Ref": "hostPort"}]]}, 
      {"Ref": "healthCheckPath"} 
      ] 
     ] 
     } 
    }, 

    ... ASG Stuff ... 

    { 
    ... snip ... 

    "HealthCheckType": "ELB", 
    "HealthCheckGracePeriod": "0", 
    "Cooldown": "300" 
    }, 
    "UpdatePolicy" : { 
    "AutoScalingRollingUpdate" : { 
     "MinInstancesInService" : "1", 
     "MaxBatchSize" : "1" 
    } 
    } 
+0

esaminare il tuo codice, penso che il problema non è in ASG 'impostazione AutoScalingGroup', è nel vostro ELB setting.' "HealthCheckGracePeriod": "0",' mi dà strana sensazione, si potrebbe passare a ' 300'. Dopodiché, ELB si occuperà della disponibilità, non dell'ASG. L'ASG si scalerà e diminuirà in base allo stato ELB. – BMW

+0

Anche con un periodo di prova, l'ASG considera l'istanza InService prima dell'ELB. Mi sembra un errore in CloudFormation. In realtà ho impostato quel tempo fino a zero nel tentativo di risolvere il problema. – d11wtq

+0

Sei sicuro che Load Balancer segnala l'istanza come "non sana"? Dove vedi questo stato? La console a volte non viene aggiornata immediatamente. La CLI di AWS ti offre lo stesso stato? Qual è il codice di stato HTTP della tua app mentre inizia? Restituisce HTTP 200 OK? Puoi verificarlo usando 'curl -I ...' –

risposta

17

In primo luogo, dalla nostra esperienza con CloudFormation ASG HealthCheckType e HealthCheckGracePeriod vengono sfruttate in primo luogo al di fuori della portata degli eventi CloudFormation. Queste proprietà entrano in gioco ogni volta che viene aggiunta una nuova istanza all'ASG. Questo può essere durante un aggiornamento di CloudFormation, ma anche durante gli eventi di Auto Scaling o durante un evento di auto-riparazione. In questi ultimi casi è importante impostare HealthCheckGracePeriod su un valore che dia alla nuova istanza il tempo sufficiente per entrare in linea prima di considerare i controlli di integrità ELB.

Sembra che la funzionalità che ti interessa di più sia l'UpdatePolicy che viene richiamato quando si esegue un aggiornamento di CloudFormation con una configurazione di avvio modificata. La proprietà magic è WaitOnResourceSignals che forza l'ASG ad attendere un segnale di successo prima di considerare l'aggiornamento un successo.

"UpdatePolicy" : { 
    "AutoScalingRollingUpdate" : { 
     "MinInstancesInService" : "1", 
     "MaxBatchSize" : "1", 
     "PauseTime" : "PT15M", 
     "WaitOnResourceSignals" : "true" 
    } 
    }, 

Quando la proprietà WaitOnResourceSignals è impostata su true, la proprietà pausetime diventa un timeout. Se l'ASG non riceve un segnale entro PauseTime di 15 minuti, l'aggiornamento viene considerato un errore e la nuova istanza viene interrotta. Non appena l'ASG riceve un segnale di successo, entra in gioco il controllo dello stato ASG, a meno che HealthCheckGracePeriod non sia ancora scaduto. Normalmente, impostiamo HealthCheckGracePeriod sullo stesso valore di PauseTime. Ciò garantisce che non iniziamo mai a utilizzare il controllo dello stato ELB prima che l'istanza abbia avuto la possibilità di inviare un segnale o raggiungere il timeout PauseTime. http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html

In genere, un segnale di successo viene inviato all'ASG seguendo lo script di bootstrap cfn-init all'interno dei Dati utente della Configurazione di avvio ASG.

"UserData"  : { "Fn::Base64" : { "Fn::Join" : ["", [ 
    "#!/bin/bash -xe\n", 
    "yum update -y aws-cfn-bootstrap\n", 

    "/opt/aws/bin/cfn-init -v ", 
    "   --stack ", { "Ref" : "AWS::StackName" }, 
    "   --resource LaunchConfig ", 
    "   --configsets full_install ", 
    "   --region ", { "Ref" : "AWS::Region" }, "\n", 

    "/opt/aws/bin/cfn-signal -e $? ", 
    "   --stack ", { "Ref" : "AWS::StackName" }, 
    "   --resource WebServerGroup ", 
    "   --region ", { "Ref" : "AWS::Region" }, "\n" 
]]}} 

Questo è sufficiente per molti casi, ma a volte l'istanza può non essere ancora pronta quando inviamo il segnale di successo di nuovo alla ASG. Ad esempio, potremmo voler attendere un processo in background per caricare i dati o attendere l'avvio del nostro server delle applicazioni. Ciò è particolarmente vero se il nostro controllo dello stato ELB si rivolge a un URL che richiede l'esecuzione della nostra applicazione. In questi casi vogliamo ritardare il segnale di successo finché la nostra istanza non è pronta. Ecco un esempio di come creare un configSet di configurazione di avvio per ritardare il segnale finché l'API ELB non restituisce uno stato "InService" per l'istanza.

"verify_instance_health" : { 
    "commands" : { 
     "ELBHealthCheck" : { 
     "command" : { "Fn::Join" : ["", [ 
      "until [ \"$state\" == \"\\\"InService\\\"\" ]; do ", 
      " state=$(aws --region ", { "Ref" : "AWS::Region" }, " elb describe-instance-health ", 
      "    --load-balancer-name ", { "Ref" : "ElasticLoadBalancer" }, 
      "    --instances $(curl -s http://169.254.169.254/latest/meta-data/instance-id) ", 
      "    --query InstanceStates[0].State); ", 
      " sleep 10; ", 
      "done" 
     ]]} 
     } 
    } 
    } 

Vedi il forum di discussione per ulteriori informazioni e un esempio completo utilizzando il controllo sanitario ELB - https://forums.aws.amazon.com/ann.jspa?annID=2741

Nota: Questi esempi richiedono inoltre di utilizzare l'ASG CreationPolicy attributo di ricevere i segnali durante la creazione ASG. In passato, le risorse WaitCondition e WaitConditionHandle venivano utilizzate per ricevere i segnali, ma questi non sono più raccomandati. L'attributo Count è il numero di segnali che dovrebbero essere ricevuti alla creazione. Questo valore dovrebbe essere uguale al numero MinSize ASG.

"CreationPolicy" : { 
    "ResourceSignal" : { 
     "Timeout" : "PT15M", 
     "Count" : "2" 
    } 
    }, 

http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-creationpolicy.html

+6

Molto utile, grazie. È un peccato che AutoScalingRollingUpdate non possa "funzionare" solo con il tipo di controllo dello stato ELB, in quanto eliminerebbe enormemente questo problema. Il 99% delle volte, se il tipo di controllo dello stato è "ELB", è ciò che conta per un'istanza da considerare "InService". – d11wtq

+0

Grazie per l'ottima guida. Il suggerimento di rendere 'HealthCheckGracePeriod' coerente con' PauseTime' era fondamentale.Il nostro 'HealthCheckGracePeriod' era più corto di' PauseTime' e il risultato era che l'ELB avrebbe iniziato a controllare la salute troppo presto, contrassegnare alcune istanze come malsane, forzarne di nuove da implementare e rendere l'intero aggiornamento un imprevedibile, dispendioso dispendio di tempo . Rendendo i due timeout uguali, quei problemi sono andati via. –

4

mi rendo conto che questo è un po 'in ritardo ma forse potrebbe salvare qualcuno un po' di tempo e fatica.

Se si utilizza elbv2, il comando avrà il seguente aspetto. Si prega di essere informati del "=" versus "==" come questo mi ha fatto inciampare per ore. Ubuntu 16 esegue comandi come /bin/sh e non /bin/bash il che significa che [ \"$state\" == \"\\\"healthy\\\"\" ] non avrà mai risultato vero. Almeno questa è la mia comprensione.

"commands": { 
    "ELBHealthCheck": { 
    "command": { 
     "Fn::Join": ["", [ 
     "until [ \"$state\" = \"\\\"healthy\\\"\" ]; do ", 
     "state=$(aws elbv2 describe-target-health ", 
     "--region ", { 
      "Ref": "AWS::Region" 
     }, 
     " ", 
     "--target-group-arn ", { 
      "Ref": "ELBRestPublicTargetGroup" 
     }, 
     " ", 
     "--targets Id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) ", 
     "--query TargetHealthDescriptions[0].TargetHealth.State); ", 
     "echo $(date): [$state] >> /tmp/health.log; ", 
     "sleep 10; ", 
     "done" 
     ]] 
    } 
    } 
} 
+0

Meglio tardi poi mai davvero! Mi hai appena salvato due giorni di confusione/frustrazione. Tutto è arrivato a '=='. Grazie! – grep

+0

Anche io sto affrontando un problema simile, puoi condividere il modello completo di cloudformation? Grazie – Umer

+0

Anche io sto affrontando un problema simile, puoi condividere il modello completo di cloudformation? Grazie – Umer