فحوصات صحة Auto Scaling Group: متى تتحول من EC2 إلى ELB؟

أحد أكثر المواقف إرباكاً في تشغيل بيئات الإنتاج هو مشاهدة ASG يُنهي instances تبدو سليمة تماماً من منظور EC2 — الجهاز يعمل، الشبكة متصلة، لكن التطبيق لا يستجيب. السبب الجذري في الغالب ليس خللاً في ASG، بل هو عدم تطابق بين نوع فحص الصحة المُكوَّن وما يعنيه 'السليم' فعلياً لتطبيقك.

ملخص سريع (TL;DR) — فحوصات صحة Auto Scaling Group

السيناريونوع الفحص المناسبالسلوك
الـ instance يعمل لكن التطبيق لا يستجيبELBيعتمد على نتيجة health check من Load Balancer
لا يوجد Load BalancerEC2يفحص حالة الـ instance على مستوى hypervisor فقط
التطبيق يحتاج وقتاً للتهيئة عند الإطلاقELB + grace period مناسبيمنح الـ instance وقتاً قبل بدء الفحص
فحوصات مخصصة خارج نطاق ELBCustom Health Check عبر APIتُرسل حالة الصحة يدوياً إلى ASG

كيف تعمل فحوصات صحة Auto Scaling Group

يعتمد ASG على مصدر واحد لتحديد ما إذا كان الـ instance يستحق البقاء أم يجب إنهاؤه واستبداله. هذا المصدر هو نوع فحص الصحة المُكوَّن. فهم الفرق بين المصادر المتاحة هو ما يفصل بين بيئة مستقرة وأخرى تُعاني من دوامة إنهاء مستمرة.

مصادر فحص الصحة

EC2 Health Check (الافتراضي): يفحص ASG حالة الـ instance على مستوى hypervisor عبر EC2 status checks. إذا كانت الحالة running وفحوصات النظام ناجحة، يعتبر الـ instance سليماً — بغض النظر عما يجري داخله.

ELB Health Check: عند تفعيله، يضيف ASG شرطاً إضافياً: يجب أن يُعلن Load Balancer أن الـ instance InService ضمن target group. هذا يعني أن فحص الصحة المُعرَّف على مستوى target group (HTTP endpoint، TCP port، إلخ) يجب أن ينجح.

Custom Health Check: يمكن لأي نظام خارجي إرسال حالة الصحة مباشرة إلى ASG عبر API set-instance-health، مما يتيح منطق فحص مخصص تماماً.

graph TD A["ASG يفحص صحة Instance"] --> B{"نوع الفحص المُفعَّل"} B --> C["EC2 فقط"] B --> D["ELB مُضاف"] C --> E["فحص حالة Hypervisor
running + system checks"] D --> F["فحص EC2
+ فحص Target Group"] E --> G{"Instance running?"} F --> H{"كلا الفحصين ناجحان?"} G -->|"نعم"| I["سليم ✓"] G -->|"لا"| J["إنهاء + استبدال"] H -->|"نعم"| I H -->|"فشل أحدهما"| J A --> K["Grace Period نشط?"] K -->|"نعم"| L["تجاهل نتائج الفحص مؤقتاً"]
  1. EC2 Check فقط: يفحص ASG حالة الـ instance على مستوى hypervisor — إذا كان running فهو 'سليم' بصرف النظر عن التطبيق.
  2. ELB Check مُضاف: يُضيف شرط نجاح health check من target group — التطبيق يجب أن يستجيب فعلياً.
  3. القرار النهائي: إذا فشل أي من المصدرين المُفعَّلين، يُعلَن الـ instance غير سليم ويُجدوَل للإنهاء.
  4. Grace Period: يحمي الـ instances الجديدة من الفحص المبكر خلال فترة التهيئة.

منطق دمج الفحوصات

نقطة دقيقة يغفلها كثيرون: عند تفعيل ELB health check في ASG، لا يُلغي فحص EC2 — بل يُضاف إليه. الـ instance يجب أن يجتاز كلا الفحصين ليُعتبر سليماً. فشل أي منهما يكفي لإطلاق عملية الإنهاء والاستبدال.

تشخيص المشكلة: لماذا يُنهي ASG instances سليمة؟

الخطوة 1: تحديد نوع فحص الصحة الحالي

قبل أي تغيير، تحقق من الإعداد الحالي. كثير من الفرق تفترض أن ELB health check مُفعَّل لمجرد وجود Load Balancer — وهذا افتراض خاطئ شائع.

aws autoscaling describe-auto-scaling-groups \
  --auto-scaling-group-names YOUR-ASG-NAME \
  --query 'AutoScalingGroups[0].{HealthCheckType:HealthCheckType,HealthCheckGracePeriod:HealthCheckGracePeriod,LoadBalancerNames:LoadBalancerNames,TargetGroupARNs:TargetGroupARNs}' \
  --output json

انتبه لحقل HealthCheckType — إذا كانت القيمة EC2 مع وجود target groups مُرتبطة، فأنت تعمل بفحص hypervisor فقط، والتطبيق غير مراقَب.

الخطوة 2: فحص سجل أنشطة ASG لفهم سبب الإنهاء

سجل الأنشطة يُخبرك بالضبط أي مصدر أعلن أن الـ instance غير سليم — هذا يوفر عليك ساعات من التخمين.

aws autoscaling describe-scaling-activities \
  --auto-scaling-group-name YOUR-ASG-NAME \
  --max-items 20 \
  --query 'Activities[?contains(Description, `Terminating`) || contains(Description, `unhealthy`)].{Time:StartTime,Description:Description,Cause:Cause}' \
  --output table

إذا رأيت في حقل Cause عبارات مثل an instance was taken out of service in response to a ELB system health check failure، فالمشكلة في target group health check وليس في إعداد ASG نفسه.

الخطوة 3: التحقق من حالة الـ instances في Target Group

إذا كان ELB health check مُفعَّلاً أو تخطط لتفعيله، تحقق من حالة الـ instances في target group مباشرة — هذا يكشف ما إذا كان المشكلة في الـ health check endpoint نفسه.

aws elbv2 describe-target-health \
  --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/YOUR-TG-NAME/1234567890abcdef \
  --query 'TargetHealthDescriptions[*].{Id:Target.Id,Port:Target.Port,State:TargetHealth.State,Reason:TargetHealth.Reason,Description:TargetHealth.Description}' \
  --output table

حالة unhealthy مع سبب Target.FailedHealthChecks تعني أن التطبيق لا يستجيب للـ health check endpoint المُعرَّف. تحقق من أن المسار صحيح وأن الـ security group يسمح بالاتصال من Load Balancer.

الخطوة 4: مراجعة إعدادات Health Check في Target Group

المشكلة الأكثر شيوعاً التي تُسبب إنهاء instances سليمة هي health check endpoint يُعيد كود HTTP غير 2xx، أو timeout قصير جداً لتطبيق بطيء الاستجابة.

aws elbv2 describe-target-groups \
  --target-group-arns arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/YOUR-TG-NAME/1234567890abcdef \
  --query 'TargetGroups[0].{Protocol:HealthCheckProtocol,Path:HealthCheckPath,Port:HealthCheckPort,Interval:HealthCheckIntervalSeconds,Timeout:HealthCheckTimeoutSeconds,HealthyThreshold:HealthyThresholdCount,UnhealthyThreshold:UnhealthyThresholdCount,Matcher:Matcher}' \
  --output json

الخطوة 5: التحول من EC2 إلى ELB Health Check

بعد التحقق من أن target group health check يعمل بشكل صحيح، يمكن تغيير نوع فحص الصحة في ASG. لاحظ أن هذا التغيير يسري على الـ instances الجديدة والحالية.

aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name YOUR-ASG-NAME \
  --health-check-type ELB \
  --health-check-grace-period 300

قيمة health-check-grace-period بالثواني — اضبطها بناءً على الوقت الفعلي الذي يحتاجه تطبيقك للوصول إلى حالة جاهزة لاستقبال الطلبات. إذا كان تطبيقك يحتاج 4 دقائق للتهيئة وضبطت 60 ثانية، ستدخل في دوامة إنهاء لا تنتهي.

تجربة من الإنتاج: التشخيص الخاطئ الكلاسيكي

الأعراض كانت واضحة: ASG يُنهي instances كل 8-10 دقائق بعد النشر، والفريق يرى الـ instances في حالة running في EC2 console. الافتراض الأول كان خطأً في AMI أو مشكلة في bootstrap script.

بعد مراجعة سجل الأنشطة، ظهر السبب: an instance was taken out of service in response to a ELB system health check failure. التطبيق كان يعمل — لكن health check endpoint كان /health بينما التطبيق الجديد غيّر المسار إلى /api/health دون تحديث إعداد target group.

الـ EC2 health check كان يُعلن الـ instance سليماً لأن الجهاز يعمل. ELB health check كان يُعلنه غير سليم لأن /health يُعيد 404. ASG يدمج المصدرين — فشل أحدهما يكفي.

الإصلاح كان تحديث health check path في target group، لا تغيير نوع فحص الصحة في ASG.

aws elbv2 modify-target-group \
  --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/YOUR-TG-NAME/1234567890abcdef \
  --health-check-path /api/health \
  --health-check-interval-seconds 30 \
  --health-check-timeout-seconds 10 \
  --healthy-threshold-count 2 \
  --unhealthy-threshold-count 3

إعداد Custom Health Check عبر API

في بعض السيناريوهات، لا يكفي فحص HTTP endpoint — قد تحتاج إلى منطق مخصص مثل التحقق من اتصال قاعدة البيانات أو جاهزية cache. في هذه الحالة، يمكن لنظام خارجي إرسال حالة الصحة مباشرة إلى ASG.

aws autoscaling set-instance-health \
  --instance-id i-1234567890abcdef0 \
  --health-status Unhealthy \
  --should-respect-grace-period

الخيار --should-respect-grace-period يمنع الإنهاء الفوري إذا كان الـ instance لا يزال ضمن grace period — مفيد لتجنب إنهاء instances في مرحلة التهيئة.

صلاحيات IAM المطلوبة

إذا كانت أدوات المراقبة أو CI/CD pipeline تحتاج إلى قراءة حالة ASG أو تحديثها، هذه الصلاحيات الدنيا المطلوبة:

🔽 عرض سياسة IAM
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadASGHealth",
      "Effect": "Allow",
      "Action": [
        "autoscaling:DescribeAutoScalingGroups",
        "autoscaling:DescribeScalingActivities",
        "elasticloadbalancing:DescribeTargetHealth",
        "elasticloadbalancing:DescribeTargetGroups"
      ],
      "Resource": "*"
    },
    {
      "Sid": "UpdateASGHealthCheck",
      "Effect": "Allow",
      "Action": [
        "autoscaling:UpdateAutoScalingGroup",
        "autoscaling:SetInstanceHealth"
      ],
      "Resource": "arn:aws:autoscaling:us-east-1:123456789012:autoScalingGroup:*:autoScalingGroupName/YOUR-ASG-NAME"
    },
    {
      "Sid": "UpdateTargetGroup",
      "Effect": "Allow",
      "Action": [
        "elasticloadbalancing:ModifyTargetGroup"
      ],
      "Resource": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/YOUR-TG-NAME/*"
    }
  ]
}

لاحظ أن DescribeAutoScalingGroups وDescribeScalingActivities تتطلب Resource: "*" لأن هذه الـ actions لا تدعم تقييد الموارد على مستوى ARN وفقاً لـ Service Authorization Reference.

متى تبقى على EC2 Health Check؟

التحول إلى ELB health check ليس دائماً الإجابة الصحيحة. إذا لم يكن لديك Load Balancer، أو كانت الـ instances تؤدي مهام background processing بدون HTTP endpoint، فإن ELB health check غير مناسب. كذلك إذا كان تطبيقك يحتاج وقتاً طويلاً للتهيئة وكان grace period غير مضبوط بدقة، قد يُسبب التحول موجة من الإنهاءات غير المبررة عند النشر.

graph TD START["Instances تُنهى بشكل غير متوقع"] --> LOG["فحص سجل أنشطة ASG"] LOG --> Q1{"ما مصدر إعلان عدم الصحة?"} Q1 -->|"EC2 system check"| EC2PATH["مشكلة في الـ instance نفسه"] Q1 -->|"ELB health check"| ELBPATH["مشكلة في التطبيق أو endpoint"] Q1 -->|"إنهاء مبكر جداً"| GRACE["Grace Period قصير جداً"] EC2PATH --> EC2FIX["فحص EC2 console
system status checks"] ELBPATH --> TGCHECK["فحص حالة instances
في Target Group"] TGCHECK --> Q2{"هل الـ endpoint صحيح?"} Q2 -->|"لا"| FIXPATH["تحديث health check path
في Target Group"] Q2 -->|"نعم، لكن ASG على EC2"| CHANGETYPE["تغيير HealthCheckType
إلى ELB في ASG"] GRACE --> GRACEFIX["زيادة health-check-grace-period"]
  1. نقطة البداية: instances تُنهى بشكل غير متوقع.
  2. فحص سجل الأنشطة: تحديد مصدر إعلان عدم الصحة.
  3. مسار EC2: مشكلة في الـ instance نفسه — فحص system status checks.
  4. مسار ELB: مشكلة في التطبيق أو health check endpoint — فحص target group.
  5. مسار Grace Period: الـ instance يُنهى قبل اكتمال التهيئة — زيادة grace period.

الخلاصة والخطوات التالية لـ Auto Scaling Group Health Checks

التحول من EC2 إلى ELB health check يحل مشكلة instances تبدو سليمة لكن تطبيقها لا يستجيب — لكنه يفترض أن target group health check مُعرَّف بشكل صحيح ويعمل. الخطأ الشائع هو تغيير نوع الفحص في ASG دون التحقق من أن الـ health check endpoint في target group يعمل فعلاً.

الخطوة الأولى دائماً هي قراءة سجل أنشطة ASG لتحديد مصدر إعلان عدم الصحة، ثم التحقق من حالة الـ instances في target group مباشرة. هذا يوفر عليك تغييرات عمياء قد تُفاقم المشكلة.

مسرد المصطلحات

المصطلحالتعريف
EC2 Status Checkفحص على مستوى hypervisor يتحقق من أن الـ instance يعمل وأن النظام الأساسي سليم
ELB Health Checkفحص يُجريه Load Balancer على الـ instance للتحقق من أن التطبيق يستجيب وفق المعايير المُعرَّفة
Health Check Grace Periodفترة زمنية بالثواني يتجاهل فيها ASG نتائج فحص الصحة بعد إطلاق instance جديد
Target Groupمجموعة من الـ targets (instances، IPs، Lambda) يوجّه إليها Load Balancer الطلبات
InService / Unhealthyحالات الـ instance في target group — InService يعني نجاح health check، Unhealthy يعني الفشل

Related Posts

تعليقات

المشاركات الشائعة من هذه المدونة

استرجاع معرّف نسخة EC2 عبر خدمة البيانات الوصفية IMDSv2

أوضاع سعة DynamoDB: متى تختار On-Demand ومتى تختار Provisioned؟

فهم مهلة الرؤية في SQS: لماذا تُعالَج رسائلك مرتين؟