Kubernetes پر پہلی ایپلیکیشن تعینات کرتے وقت پانچ مسز

Kubernetes پر پہلی ایپلیکیشن تعینات کرتے وقت پانچ مسزAris Dreamer کی طرف سے ناکام

بہت سے لوگوں کا خیال ہے کہ یہ ایپلیکیشن کوبرنیٹس میں منتقل کرنا کافی ہے (یا تو ہیلم کا استعمال کرتے ہوئے یا دستی طور پر) - اور خوشی ہوگی۔ لیکن سب کچھ اتنا آسان نہیں ہے۔

ٹیم Mail.ru کلاؤڈ سلوشنز DevOps انجینئر جولین گینڈی کے ایک مضمون کا ترجمہ کیا۔ وہ بتاتا ہے کہ ہجرت کے عمل کے دوران اس کی کمپنی کو کن نقصانات کا سامنا کرنا پڑا تاکہ آپ ایک ہی ریک پر قدم نہ رکھیں۔

پہلا مرحلہ: پوڈ کی درخواستیں اور حدود مرتب کریں۔

آئیے ایک صاف ستھرا ماحول ترتیب دے کر شروع کریں جس میں ہماری پھلیاں چلیں گی۔ Kubernetes پوڈ شیڈولنگ اور فیل اوور میں بہت اچھا ہے۔ لیکن یہ پتہ چلا کہ شیڈولر بعض اوقات پوڈ نہیں رکھ سکتا اگر یہ اندازہ لگانا مشکل ہو کہ اسے کامیابی سے کام کرنے کے لیے کتنے وسائل کی ضرورت ہے۔ یہ وہ جگہ ہے جہاں وسائل اور حدود کی درخواستیں آتی ہیں۔ درخواستوں اور حدود کو ترتیب دینے کے لیے بہترین نقطہ نظر کے بارے میں کافی بحث ہے۔ کبھی کبھی ایسا لگتا ہے کہ یہ واقعی سائنس سے زیادہ ایک فن ہے۔ یہاں ہمارا نقطہ نظر ہے.

پوڈ کی درخواستیں۔ پوڈ کو بہترین طریقے سے رکھنے کے لیے شیڈیولر کے ذریعے استعمال ہونے والی اہم قیمت ہے۔

میں سے Kubernetes دستاویزات: فلٹر مرحلہ نوڈس کے ایک سیٹ کی وضاحت کرتا ہے جہاں ایک پوڈ کو شیڈول کیا جا سکتا ہے۔ مثال کے طور پر، PodFitsResources فلٹر یہ دیکھنے کے لیے چیک کرتا ہے کہ آیا کسی نوڈ کے پاس پوڈ سے مخصوص وسائل کی درخواستوں کو پورا کرنے کے لیے کافی وسائل ہیں۔

ہم درخواست کی درخواستیں اس طرح استعمال کرتے ہیں کہ ہم اندازہ لگا سکیں کہ کتنے وسائل ہیں۔ حقیقت میں ایپلی کیشن کو مناسب طریقے سے کام کرنے کی ضرورت ہے۔ اس طرح شیڈولر حقیقت پسندانہ طور پر نوڈس رکھ سکتا ہے۔ ابتدائی طور پر، ہم ہر پوڈ کے لیے کافی وسائل کو یقینی بنانے کے لیے درخواستوں کو اوور شیڈیول کرنا چاہتے تھے، لیکن ہم نے دیکھا کہ شیڈولنگ کے وقت میں نمایاں اضافہ ہوا، اور کچھ پوڈز مکمل طور پر طے شدہ نہیں تھے، گویا ان کے لیے وسائل کی کوئی درخواستیں نہیں تھیں۔

اس صورت میں، شیڈیولر اکثر پوڈز کو "نچوڑ" دیتا تھا اور انہیں دوبارہ شیڈول کرنے کے قابل نہیں رہتا تھا کیونکہ کنٹرول جہاز کو اندازہ نہیں تھا کہ ایپلیکیشن کو کتنے وسائل کی ضرورت ہوگی، جو کہ شیڈولنگ الگورتھم کا ایک اہم جز ہے۔

پھلی کی حدود پوڈ کے لیے ایک واضح حد ہے۔ یہ وسائل کی زیادہ سے زیادہ مقدار کی نمائندگی کرتا ہے جو کلسٹر کنٹینر کو مختص کرے گا۔

دوبارہ، سے سرکاری دستاویزات: اگر ایک کنٹینر کی میموری کی حد 4 GiB ہے، تو کیوبلیٹ (اور کنٹینر کا رن ٹائم) اسے نافذ کرے گا۔ رن ٹائم کنٹینر کو مخصوص وسائل کی حد سے زیادہ استعمال کرنے سے روکتا ہے۔ مثال کے طور پر، جب کسی کنٹینر میں کوئی عمل میموری کی اجازت شدہ مقدار سے زیادہ استعمال کرنے کی کوشش کرتا ہے، تو سسٹم کرنل اس عمل کو "آؤٹ آف میموری" (OOM) کی خرابی کے ساتھ ختم کر دیتا ہے۔

ایک کنٹینر ہمیشہ وسائل کی درخواست سے زیادہ وسائل استعمال کرسکتا ہے، لیکن یہ کبھی بھی حد سے زیادہ استعمال نہیں کرسکتا۔ اس قدر کو درست طریقے سے سیٹ کرنا مشکل ہے، لیکن یہ بہت ضروری ہے۔

مثالی طور پر، ہم چاہتے ہیں کہ پوڈ کے وسائل کی ضروریات نظام میں دیگر عملوں میں مداخلت کیے بغیر کسی عمل کے لائف سائیکل کے دوران تبدیل ہوں - یہ حدود طے کرنے کا مقصد ہے۔

بدقسمتی سے، میں اس بارے میں مخصوص ہدایات نہیں دے سکتا کہ کن اقدار کو سیٹ کرنا ہے، لیکن ہم خود درج ذیل اصولوں پر عمل کرتے ہیں:

  1. لوڈ ٹیسٹنگ ٹول کا استعمال کرتے ہوئے، ہم ٹریفک کی بنیادی سطح کی نقل کرتے ہیں اور پوڈ وسائل (میموری اور پروسیسر) کے استعمال کا مشاہدہ کرتے ہیں۔
  2. پوڈ کی درخواستوں کو من مانی طور پر کم قیمت پر سیٹ کریں (درخواستوں کی قیمت سے تقریبا 5 گنا وسائل کی حد کے ساتھ) اور مشاہدہ کریں۔ جب درخواستیں بہت کم سطح پر ہوں، تو عمل شروع نہیں ہو سکتا، اکثر خفیہ Go رن ٹائم کی خرابیوں کا باعث بنتا ہے۔

میں نوٹ کرتا ہوں کہ وسائل کی اعلیٰ حدیں شیڈولنگ کو مزید مشکل بنا دیتی ہیں کیونکہ پوڈ کو کافی وسائل کے ساتھ ٹارگٹ نوڈ کی ضرورت ہوتی ہے۔

ایسی صورت حال کا تصور کریں جہاں آپ کے پاس ایک ہلکا پھلکا ویب سرور ہے جس میں وسائل کی حد بہت زیادہ ہے، جیسے 4 جی بی میموری۔ اس عمل کو ممکنہ طور پر افقی طور پر چھوٹا کرنے کی ضرورت ہوگی، اور ہر نئے پوڈ کو کم از کم 4 جی بی دستیاب میموری والے نوڈ پر شیڈول کرنے کی ضرورت ہوگی۔ اگر ایسا کوئی نوڈ موجود نہیں ہے، تو کلسٹر کو اس پوڈ پر کارروائی کرنے کے لیے ایک نیا نوڈ متعارف کرانا چاہیے، جس میں کچھ وقت لگ سکتا ہے۔ تیز رفتار اور ہموار پیمانے کو یقینی بنانے کے لیے وسائل کی درخواستوں اور حدود کے درمیان کم از کم فرق حاصل کرنا ضروری ہے۔

دوسرا مرحلہ: زندہ دلی اور تیاری کے ٹیسٹ مرتب کریں۔

یہ ایک اور لطیف موضوع ہے جس پر کبرنیٹس کمیونٹی میں اکثر بحث کی جاتی ہے۔ لائیونس اور ریڈی نیس ٹیسٹ کے بارے میں اچھی طرح سمجھنا ضروری ہے کیونکہ یہ سافٹ ویئر کے مستحکم آپریشن کے لیے ایک طریقہ کار فراہم کرتے ہیں اور ڈاؤن ٹائم کو کم سے کم کرتے ہیں۔ تاہم، اگر صحیح طریقے سے ترتیب نہ دی گئی ہو تو وہ آپ کی درخواست کی کارکردگی کو سنجیدگی سے متاثر کر سکتے ہیں۔ ذیل میں ایک خلاصہ ہے کہ دونوں نمونے کیا ہیں۔

جیونت ظاہر کرتا ہے کہ کنٹینر چل رہا ہے. اگر یہ ناکام ہو جاتا ہے تو، کیوبلیٹ کنٹینر کو ختم کر دیتا ہے اور اس کے لیے دوبارہ شروع کرنے کی پالیسی فعال ہو جاتی ہے۔ اگر کنٹینر Liveness Probe سے لیس نہیں ہے، تو پہلے سے طے شدہ حالت کامیاب ہوگی - جیسا کہ اس میں بتایا گیا ہے۔ Kubernetes دستاویزات.

لائیونس پروبس سستے ہونے چاہئیں، یعنی بہت زیادہ وسائل استعمال نہ کریں، کیونکہ وہ کثرت سے چلتے ہیں اور انہیں Kubernetes کو مطلع کرنا چاہیے کہ ایپلیکیشن چل رہی ہے۔

اگر آپ ہر سیکنڈ چلانے کا آپشن سیٹ کرتے ہیں، تو اس میں فی سیکنڈ 1 درخواست کا اضافہ ہو جائے گا، لہذا آگاہ رہیں کہ اس ٹریفک کو پروسیس کرنے کے لیے اضافی وسائل کی ضرورت ہوگی۔

ہماری کمپنی میں، Liveness ٹیسٹ کسی ایپلیکیشن کے بنیادی اجزاء کی جانچ کرتے ہیں، چاہے ڈیٹا (مثال کے طور پر، ریموٹ ڈیٹا بیس یا کیشے سے) پوری طرح دستیاب نہ ہو۔

ہم نے ایپلی کیشنز میں ایک "صحت" کا اختتامی نقطہ ترتیب دیا ہے جو صرف 200 رسپانس کوڈ واپس کرتا ہے۔ یہ اس بات کا اشارہ ہے کہ عمل چل رہا ہے اور درخواستوں کو ہینڈل کرنے کے قابل ہے (لیکن ابھی تک ٹریفک نہیں)۔

کوشش کریں تیاری اشارہ کرتا ہے کہ آیا کنٹینر درخواستوں کی خدمت کے لیے تیار ہے۔ اگر ریڈی نیس پروب ناکام ہو جاتا ہے تو اینڈ پوائنٹ کنٹرولر پوڈ کے آئی پی ایڈریس کو پوڈ سے مماثل تمام سروسز کے اینڈ پوائنٹس سے ہٹا دیتا ہے۔ یہ بھی Kubernetes دستاویزات میں بیان کیا گیا ہے۔

تیاری کی تحقیقات زیادہ وسائل استعمال کرتی ہیں، کیونکہ انہیں بیک اینڈ کو اس طرح مارنا چاہیے کہ یہ ظاہر ہو کہ درخواست درخواستوں کو قبول کرنے کے لیے تیار ہے۔

کمیونٹی میں اس بارے میں کافی بحث ہے کہ آیا ڈیٹا بیس تک براہ راست رسائی حاصل کی جائے۔ اوور ہیڈ کو مدنظر رکھتے ہوئے (چیک اکثر ہوتے ہیں، لیکن ان کو کنٹرول کیا جا سکتا ہے)، ہم نے فیصلہ کیا کہ کچھ ایپلی کیشنز کے لیے، ٹریفک کی خدمت کے لیے تیاری صرف اس جانچ کے بعد شمار کی جاتی ہے کہ ڈیٹا بیس سے ریکارڈ واپس آئے ہیں۔ اچھی طرح سے تیار کردہ تیاری کے ٹرائلز نے اعلی سطح کی دستیابی کو یقینی بنایا اور تعیناتی کے دوران ڈاؤن ٹائم کو ختم کیا۔

اگر آپ اپنی درخواست کی تیاری کو جانچنے کے لیے ڈیٹا بیس سے استفسار کرنے کا فیصلہ کرتے ہیں، تو یقینی بنائیں کہ یہ جتنا ممکن ہو سستا ہے۔ آئیے اس سوال کو لیتے ہیں:

SELECT small_item FROM table LIMIT 1

یہاں ایک مثال ہے کہ ہم کبرنیٹس میں ان دو اقدار کو کس طرح ترتیب دیتے ہیں:

livenessProbe: 
 httpGet:   
   path: /api/liveness    
   port: http 
readinessProbe:  
 httpGet:    
   path: /api/readiness    
   port: http  periodSeconds: 2

آپ کچھ اضافی ترتیب کے اختیارات شامل کر سکتے ہیں:

  • initialDelaySeconds - کنٹینر کے آغاز اور تحقیقات کے آغاز کے درمیان کتنے سیکنڈ گزریں گے۔
  • periodSeconds - نمونے کی دوڑ کے درمیان انتظار کا وقفہ۔
  • timeoutSeconds - سیکنڈوں کی تعداد جس کے بعد پوڈ کو ایمرجنسی سمجھا جاتا ہے۔ نارمل ٹائم آؤٹ۔
  • failureThreshold پوڈ کو دوبارہ شروع کرنے کا سگنل بھیجے جانے سے پہلے ٹیسٹ میں ناکامیوں کی تعداد ہے۔
  • successThreshold پوڈ کے تیار حالت میں منتقلی سے پہلے کامیاب آزمائشوں کی تعداد ہے (ناکامی کے بعد جب پوڈ شروع ہوتا ہے یا ٹھیک ہوجاتا ہے)۔

تیسرا مرحلہ: پوڈ کی ڈیفالٹ نیٹ ورک پالیسیاں ترتیب دینا

Kubernetes میں ایک "فلیٹ" نیٹ ورک ٹپوگرافی ہے، بطور ڈیفالٹ تمام پوڈز ایک دوسرے سے براہ راست بات چیت کرتے ہیں۔ بعض صورتوں میں یہ مطلوب نہیں ہے۔

سیکیورٹی کا ایک ممکنہ مسئلہ یہ ہے کہ حملہ آور نیٹ ورک پر موجود تمام پوڈز پر ٹریفک بھیجنے کے لیے ایک ہی کمزور ایپلیکیشن کا استعمال کر سکتا ہے۔ سیکورٹی کے بہت سے شعبوں کی طرح، کم از کم استحقاق کا اصول یہاں لاگو ہوتا ہے۔ مثالی طور پر، نیٹ ورک کی پالیسیوں کو واضح طور پر بتانا چاہیے کہ پوڈز کے درمیان کن کنکشنز کی اجازت ہے اور کون سے نہیں۔

مثال کے طور پر، درج ذیل ایک سادہ پالیسی ہے جو کسی خاص نام کی جگہ کے لیے آنے والے تمام ٹریفک کو مسترد کرتی ہے:

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:  
 name: default-deny-ingress
spec:  
 podSelector: {}  
 policyTypes:  
   - Ingress

اس ترتیب کا تصور:

Kubernetes پر پہلی ایپلیکیشن تعینات کرتے وقت پانچ مسز
(https://miro.medium.com/max/875/1*-eiVw43azgzYzyN1th7cZg.gif)
مزید تفصیلات یہاں.

چوتھا مرحلہ: ہکس اور انیٹ کنٹینرز کے ساتھ حسب ضرورت برتاؤ

ہمارے اہم اہداف میں سے ایک یہ تھا کہ ڈویلپرز کے لیے بغیر وقت کے Kubernetes میں تعیناتیاں فراہم کی جائیں۔ یہ مشکل ہے کیونکہ ایپلی کیشنز کو بند کرنے اور ان کے استعمال شدہ وسائل کو جاری کرنے کے بہت سے اختیارات موجود ہیں۔

کے ساتھ خاص مشکلات پیدا ہوئیں نگنکس. ہم نے دیکھا کہ جب ان پوڈز کو ترتیب سے تعینات کیا گیا تو، کامیابی سے مکمل ہونے سے پہلے فعال کنکشن میں خلل پڑا۔

انٹرنیٹ پر وسیع تحقیق کے بعد، یہ پتہ چلا کہ Kubernetes پوڈ کو بند کرنے سے پہلے Nginx کنکشن کے ختم ہونے کا انتظار نہیں کرتا ہے۔ پری اسٹاپ ہک کی مدد سے، ہم نے درج ذیل فعالیت کو نافذ کیا اور مکمل طور پر ڈاؤن ٹائم سے چھٹکارا حاصل کیا:

lifecycle: 
 preStop:
   exec:
     command: ["/usr/local/bin/nginx-killer.sh"]

لیکن nginx-killer.sh:

#!/bin/bash
sleep 3
PID=$(cat /run/nginx.pid)
nginx -s quit
while [ -d /proc/$PID ]; do
   echo "Waiting while shutting down nginx..."
   sleep 10
done

ایک اور انتہائی مفید نمونہ مخصوص ایپلی کیشنز کے آغاز کو سنبھالنے کے لیے init کنٹینرز کا استعمال ہے۔ یہ خاص طور پر مفید ہے اگر آپ کے پاس وسائل کے لحاظ سے ڈیٹا بیس کی منتقلی کا عمل ہے جسے ایپلیکیشن شروع ہونے سے پہلے چلایا جانا چاہیے۔ آپ مرکزی درخواست کے لیے اس طرح کی کوئی حد متعین کیے بغیر اس عمل کے لیے وسائل کی ایک اعلیٰ حد بھی متعین کر سکتے ہیں۔

ایک اور عام اسکیم init کنٹینر میں رازوں تک رسائی حاصل کرنا ہے، جو یہ اسناد مرکزی ماڈیول کو فراہم کرتا ہے، جو خود مین ایپلیکیشن ماڈیول کے رازوں تک غیر مجاز رسائی کو روکتا ہے۔

ہمیشہ کی طرح، دستاویزات سے ایک اقتباس: init کنٹینرز محفوظ طریقے سے یوزر کوڈ یا یوٹیلیٹیز چلاتے ہیں جو بصورت دیگر ایپلیکیشن کے کنٹینر امیج کی سیکیورٹی سے سمجھوتہ کریں گے۔ غیر ضروری ٹولز کو الگ رکھ کر، آپ ایپلی کیشن کے کنٹینر امیج کے حملے کی سطح کو محدود کرتے ہیں۔

پانچواں مرحلہ: کرنل کنفیگریشن

آخر میں، آئیے ایک زیادہ جدید تکنیک کے بارے میں بات کرتے ہیں۔

Kubernetes ایک انتہائی لچکدار پلیٹ فارم ہے جو آپ کو کام کا بوجھ چلانے کی اجازت دیتا ہے تاہم آپ کو مناسب نظر آتا ہے۔ ہمارے پاس متعدد انتہائی موثر ایپلی کیشنز ہیں جو انتہائی وسائل کے حامل ہیں۔ وسیع پیمانے پر لوڈ ٹیسٹنگ کرنے کے بعد، ہم نے پایا کہ جب ڈیفالٹ Kubernetes سیٹنگز نافذ ہو رہی تھیں تو ایک ایپلیکیشن کو متوقع ٹریفک بوجھ کو برقرار رکھنے میں مشکل پیش آ رہی تھی۔

تاہم، Kubernetes آپ کو ایک مراعات یافتہ کنٹینر چلانے کی اجازت دیتا ہے جو صرف ایک مخصوص پوڈ کے لیے کرنل کے پیرامیٹرز کو تبدیل کرتا ہے۔ کھلے رابطوں کی زیادہ سے زیادہ تعداد کو تبدیل کرنے کے لیے ہم کیا استعمال کرتے تھے:

initContainers:
  - name: sysctl
     image: alpine:3.10
     securityContext:
         privileged: true
      command: ['sh', '-c', "sysctl -w net.core.somaxconn=32768"]

یہ ایک زیادہ جدید تکنیک ہے جس کی اکثر ضرورت نہیں ہوتی ہے۔ لیکن اگر آپ کی ایپلیکیشن بھاری بوجھ سے نمٹنے کے لیے جدوجہد کر رہی ہے، تو آپ ان میں سے کچھ سیٹنگز کو ٹوئیک کرنے کی کوشش کر سکتے ہیں۔ اس عمل کے بارے میں مزید معلومات اور مختلف اقدار کی ترتیب - ہمیشہ کی طرح سرکاری دستاویزات میں.

آخر میں

اگرچہ Kubernetes ایک آؤٹ آف دی باکس حل کی طرح لگتا ہے، لیکن ایپلیکیشنز کو آسانی سے چلانے کے لیے چند اہم اقدامات کیے جانے چاہییں۔

Kubernetes میں منتقلی کے دوران، "لوڈ ٹیسٹنگ سائیکل" کی پیروی کرنا ضروری ہے: ایپلیکیشن کو چلائیں، اسے بوجھ کے نیچے ٹیسٹ کریں، میٹرکس اور اسکیلنگ کے رویے کا مشاہدہ کریں، اس ڈیٹا کی بنیاد پر کنفیگریشن کو ایڈجسٹ کریں، پھر اس سائیکل کو دوبارہ دہرائیں۔

متوقع ٹریفک کے بارے میں حقیقت پسند بنیں اور اس سے آگے بڑھ کر یہ دیکھنے کی کوشش کریں کہ کون سے اجزاء پہلے ٹوٹتے ہیں۔ اس تکراری نقطہ نظر کے ساتھ، درج کردہ سفارشات میں سے صرف چند ہی کامیابی حاصل کرنے کے لیے کافی ہو سکتی ہیں۔ یا اس کے لیے مزید گہرائی سے حسب ضرورت ضرورت پڑ سکتی ہے۔

ہمیشہ اپنے آپ سے یہ سوالات پوچھیں:

  1. ایپلیکیشنز کتنے وسائل استعمال کرتی ہیں اور یہ رقم کیسے بدلے گی؟
  2. اصل پیمانے کی ضروریات کیا ہیں؟ ایپ اوسطاً کتنی ٹریفک کو سنبھالے گی؟ چوٹی ٹریفک کے بارے میں کیا خیال ہے؟
  3. سروس کو کتنی بار ختم کرنے کی ضرورت ہوگی؟ ٹریفک حاصل کرنے کے لیے نئی پوڈز کو کتنی جلدی تیار ہونے اور چلانے کی ضرورت ہے؟
  4. پوڈز کو کتنی خوبصورتی سے بند کیا جاتا ہے؟ کیا یہ بالکل ضروری ہے؟ کیا ڈاؤن ٹائم کے بغیر تعیناتی حاصل کرنا ممکن ہے؟
  5. حفاظتی خطرات کو کیسے کم کیا جائے اور کسی بھی سمجھوتہ شدہ پوڈ سے ہونے والے نقصان کو کیسے محدود کیا جائے؟ کیا کسی بھی خدمات کے پاس اجازت یا رسائی ہے جس کی انہیں ضرورت نہیں ہے؟

Kubernetes ایک ناقابل یقین پلیٹ فارم فراہم کرتا ہے جو آپ کو ایک کلسٹر میں ہزاروں خدمات کو تعینات کرنے کے لیے بہترین طریقوں کو استعمال کرنے کی اجازت دیتا ہے۔ تاہم، تمام ایپلی کیشنز مختلف ہیں. بعض اوقات عمل درآمد میں تھوڑا اور کام کی ضرورت ہوتی ہے۔

خوش قسمتی سے، Kubernetes تمام تکنیکی اہداف کو حاصل کرنے کے لیے ضروری ترتیبات فراہم کرتا ہے۔ وسائل کی درخواستوں اور حدود، لائیونس اور ریڈی نیس پروبس، انیٹ کنٹینرز، نیٹ ورک کی پالیسیوں، اور کسٹم کرنل ٹیوننگ کے امتزاج کا استعمال کرتے ہوئے، آپ فالٹ ٹولرنس اور تیز رفتار اسکیل ایبلٹی کے ساتھ اعلیٰ کارکردگی حاصل کر سکتے ہیں۔

اور کیا پڑھنا ہے:

  1. پیداواری ماحول میں کنٹینرز اور کبرنیٹس کو چلانے کے لیے بہترین طرز عمل اور بہترین طریقہ کار.
  2. Kubernetes کے لیے 90+ مفید ٹولز: تعیناتی، انتظام، نگرانی، حفاظت اور مزید.
  3. ٹیلیگرام میں ہمارا چینل Around Kubernetes.

ماخذ: www.habr.com

نیا تبصرہ شامل کریں