Kubernetes ورک لوڈز کے لیے پروڈکشن بیس لائن
ریکویسٹس، پروبز، ڈسرپشن بجٹ، منظم شٹ ڈاؤن اور پوڈ سیکیورٹی: وہ ترتیبات جو پروڈکشن Deployment میں پہلے انسیڈنٹ سے پہلے ہونی چاہییں۔
مثالیں عمومی اور وضاحتی ہیں۔ یہ کسی کلائنٹ کے ماحول سے نہیں لی گئیں: حدود اور ترتیبات کو اپنے نظام کے مطابق ڈھالیں۔
بیس لائن کیوں
Kubernetes تقریباً بغیر کنفیگریشن کے تقریباً کچھ بھی چلا دیتا ہے، اور یہی مسئلہ ہے: ڈیفالٹس شروع کرنے کے لیے چنے گئے ہیں، چلتے رہنے کے لیے نہیں۔ نیچے کی ترتیبات پہلے دن شامل کرنا سستا ہے اور خرابی کے دوران دریافت کرنا مہنگا۔ یہ اسٹیٹ لیس Deployment پر لاگو ہوتی ہیں؛ اسٹیٹ فل ورک لوڈز کو مزید چاہیے۔
ریکویسٹس اور لمٹس
شیڈولر پوڈز کو ان کی requests کے مطابق رکھتا ہے، اور Horizontal Pod Autoscaler انہی کے مقابلے میں استعمال ناپتا ہے۔ requests کے بغیر پوڈ اندھا دھند رکھا جاتا ہے اور CPU کی بنیاد پر آٹو اسکیل نہیں ہو سکتا۔
میموری کو دبایا نہیں جا سکتا: جو کنٹینر اپنی میموری لمٹ سے بڑھے اسے ختم کر دیا جاتا ہے۔ میموری لمٹ کو request کے برابر یا قریب رکھیں، تاکہ پوڈ کبھی ایسی میموری پر شیڈول نہ ہو جسے وہ رکھ نہ سکے۔ CPU مختلف ہے — CPU لمٹ سے اوپر کنٹینر تھروٹل ہوتا ہے، جو تاخیر کی صورت میں ظاہر ہوتا ہے۔ کئی ٹیمیں تاخیر کے لحاظ سے حساس سروسز کے لیے CPU requests رکھتی ہیں اور CPU لمٹ ہٹا دیتی ہیں؛ آپ جو بھی چنیں، تھروٹلنگ ناپیں۔
تین پروبز، تین کام
- Readiness طے کرتا ہے کہ پوڈ کو ٹریفک ملے یا نہیں۔ مشترکہ انحصارات سے محتاط رہیں: اگر سب پوڈز ایک ساتھ readiness میں ناکام ہوں تو سروس کے پاس کوئی اینڈ پوائنٹ نہیں بچتا۔
- Liveness طے کرتا ہے کہ کنٹینر دوبارہ شروع ہو یا نہیں۔ اسے صرف پروسیس تک محدود رکھیں: اگر یہ ڈیٹا بیس چیک کرتا ہے تو ڈیٹا بیس کی خرابی سب پوڈز کو ایک ساتھ دوبارہ شروع کر دے گی۔
- Startup سست ایپ کے شروع ہونے تک باقی پروبز کو روکے رکھتا ہے، بجائے اس کے کہ liveness کی تاخیر بڑھائی جائے۔
نوڈ ڈرین اور زون کی ناکامی سے بچاؤ
نوڈ اپ گریڈ اور آٹو اسکیلنگ مسلسل پوڈز کو ہٹاتے رہتے ہیں۔ PodDisruptionBudget یہ محدود کرتا ہے کہ ایک رضاکارانہ رکاوٹ بیک وقت کتنی ریپلیکاز بند کر سکتی ہے، اور topology spread constraints ریپلیکاز کو مختلف زونز میں رکھتے ہیں، تاکہ ایک زون کی ناکامی پوری سروس کو نہ لے ڈوبے۔
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api
spec:
maxUnavailable: 1
selector:
matchLabels: { app: api }
منظم شٹ ڈاؤن
جب کوئی پوڈ حذف کیا جاتا ہے تو سروس اینڈ پوائنٹس سے اس کا ہٹنا اور اس کے کنٹینرز کا بند ہونا (پہلے preStop ہک، پھر SIGTERM) ایک ساتھ شروع ہوتے ہیں۔ جو ایپ فوراً بند ہو جائے وہ ان درخواستوں کو کھو دیتی ہے جو ابھی تک اس کی طرف بھیجی جا رہی ہیں۔ لوڈ بیلنسرز کو اپ ڈیٹ ہونے دینے کے لیے مختصر preStop وقفہ شامل کریں، SIGTERM ملنے پر جاری کام مکمل کریں، اور terminationGracePeriodSeconds کو وقفے اور ڈرین کے مجموعی وقت سے زیادہ رکھیں۔
سیکیورٹی کانٹیکسٹ اور امیجز
نان روٹ صارف کے طور پر چلائیں، تمام Linux capabilities ہٹائیں، اختیارات میں اضافہ روکیں اور روٹ فائل سسٹم کو صرف پڑھنے کے لیے ماؤنٹ کریں؛ restricted Pod Security Standard ان میں سے زیادہ تر کو نیم اسپیس کی سطح پر نافذ کرتا ہے۔ امیجز کا حوالہ بدلنے والے ٹیگ کے بجائے ڈائجسٹ سے دیں، تاکہ جو آزمایا گیا بالکل وہی چلے۔
سب کچھ ایک ساتھ
بیس لائن لاگو کیا ہوا ایک Deployment۔ اقدار محض مثال ہیں: requests اس مثال سے نہیں، ناپے گئے استعمال سے طے کریں۔
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
selector:
matchLabels: { app: api }
template:
metadata:
labels: { app: api }
spec:
terminationGracePeriodSeconds: 45
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels: { app: api }
securityContext:
runAsNonRoot: true
seccompProfile: { type: RuntimeDefault }
containers:
- name: api
image: registry.example.com/api@sha256:<digest>
resources:
requests: { cpu: 250m, memory: 256Mi }
limits: { memory: 256Mi }
readinessProbe:
httpGet: { path: /ready, port: 8080 }
periodSeconds: 5
livenessProbe:
httpGet: { path: /live, port: 8080 }
periodSeconds: 10
failureThreshold: 3
startupProbe:
httpGet: { path: /live, port: 8080 }
periodSeconds: 5
failureThreshold: 30
lifecycle:
preStop:
sleep: { seconds: 5 } # native sleep action, Kubernetes 1.30+
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities: { drop: ["ALL"] }