পাঠ ৫৬ · ৫৭-এর মধ্যে · মডিউল ১৩
Home / Courses / Cloud Computing & DevOps / কেস স্টাডি: K8s মাইক্রোসার্ভিস

কেস স্টাডি: Kubernetes-এ একটি মাইক্রোসার্ভিস ডিপ্লয় করা

Case study: deploying a microservice on Kubernetes
১০ মিনিট পড়া উন্নত · Advanced কেস স্টাডি Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • একটি বাস্তব মাইক্রোসার্ভিস ডিপ্লয়মেন্টে M7-এর প্রতিটি লেসনের টুকরো কোথায় বসে
  • একটি Helm চার্ট কীভাবে একই ম্যানিফেস্ট টেমপ্লেট বিভিন্ন এনভায়রনমেন্টে ভিন্নভাবে রেন্ডার করে
  • Deployment+Service+ConfigMap একসাথে একটি সমন্বিত "ম্যানিফেস্ট" তৈরি করে কীভাবে
  • একটি পড ক্র্যাশের পর কন্ট্রোল প্লেন কীভাবে স্বয়ংক্রিয়ভাবে সেলফ-হিল করে

১ · কনটেক্সট — সমস্যা

একটি নতুন "অর্ডারস API" মাইক্রোসার্ভিস প্রস্তুত — এখন এটিকে Kubernetes-এ প্রোডাকশন-রেডি উপায়ে ডিপ্লয় করতে হবে, যাতে এটি স্বাধীনভাবে স্কেল করতে পারে, নিরাপদে কনফিগারেশন/সিক্রেট পেতে পারে, বাইরে থেকে বা ক্লাস্টারের ভেতর থেকে নির্ভরযোগ্যভাবে অ্যাক্সেসযোগ্য থাকতে পারে, এবং কোনো পড ক্র্যাশ করলে নিজে থেকেই সুস্থ হয়ে উঠতে পারে।

২ · অ্যাপ্রোচ — M7-এর প্রতিটি টুকরো একত্র করা

প্রথমে একটি multi-stage Dockerfile (M6/L23, L25) দিয়ে ইমেজ বিল্ড করা হয় — বিল্ড টুল বাদ দিয়ে শুধু রানটাইম আর্টিফ্যাক্ট চূড়ান্ত ইমেজে থাকে (ছোট, কম অ্যাটাক-সারফেস)। একটি Deployment (M7/L28) নির্দিষ্ট রেপ্লিকা কাউন্ট নিয়ে সংজ্ঞায়িত হয়, একটি Service (M7/L29) দিয়ে ক্লাস্টারের ভেতরে স্থিতিশীল অ্যাক্সেস দেওয়া হয়, আর প্রয়োজনে একটি Ingress বাইরের HTTP অ্যাক্সেস সামলায়। কনফিগারেশন (লগ লেভেল, ফিচার ফ্ল্যাগ) ConfigMap-এ, ও সংবেদনশীল ডেটা (ডেটাবেস পাসওয়ার্ড) Secret-এ ইনজেক্ট করা হয় (M7/L30)। পুরো ম্যানিফেস্ট সেট একটি প্যারামিটারাইজড Helm চার্ট হিসেবে প্যাকেজ করা হয় (M7/L31), যাতে dev-এ কম রেপ্লিকা আর production-এ বেশি রেপ্লিকা নিয়ে একই চার্ট চালানো যায়। সবশেষে, কন্ট্রোল প্লেনের রিকনসিলিয়েশন লুপ (M7/L27) ক্রমাগত পর্যবেক্ষণ করে ডিজায়ার্ড রেপ্লিকা কাউন্ট বজায় আছে কিনা, এবং না থাকলে নিজে থেকেই ঠিক করে।

Helm চার্ট (L31) values.yaml সহ Deployment L28 Service L29 ConfigMap/Secret L30 চলমান পড (রিকনসাইল্ড, L27) Self-healing Running Pods
একটি Helm চার্ট রেন্ডার হয়ে তিনটি রিসোর্স তৈরি করে, যা একসাথে সেলফ-হিলিং পড চালায়।

৩ · মূল সিদ্ধান্ত

রেপ্লিকা কাউন্ট ও এক্সপোজার সিদ্ধান্ত

production-এর জন্য রেপ্লিকা কাউন্ট শুধু "যথেষ্ট মনে হওয়া" সংখ্যা নয় — এটি প্রত্যাশিত ট্রাফিক ও সিঙ্গেল-পড ক্যাপাসিটির উপর ভিত্তি করে ঠিক করা উচিত (L50-এর রাইট-সাইজিং নীতির প্রতিধ্বনি), এবং dev-এ কম রেপ্লিকা রেখে খরচ বাঁচানো যায় যেহেতু সেখানে হাই-এভেইলেবিলিটির প্রয়োজন নেই। এক্সপোজারের ক্ষেত্রে — শুধু যে সার্ভিস সত্যিই বাইরের ক্লায়েন্টদের প্রয়োজন তা Ingress দিয়ে এক্সপোজ করা হয়, বাকি অভ্যন্তরীণ সার্ভিস ClusterIP-তে সীমাবদ্ধ রাখা হয় (L16-এর least-privilege নীতির নেটওয়ার্কিং প্রয়োগ)।

৪ · কোড — সমন্বিত ম্যানিফেস্ট + রিকনসিলিয়েশন

নিচের কোডে একটি Helm-এর মতো টেমপ্লেট রেন্ডারিং ফাংশন Deployment+Service+ConfigMap একসাথে একটি সমন্বিত ম্যানিফেস্টে তৈরি করে, তারপর একটি সিমুলেটেড পড ক্র্যাশের পর রিকনসিলিয়েশন ফাংশন (L27/L28-এর প্যাটার্ন) স্বয়ংক্রিয়ভাবে ডিজায়ার্ড রেপ্লিকা কাউন্ট পুনরুদ্ধার করে।

Python
# একটি Helm-এর মতো টেমপ্লেট রেন্ডারার — একই "চার্ট" ভিন্ন values দিয়ে ভিন্ন ম্যানিফেস্ট তৈরি করে
def render_manifest(values):
    return {
        "deployment": {
            "name": values["name"],
            "replicas": values["replicas"],
            "image": values["image"],
        },
        "service": {
            "name": f"{values['name']}-svc",
            "selector": {"app": values["name"]},
        },
        "configmap": {
            "name": f"{values['name']}-config",
            "data": values["config"],
        },
    }

dev_values = {
    "name": "orders-api", "replicas": 1,
    "image": "orders-api:1.4.0", "config": {"LOG_LEVEL": "debug"},
}
prod_values = {
    "name": "orders-api", "replicas": 4,
    "image": "orders-api:1.4.0", "config": {"LOG_LEVEL": "info"},
}

for env_name, values in [("dev", dev_values), ("production", prod_values)]:
    manifest = render_manifest(values)
    print(f"=== {env_name} ম্যানিফেস্ট ===")
    for resource, spec in manifest.items():
        print(f"  {resource:12}: {spec}")
    print()

# --- রিকনসিলিয়েশন (L27/L28-এর প্যাটার্ন) ---
desired_replicas = prod_values["replicas"]
actual_running_pods = [f"pod-{i+1}" for i in range(desired_replicas)]

def simulate_pod_crash(pods, crashed_pod):
    return [p for p in pods if p != crashed_pod]

def reconcile(desired, actual):
    diff = desired - len(actual)
    if diff > 0:
        new_pods = [f"pod-{len(actual)+i+1}-new" for i in range(diff)]
        return actual + new_pods, f"{diff}টি নতুন পড তৈরি করা হলো (সেলফ-হিলিং)"
    if diff < 0:
        return actual[:desired], f"{-diff}টি অতিরিক্ত পড বন্ধ করা হলো"
    return actual, "কোনো পরিবর্তন দরকার নেই — ইতিমধ্যে ডিজায়ার্ড স্টেটে"

print(f"প্রোডাকশন ডিজায়ার্ড রেপ্লিকা: {desired_replicas}")
print(f"ক্র্যাশের আগে চলমান পড:      {actual_running_pods}")

actual_running_pods = simulate_pod_crash(actual_running_pods, "pod-2")
print(f"\n'pod-2' ক্র্যাশের পর:       {actual_running_pods}")

reconciled_pods, action = reconcile(desired_replicas, actual_running_pods)
print(f"রিকনসিলিয়েশন অ্যাকশন:       {action}")
print(f"রিকনসিলিয়েশনের পর:         {reconciled_pods}")

    
লক্ষ্য করুন dev ও production ম্যানিফেস্ট একই টেমপ্লেট ফাংশন থেকে এসেছে — শুধু values পাল্টে ভিন্ন রেপ্লিকা কাউন্ট পাওয়া গেছে (L31-এর Helm নীতি হুবহু)। আর "pod-2" ক্র্যাশের পর, রিকনসিলিয়েশন ফাংশন স্বয়ংক্রিয়ভাবে একটি নতুন পড তৈরি করে ৪-এর ডিজায়ার্ড কাউন্ট পুনরুদ্ধার করেছে — কোনো মানুষ হস্তক্ষেপ ছাড়াই।

৫ · ফলাফল

"অর্ডারস API" এখন dev ও production উভয় এনভায়রনমেন্টে একই, প্রমাণিত Helm চার্ট দিয়ে ধারাবাহিকভাবে ডিপ্লয়যোগ্য, কনফিগারেশন ও সিক্রেট নিরাপদে বাইরে থেকে ইনজেক্ট হয় (কোনো ইমেজ রিবিল্ড ছাড়াই), এবং যেকোনো পড ক্র্যাশ থেকে সেকেন্ডের মধ্যে স্বয়ংক্রিয়ভাবে সুস্থ হয়ে ওঠে — একটি সম্পূর্ণ, প্রোডাকশন-রেডি মাইক্রোসার্ভিস ডিপ্লয়মেন্ট।

মূল কথা · Key takeaway

একটি "সম্পূর্ণ Kubernetes ডিপ্লয়মেন্ট" আসলে M7-এর প্রতিটি আলাদা লেসনে শেখা টুকরোর (Deployment, Service, ConfigMap, Helm, রিকনসিলিয়েশন) একটি সুসংগঠিত সমাবেশ মাত্র — প্রতিটি টুকরো আলাদাভাবে সহজ, একত্রে শক্তিশালী।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ কেন dev ও production একই Docker ইমেজ ট্যাগ (orders-api:1.4.0) ব্যবহার করছে, কিন্তু ভিন্ন LOG_LEVEL?

এটিই L19/L30-এর এক্সটার্নালাইজেশন নীতির মূল সুবিধা — একই, একবার-বিল্ড-করা, টেস্ট-করা ইমেজ প্রতিটি এনভায়রনমেন্টে চলে (dev-এ যা পরীক্ষা হয়েছে তা-ই production-এ যায়, ফলে "works on dev but not prod" সমস্যা কমে), অথচ কনফিগারেশন (এখানে লগ ভার্বোসিটি) ConfigMap দিয়ে আলাদাভাবে ইনজেক্ট করা হয় — ইমেজ রিবিল্ড না করেই।

প্র ০২ যদি রিকনসিলিয়েশন লুপ (L27) না থাকত, "pod-2" ক্র্যাশের প্রভাব কী হতো?

ক্র্যাশ হওয়া পডটি প্রতিস্থাপিত না হয়েই থেকে যেত — সার্ভিসের ক্যাপাসিটি স্থায়ীভাবে কমে যেত (৪-এর বদলে ৩ পড চলত), এবং যতক্ষণ না কেউ ম্যানুয়ালি লক্ষ্য করে নতুন পড তৈরি করত, ততক্ষণ সিস্টেম কমক্ষমতায় চলতে থাকত। রিকনসিলিয়েশন লুপই Kubernetes-কে "সেলফ-হিলিং" করে তোলে, এটি বাদ দিলে সেই মৌলিক গ্যারান্টিটাই হারিয়ে যায়।

প্র ০৩ এই মাইক্রোসার্ভিসের production রেপ্লিকা কাউন্ট (৪) কীভাবে যুক্তিসঙ্গতভাবে ঠিক করা উচিত, নিছক অনুমান নয়?

L50-এর রাইট-সাইজিং নীতি অনুযায়ী — প্রত্যাশিত সর্বোচ্চ ট্রাফিক, প্রতিটি পড কত রিকোয়েস্ট/সেকেন্ড নিরাপদে সামলাতে পারে (লোড টেস্টিং দিয়ে পরিমাপ করা), এবং একটি পড ক্র্যাশ/আপডেটের সময়ও যথেষ্ট ক্যাপাসিটি বজায় রাখার জন্য একটি মার্জিন যোগ করে — নিছক "৪ ভালো একটা সংখ্যা মনে হচ্ছে" ধরনের অনুমান নয়।

অনুশীলন

  1. পরীক্ষা করুন: উপরের কোডে simulate_pod_crash দুইবার কল করে "pod-1" ও "pod-3" দুটোই ক্র্যাশ করান, তারপর রিকনসিলিয়েশন চালিয়ে দেখুন।

    দুইটি পড ক্র্যাশের পর মাত্র ২টি চলমান পড থাকবে, আর reconcile() শনাক্ত করবে ডিজায়ার্ড (৪) ও বর্তমান (২)-এর মধ্যে পার্থক্য ২, এবং ২টি নতুন পড তৈরির অ্যাকশন রিপোর্ট করবে — দেখাচ্ছে রিকনসিলিয়েশন যেকোনো সংখ্যক একযোগে ক্র্যাশ থেকেই সঠিকভাবে পুনরুদ্ধার করে।

  2. চিন্তা করুন: কেন render_manifest()-এর মতো একটি ফাংশন সরাসরি প্রতিটি এনভায়রনমেন্টের জন্য আলাদা, হাতে-লেখা YAML ফাইলের চেয়ে ভালো?

    একটি একক টেমপ্লেট ফাংশন নিশ্চিত করে সব এনভায়রনমেন্ট একই কাঠামো অনুসরণ করে — কোনো এনভায়রনমেন্টে ভুলবশত একটি ফিল্ড বাদ পড়া বা টাইপো হওয়ার সুযোগ কমে যায়। একটি বাগ ঠিক করতে বা নতুন ফিল্ড যোগ করতে একবারই টেমপ্লেট পাল্টাতে হয়, প্রতিটি এনভায়রনমেন্টের আলাদা ফাইল খুঁজে বের করে সমন্বয় করার দরকার হয় না — ঠিক L19-এর Terraform মডিউলের মতোই সুবিধা।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
কেস স্টাডি: মাল্টি-ক্লাউড ডিজাস্টার রিকভারি স্ট্র্যাটেজি