إذا كنت تدير مجموعات EKS، فمن المؤكد أنك تعرف تحديات تخصيص العقد بكفاءة. هنا يأتي دور كاربنتر ليغير الطريقة التي تدير بها مواردك، منهياً مشكلة الهدر والتخمين في أحجام مجموعات العقد.
هل تتعب من تخمين أحجام مجموعات العقد في EKS؟ يبدو أنك لست وحدك! إذا كنت تدير مجموعات EKS لفترة، فأنت تعلم جيدًا المعاناة: تُخصص مجموعات العقد الخاصة بك بناءً على تقديرات تقريبية لحمل الذروة، وتزيد من هذا التقدير خوفاً من تعطل التطبيقات، لتجد في النهاية أن نصف أسطولك لا يعمل، والفاتورة تتصاعد بهدوء. هذا ليس مجرد مشكلة جدولة، بل مشكلة توقع، وكوبرنيتيس وحده لم يُصمم لحلها.
ماذا يعني هذا بالنسبة لك؟ حسناً، قبل ظهور كاربنتر، كان التوسع التلقائي على EKS يعتمد بشكل كبير على Cluster Autoscaler (CA) ومجموعات التوسيع التلقائي (ASG). كانت العملية كالتالي: تحدد مجموعات عقد مُدارة، كل منها مدعومة بـ ASG مرتبطة بنوع معين من المثيلات. يراقب Cluster Autoscaler خادم API بحثًا عن Pods في حالة Pending (معلقة) حدث لها FailedScheduling (فشل الجدولة). ثم يقوم بمحاكاة: «إذا أضفت عقدة واحدة من مجموعة العقد X، فهل سيتم جدولة هذا الـ Pod؟» إذا كانت الإجابة نعم، فإنه يزيد السعة المطلوبة لـ ASG بواحد، وتطلق ASG مثيلاً، ويسجل الـ kubelet، ويربط المجدول الـ Pod.
لكن هذه الطريقة القديمة كانت بها مشكلة كبيرة. Cluster Autoscaler يمكنه فقط المحاكاة مقابل مجموعات العقد الموجودة بالفعل. لا يستطيع «اختراع» شكل عقدة جديدة لتناسب احتياجاتك بالضبط. على سبيل المثال، إذا كانت مجموعتك مبنية على مثيلات m5.xlarge (4 vCPU، 16 جيجابايت) وجاءت دفعة من Pods تطلب كل منها 2 vCPU و 14 جيجابايت، فإن كل عقدة تضيفها ستستوعب Podًا واحدًا فقط، وتهدر 2 vCPU. سيستمر Cluster Autoscaler بفعل ذلك طوال اليوم، لأنه من منظوره، نجحت المحاكاة.
وهناك مشكلة أخرى: يتطلب Cluster Autoscaler أن تكون كل عقدة في المجموعة متجانسة حتى تكون محاكاته صحيحة. إذا قمت بخلط أنواع المثيلات داخل ASG واحدة، يصبح تقدير الـ Autoscaler «لما توفره العقدة من هذه المجموعة» خاطئًا، مما يؤدي إلى تخصيص مفرط أو غير فعال. يأتي كاربنتر ليحل هذه التحديات، مما يتيح لك تكوين NodePools بشكل أكثر ذكاءً وكفاءة، ويوفر لك المال ويقلل من القلق بشأن العقد الخاملة.
ماذا يعني هذا بالنسبة لك؟ حسناً، قبل ظهور كاربنتر، كان التوسع التلقائي على EKS يعتمد بشكل كبير على Cluster Autoscaler (CA) ومجموعات التوسيع التلقائي (ASG). كانت العملية كالتالي: تحدد مجموعات عقد مُدارة، كل منها مدعومة بـ ASG مرتبطة بنوع معين من المثيلات. يراقب Cluster Autoscaler خادم API بحثًا عن Pods في حالة Pending (معلقة) حدث لها FailedScheduling (فشل الجدولة). ثم يقوم بمحاكاة: «إذا أضفت عقدة واحدة من مجموعة العقد X، فهل سيتم جدولة هذا الـ Pod؟» إذا كانت الإجابة نعم، فإنه يزيد السعة المطلوبة لـ ASG بواحد، وتطلق ASG مثيلاً، ويسجل الـ kubelet، ويربط المجدول الـ Pod.
لكن هذه الطريقة القديمة كانت بها مشكلة كبيرة. Cluster Autoscaler يمكنه فقط المحاكاة مقابل مجموعات العقد الموجودة بالفعل. لا يستطيع «اختراع» شكل عقدة جديدة لتناسب احتياجاتك بالضبط. على سبيل المثال، إذا كانت مجموعتك مبنية على مثيلات m5.xlarge (4 vCPU، 16 جيجابايت) وجاءت دفعة من Pods تطلب كل منها 2 vCPU و 14 جيجابايت، فإن كل عقدة تضيفها ستستوعب Podًا واحدًا فقط، وتهدر 2 vCPU. سيستمر Cluster Autoscaler بفعل ذلك طوال اليوم، لأنه من منظوره، نجحت المحاكاة.
وهناك مشكلة أخرى: يتطلب Cluster Autoscaler أن تكون كل عقدة في المجموعة متجانسة حتى تكون محاكاته صحيحة. إذا قمت بخلط أنواع المثيلات داخل ASG واحدة، يصبح تقدير الـ Autoscaler «لما توفره العقدة من هذه المجموعة» خاطئًا، مما يؤدي إلى تخصيص مفرط أو غير فعال. يأتي كاربنتر ليحل هذه التحديات، مما يتيح لك تكوين NodePools بشكل أكثر ذكاءً وكفاءة، ويوفر لك المال ويقلل من القلق بشأن العقد الخاملة.