Container, Kubernetes ও CI/CD

আধুনিক deploy কীভাবে হয়

রোডম্যাপের মাস ৯পড়তে প্রায় ৯ মিনিট

তুমি Docker দিয়ে app কে container এ ভরেছো, আর CI/CD দিয়ে deploy করেছো। বড় system এ শত শত container চালাতে হয়, কয়েকটা machine জুড়ে, আর কেউ নষ্ট হলে নিজে থেকে আবার চালু, চাপ বাড়লে নিজে থেকে বাড়ানো। এই কাজটা করে container orchestrator, যার মধ্যে সবচেয়ে প্রচলিত Kubernetes। এই অধ্যায়ে এর মূল ধারণা, আর আধুনিক deploy এর কৌশলগুলো। লক্ষ্য Kubernetes এর বিশেষজ্ঞ হওয়া না, বরং কথাবার্তা বোঝা আর কখন এটা লাগে সেটা জানা।

#Kubernetes কী সমস্যা সমাধান করে

তুমি বলো কী চাও ("order-api এর ৪টা copy সবসময় চালু থাকুক, প্রতিটা ৫০০MB memory"), Kubernetes নিজেই ঠিক করে কীভাবে (কোন machine এ, নষ্ট হলে কোথায় আবার)। একে বলে declarative ব্যবস্থা।

Control plane API server Scheduler (কোথায় চালাবে) Controller (কাঙ্ক্ষিত অবস্থা বজায় রাখে) etcd (সব অবস্থার রেকর্ড) Worker node (machine) গুলো Node ১ pod: order-api pod: order-api pod: worker Node ২ pod: order-api pod: menu-api Node ৩ ✗ নষ্ট হলে এর pod অন্য node এ নিজে থেকে চালু
তুমি কাঙ্ক্ষিত অবস্থা বলে দাও, control plane সারাক্ষণ বাস্তব অবস্থা মিলিয়ে দেখে আর পার্থক্য ঠিক করে।

#মূল ধারণা

ধারণা মানে
Pod সবচেয়ে ছোট একক: এক বা একাধিক container একসাথে (সাধারণত একটা)
Deployment "এই image এর N টা pod চালু রাখো", rolling update সামলায়
Service Pod গুলোর সামনে স্থির ঠিকানা আর ভেতরের load balancing (pod মরে-জন্মায়, IP বদলায়)
Ingress / Gateway বাইরের HTTP traffic কোন service এ যাবে
ConfigMap / Secret Configuration আর গোপন তথ্য, environment variable বা file হিসেবে
HPA CPU/request অনুযায়ী pod এর সংখ্যা স্বয়ংক্রিয়ভাবে বাড়ানো-কমানো
Probe Liveness/readiness check (Load Balancer অধ্যায়)
Namespace একই cluster এ আলাদা ভাগ (staging, production, team অনুযায়ী)
Job / CronJob একবারের কাজ (migration) বা নির্দিষ্ট সময়ের কাজ
YAML
# deployment.yaml (সংক্ষেপে)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-api
spec:
  replicas: 4
  selector:
    matchLabels: {app: order-api}
  template:
    metadata:
      labels: {app: order-api}
    spec:
      containers:
        - name: api
          image: ghcr.io/you/order-api:1.8.3
          ports: [{containerPort: 8000}]
          envFrom: [{secretRef: {name: order-api-secrets}}]
          resources:
            requests: {cpu: "250m", memory: "256Mi"}
            limits: {memory: "512Mi"}
          readinessProbe:
            httpGet: {path: /health/ready, port: 8000}
          livenessProbe:
            httpGet: {path: /health/live, port: 8000}

#Kubernetes কি তোমার লাগবে?

#Deploy এর কৌশল

কৌশল কীভাবে সুবিধা অসুবিধা
Recreate সব পুরনো বন্ধ, তারপর নতুন চালু সহজ কিছুক্ষণ বন্ধ
Rolling একটা একটা করে পুরনো বদলে নতুন বন্ধ হয় না; Kubernetes এর default কিছুক্ষণ দুই version একসাথে চলে
Blue-green পুরো নতুন সেট পাশে চালু, তারপর traffic এক ধাপে সরানো সাথে সাথে ফেরা যায় দ্বিগুণ resource
Canary নতুন version এ প্রথমে ৫% traffic, metric ঠিক থাকলে ধীরে ধীরে বাড়ানো সমস্যা অল্প user এ ধরা পড়ে Monitoring আর routing লাগে
Load balancer v1.8.3 (পুরনো) ৯৫% traffic v1.9.0 (নতুন) ৫% traffic error/latency ঠিক থাকলে ২৫% → ৫০% → ১০০% খারাপ হলে সাথে সাথে ০%
Canary তে নতুন version এর bug মাত্র অল্প কিছু user দেখে, আর metric দেখে স্বয়ংক্রিয়ভাবে ফেরানো যায়।

#Rolling deploy এ database migration

কিছুক্ষণ পুরনো আর নতুন code একসাথে চলে, দুজনেই একই database ব্যবহার করে। তাই migration কে backward compatible হতে হয় (expand-contract):

  1. Expand: নতুন column/table যোগ (পুরনো code এতে বিরক্ত হয় না)
  2. নতুন code deploy, যেটা দুই জায়গাতেই লেখে
  3. পুরনো data নতুন জায়গায় copy
  4. নতুন code শুধু নতুন জায়গা থেকে পড়ে
  5. Contract: পরের release এ পুরনো column মোছা

একবারে column এর নাম বদলালে rolling deploy এর মাঝখানে পুরনো code ভেঙে পড়বে।

#Feature flag

Code deploy আর feature চালু করা আলাদা করো: নতুন feature code এ থাকে কিন্তু flag বন্ধ; পরে admin panel থেকে প্রথমে নিজের team, তারপর ১০% user, তারপর সবার জন্য চালু। সমস্যা হলে flag বন্ধ, deploy ফেরানো লাগে না।

#Infrastructure as Code

Server, database, network, DNS হাতে cloud console এ click করে বানালে কেউ জানে না কী কীভাবে বানানো, আর আবার বানানো প্রায় অসম্ভব। IaC এ সব কিছু code এ লেখা (Terraform/OpenTofu, Pulumi), Git এ থাকে, review হয়, আর একই code দিয়ে staging আর production হুবহু বানানো যায়।

hcl
# Terraform উদাহরণ (সংক্ষেপে)
resource "aws_db_instance" "orders" {
  engine              = "postgres"
  instance_class      = "db.t4g.medium"
  allocated_storage   = 100
  multi_az            = true                 # অন্য zone এ standby
  backup_retention_period = 14
  publicly_accessible = false
}

#GitOps

Cluster এর কাঙ্ক্ষিত অবস্থা একটা Git repo তে; Argo CD বা Flux এর মতো tool সারাক্ষণ cluster কে সেই repo এর সাথে মেলায়। Deploy মানে একটা PR merge; ফেরানো মানে revert। কে কখন কী বদলালো, Git এর ইতিহাসে সব লেখা।

#অনুশীলন

#নিজেকে যাচাই করো

Kubernetes এর "declarative" ব্যবস্থা মানে কী?

তুমি কাঙ্ক্ষিত অবস্থা বলো (কয়টা copy, কোন image, কত resource), কীভাবে সেটা হবে তা Kubernetes ঠিক করে, আর সারাক্ষণ বাস্তব অবস্থা মিলিয়ে পার্থক্য ঠিক করে (pod মরলে আবার চালায়)।

Canary deploy এর মূল সুবিধা কী?

নতুন version প্রথমে অল্প user এর traffic পায়, তাই bug থাকলে অল্প ক্ষতিতে ধরা পড়ে, আর metric খারাপ হলে সাথে সাথে বা স্বয়ংক্রিয়ভাবে ফেরানো যায়।

Rolling deploy এ column এর নাম সরাসরি বদলানো কেন বিপজ্জনক?

Deploy এর সময় পুরনো আর নতুন code একসাথে চলে। নাম বদলানোর পর পুরনো code পুরনো নাম খুঁজে না পেয়ে ভেঙে পড়বে। Expand-contract পদ্ধতিতে ধাপে ধাপে বদলাতে হয়।

ছোট team এর জন্য Kubernetes কেন প্রায়ই প্রথম পছন্দ না?

এটা শেখা, চালানো, security আর upgrade এর বড় বোঝা আনে। PaaS বা managed container service একই মূল লাভ (container চালানো, scale, health check) অনেক কম ঝামেলায় দেয়।

চিহ্ন দিলে sidebar আর রোডম্যাপে এই অধ্যায়ের station ভরে যাবে।