12

Próbuję dostać AutoScalingRollingUpdate pracować na moją grupę AutoScaling, wnosząc w Internecie nowych instancji, a następnie tylko raz nowa instancja (ów) przyjmując ruch, kończenie starych instancji. Wygląda na to, że AutoScalingRollingUpdate jest przeznaczona do tego celu.AWS AutoScalingGroup HealthCheckType „ELB” uważa Instancji „InService” przedwcześnie

Mam HealthCheckType z mojej AutoScalingGroup na "ELB". Mam też Healthcheck na planie ELB żądać:

  • 3 udanych wniosków do/dla "zdrowej"
  • 10 nieudanych żądań do/dla "niezdrowe"
  • bez okresu karencji (zero, 0)

Teraz, z perspektywy ELB, kiedy nowe instancje pojawiają się w Internecie, nie trwają przez kilka minut w InService, czego się spodziewam. Jednak z perspektywy AutoScalingGroup są one niemal natychmiast traktowane jako InService i jako takie, moja AutoScalingGroup zabrania zdrowych instancji niedziałających, zanim nowe instancje będą faktycznie gotowe do odbierania ruchu. Jestem zdezorientowany, dlaczego ASG uważa, że ​​instancje są zdrowe przed ELB, kiedy HealthCheckType jest jawnie ustawiony na "ELB".

Próbowałem ustawić okres karencji, ale to nic nie zmienia. W rzeczywistości usunąłem okres karencji 300 sekund, ponieważ uważałem, że być może instancje były niejawnie "InService" podczas okresu łaski lub coś takiego.

wiem, że mogę ustawić PauseTime na toczenia polityki aktualizacji, ale, że jest nietrwały, ponieważ czasami awarie zdarzyć, gdy przypadki trybu online i dostać nuked i zastąpione zanim kiedykolwiek zakończyć provisioning, więc czasami okno PauseTime może zostać przekroczone. Chciałbym też zminimalizować czas, w którym moja aplikacja działa w dwóch różnych wersjach jednocześnie.

... 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

weryfikacja kodu, myślę, że problem nie jest w ASG 'ustawienie AutoScalingGroup', to w ELB setting.'„HealthCheckGracePeriod”:„0”,' daje mi dziwne uczucie, można zmienić na ' 300'. Następnie ELB zajmie się dostępnością, a nie ASG. ASG będzie skalować w górę iw dół w zależności od statusu ELB. – BMW

+0

Nawet z okresem karencji ASG rozpatruje instancję InService przed wykonaniem ELB. Wygląda mi na błąd w CloudFormation. Rzeczywiście ustawiłem ten czas na zero, próbując naprawić problem. – d11wtq

+0

Czy na pewno program Load Balancer zgłasza wystąpienie jako "niezdrowe"? Gdzie widzisz ten status? Konsola nie jest od razu aktualizowana. Czy AWS CLI daje taki sam status? Jaki jest kod statusu aplikacji podczas jej uruchamiania? Czy zwraca HTTP 200 OK? Możesz to sprawdzić za pomocą 'curl -I ...' –

Odpowiedz

17

Po pierwsze, z naszych doświadczeń z CloudFormation ASG HealthCheckType i HealthCheckGracePeriod są dźwignią głównie poza zakres zdarzeń CloudFormation. Te właściwości wchodzą w grę za każdym razem, gdy nowa instancja zostanie dodana do ASG. Może to być podczas aktualizacji CloudFormation, ale także podczas zdarzeń Auto Scaling lub podczas zdarzenia samouzdrawiania. W tych ostatnich przypadkach ważne jest, aby ustawić HealthCheckGracePeriod na wartość, która daje nowej instancji wystarczającą ilość czasu, aby przejść do trybu online przed uwzględnieniem kontroli zdrowia ELB.

Wygląda na to, że najbardziej interesuje Cię funkcja UpdatePolicy, która jest wywoływana podczas uruchamiania aktualizacji CloudFormation ze zmodyfikowaną konfiguracją uruchamiania. Magiczną właściwością jest WaitOnResourceSignals, która zmusza ASG do oczekiwania na sygnał sukcesu, zanim pomyślimy o aktualizacji.

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

Gdy właściwość WaitOnResourceSignals jest ustawiony na true, właściwość PauseTime staje się limit czasu. Jeśli ASG nie odbierze sygnału w ramach PauseTime przez 15 minut, aktualizacja zostanie uznana za awarię, a nowa instancja zostanie zakończona. Gdy tylko ASG odbiera sygnał sukcesu, sprawdza się ASG, chyba że HealthCheckGracePeriod jeszcze nie wygasł. Zazwyczaj ustawiamy wartość HealthCheckGracePeriod na taką samą wartość, jak wartość parametru PauseTime. Gwarantuje to, że nigdy nie zaczniemy używać sprawdzenia kondycji ELB, zanim instancja będzie miała szansę wysłać sygnał lub osiągnąć limit czasu wstrzymania. http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html

Zazwyczaj sygnał sukcesu jest wysyłany do ASG po skrypcie ładowania początkowego cfn-init z UserData konfiguracji uruchamiania 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" 
]]}} 

Jest to wystarczające dla wielu przypadków, ale czasami instancja może nadal nie być gotowa, gdy wyślemy sygnał o powrocie do ASG. Na przykład możemy chcieć poczekać na proces w tle, aby załadować dane lub poczekać na uruchomienie naszego serwera aplikacji. Jest to szczególnie ważne, gdy nasze sprawdzenie kondycji ELB kieruje adres URL, który wymaga, aby nasza aplikacja była uruchomiona. W takich przypadkach chcemy opóźnić sygnał sukcesu, dopóki nasza instancja nie będzie gotowa. Oto przykład, jak utworzyć konfigurację konfiguracji uruchamiania, aby opóźnić sygnał, dopóki API ELB nie zwróci statusu "InService" dla instancji.

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

Zobacz to forum dyskusyjne, aby uzyskać więcej informacji oraz kompletnego przykład używając lekarskie ELB - https://forums.aws.amazon.com/ann.jspa?annID=2741

Uwaga: Te przykłady wymagają również, że używasz ASG CreationPolicy przypisują odbierać sygnały podczas tworzenia ASG. W przeszłości zasoby WaitCondition i WaitConditionHandle były używane do odbierania sygnałów, ale nie są już zalecane. Atrybut Liczba to liczba sygnałów, które powinny zostać odebrane podczas tworzenia. Ta wartość powinna być równa wartości ASG MinSize.

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

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

+6

Bardzo pomocne, dziękuję. Szkoda, że ​​AutoScalingRollingUpdate nie może "po prostu pracować" z typem kontroli ELB, ponieważ bardzo by to wyczyściło. W 99% przypadków, jeśli Twój typ sprawdzianu to "ELB", ważne jest, aby instancja została uznana za "InService". – d11wtq

+0

Dzięki za świetny przewodnik. Sugestia uczynienia 'HealthCheckGracePeriod' spójną z' PauseTime' była krytyczna.Nasz "HealthCheckGracePeriod" był krótszy niż "PauseTime", a wynikiem było to, że ELB zaczynałby sprawdzać stan zdrowia zbyt wcześnie, oznaczyć niektóre przypadki jako niezdrowe, zmusić nowe do wdrożenia i uczynić całą aktualizację aktualizacyjną nieprzewidywalnym, czasochłonnym bałaganem . Dzięki temu, że te dwa limity czasu są takie same, te problemy zniknęły. –

4

Zdaję sobie sprawę, że jest to trochę późno, ale być może uratować komuś trochę czasu i wysiłku.

Jeśli używasz elbv2, polecenie wyglądałoby następująco. Należy poinformować o numerze "=" w stosunku do "==", ponieważ spowodowało to wiele godzin. Ubuntu 16 uruchamia polecenia jako /bin/sh, a nie /bin/bash, co oznacza, że ​​[ \"$state\" == \"\\\"healthy\\\"\" ] nigdy nie będzie miało wartości true. Przynajmniej to jest moje zrozumienie.

"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

Lepiej późno niż w rzeczywistości! Właśnie uratowałeś mi dwa dni zamieszania/frustracji. Wszystko sprowadzało się do '=='. Dzięki! – grep

+0

Mam również do czynienia z podobnym problemem, czy możesz udostępnić Ci kompletny szablon Cloudformation? Dzięki – Umer

+0

Mam podobny problem, czy możesz udostępnić Ci kompletny szablon Cloudformation? Dzięki – Umer

Powiązane problemy