পাঠ ৩০ · ৫৭-এর মধ্যে · মডিউল ৭
Home / Courses / Cloud Computing & DevOps / Secret ও Volume

ConfigMap, Secret ও Volume

ConfigMaps, Secrets & Volumes
৮ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

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

  • ConfigMap কীভাবে কনফিগারেশনকে ইমেজ থেকে আলাদা রাখে
  • Secret কেন ConfigMap থেকে আলাদা একটি অবজেক্ট, এবং base64 এনকোডিং কী সুরক্ষা দেয় (এবং দেয় না)
  • Volume কীভাবে পডকে ক্ষণস্থায়ী কন্টেইনারের বাইরেও স্থায়ী স্টোরেজ দেয়
  • একই পড টেমপ্লেট থেকে dev ও production-এ ভিন্ন কার্যকর কনফিগারেশন তৈরি করা — একটি Python সিমুলেশনে

১ · ConfigMap — কনফিগারেশনকে ইমেজ থেকে আলাদা রাখা

ConfigMapConfigMapঅ-সংবেদনশীল কনফিগারেশন ডেটা (key-value জোড়া) সংরক্ষণকারী একটি Kubernetes অবজেক্ট, যা পডে environment variable বা ফাইল হিসেবে ইনজেক্ট করা যায় — কন্টেইনার ইমেজ পুনর্নির্মাণ ছাড়াই। অ-সংবেদনশীল কনফিগারেশন (যেমন একটি ফিচার-ফ্ল্যাগের মান, একটি API endpoint URL) কন্টেইনার ইমেজ থেকে বাইরে রাখে। এটি সরাসরি L19-এর Terraform মডিউল-প্যারামিটার করার লক্ষ্যেরই একটি Kubernetes-স্তরের প্রয়োগ — একই ইমেজ dev, staging ও production-এ ভিন্ন ভিন্ন ConfigMap মান নিয়ে চলতে পারে, প্রতিবার নতুন করে ইমেজ বিল্ড না করেই (L23/L25-এর ইমিউটেবল-ইমেজ দর্শনের সাথে সামঞ্জস্যপূর্ণ)।

২ · Secret — একই ধারণা, কিন্তু সংবেদনশীল ডেটার জন্য

SecretKubernetes SecretConfigMap-এর মতোই একটি অবজেক্ট, কিন্তু সংবেদনশীল ডেটার (পাসওয়ার্ড, API কী, সার্টিফিকেট) জন্য — base64-এনকোডেড, এবং RBAC-এর মাধ্যমে অ্যাক্সেস-নিয়ন্ত্রিত। একই idea ব্যবহার করে কিন্তু সংবেদনশীল ডেটার (পাসওয়ার্ড, API কী, সার্টিফিকেট) জন্য — অন্তত base64-এনকোডেড অবস্থায় সংরক্ষিত থাকে, আদর্শভাবে rest-এ এনক্রিপ্টেড এবং RBAC (ভূমিকা-ভিত্তিক অ্যাক্সেস নিয়ন্ত্রণ)-এর মাধ্যমে অ্যাক্সেস-নিয়ন্ত্রিত। এই ধারণা সরাসরি L40-এর সিক্রেট-ম্যানেজমেন্ট মডিউল ও cybersecurity কোর্সের encryption-at-rest ধারণার সাথে সম্পর্কিত।

সতর্কতা — base64 এনকোডিং এনক্রিপশন নয়

একটি সাধারণ ভুল ধারণা — base64 এনকোডিং একটি এনক্রিপশন নয়, শুধু একটি এনকোডিং ফরম্যাট। যে কেউ একটি base64-এনকোডেড মান দেখলে কয়েক সেকেন্ডেই তা ডিকোড করে আসল মান বের করতে পারে (কোনো "কী" ছাড়াই)। তাই Secret-এর প্রকৃত নিরাপত্তা আসে rest-এ এনক্রিপশন ও কে কোন Secret পড়তে পারে তার RBAC নিয়ন্ত্রণ থেকে — base64 শুধু ডেটাকে একটি নিরাপদ ফরম্যাটে স্টোর করার একটি প্রযুক্তিগত সুবিধা, নিরাপত্তার গ্যারান্টি নয়।

৩ · Volume — কন্টেইনারের বাইরে স্থায়ী স্টোরেজ

VolumeKubernetes Volumeএকটি পডকে স্থায়ী বা শেয়ার্ড স্টোরেজ প্রদান করে, যা পডের ভেতরে থাকা পৃথক কন্টেইনারের রিস্টার্টের মধ্যেও টিকে থাকে। পডকে স্থায়ী বা শেয়ার্ড স্টোরেজ দেয়, যা পডের জীবদ্দশায় পৃথক কন্টেইনার রিস্টার্ট হলেও টিকে থাকে — এটি L24-এর Docker volume ধারণার সরাসরি সম্প্রসারণ, এখন একক হোস্টের বদলে পুরো ক্লাস্টার-স্তরে প্রযোজ্য।

৪ · একই পড টেমপ্লেট, ভিন্ন কার্যকর কনফিগারেশন

নিচের সিমুলেশনে একই base_config (পরিবর্তনহীন) একটি environment-নির্দিষ্ট ConfigMap দিয়ে মার্জ করা হয়েছে — dev ও production, দুই ক্ষেত্রেই একই পড টেমপ্লেট ব্যবহৃত হয়, শুধু কার্যকর environment variable-এর মান আলাদা।

Python
# ConfigMap মান একটি পডের environment variable হিসেবে ইনজেক্ট করার সিমুলেশন
# (fake in-memory ডেটা — বাস্তব kubectl/cluster-এর বিরুদ্ধে চলছে না)

base_config = {
    "APP_NAME": "order-service",
    "LOG_LEVEL": "info",
}

configmap_dev = {
    "API_ENDPOINT": "https://dev-internal.example/api",
    "FEATURE_NEW_CHECKOUT": "true",
}

configmap_prod = {
    "API_ENDPOINT": "https://api.example/api",
    "FEATURE_NEW_CHECKOUT": "false",
}


def build_pod_env(base_config, configmap_values):
    """একই বেস কনফিগ + environment-নির্দিষ্ট ConfigMap মান মার্জ করে চূড়ান্ত env তৈরি করে।"""
    env = dict(base_config)
    env.update(configmap_values)
    return env


dev_env = build_pod_env(base_config, configmap_dev)
prod_env = build_pod_env(base_config, configmap_prod)

print("Dev পরিবেশে (একই ইমেজ, ভিন্ন ConfigMap):")
for key, value in dev_env.items():
    print(f"  {key}={value}")

print("\nProduction পরিবেশে (একই ইমেজ, ভিন্ন ConfigMap):")
for key, value in prod_env.items():
    print(f"  {key}={value}")

    
লক্ষ্য করুন — APP_NAME ও LOG_LEVEL দুই পরিবেশেই অভিন্ন থাকে (একই base_config থেকে আসে), কিন্তু API_ENDPOINT ও FEATURE_NEW_CHECKOUT পরিবেশ-নির্দিষ্ট ConfigMap থেকে আসে এবং ভিন্ন। বাস্তব Secret-এর জন্যও ঠিক এই একই প্যাটার্ন প্রযোজ্য, শুধু মানগুলো সংবেদনশীল বলে অতিরিক্ত সুরক্ষা স্তর (এনক্রিপশন, RBAC) যুক্ত হয়।
মূল কথা · Key takeaway

ConfigMap, Secret ও Volume তিনটিই একই মূল লক্ষ্যে কাজ করে — কন্টেইনার ইমেজকে "খাঁটি" (কনফিগারেশন/সংবেদনশীল ডেটা/স্টেট-মুক্ত) রাখা, যাতে একই ইমেজ যেকোনো পরিবেশে নির্ভরযোগ্যভাবে পুনর্ব্যবহারযোগ্য থাকে। পরবর্তী পাঠে আমরা দেখব কীভাবে Helm এই সব YAML ফাইল (Deployment, Service, ConfigMap, ইত্যাদি) একসাথে প্যাকেজ করে ব্যবস্থাপনা সহজ করে।

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

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

প্র ০১ ConfigMap ও Secret দুটোই তো key-value ডেটা সংরক্ষণ করে — তাহলে আলাদা দুটি অবজেক্ট কেন দরকার?

পৃথক অবজেক্ট থাকায় Kubernetes ও অপারেটররা সংবেদনশীল ও অ-সংবেদনশীল ডেটাকে আলাদাভাবে ব্যবহার করতে পারে — Secret-এর জন্য অতিরিক্ত সুরক্ষা ব্যবস্থা (RBAC-ভিত্তিক কড়া অ্যাক্সেস নিয়ন্ত্রণ, এনক্রিপশন-at-rest) প্রয়োগ করা যায় যা ConfigMap-এর জন্য অপ্রয়োজনীয় বাড়তি জটিলতা হতো। এটি সংবেদনশীলতার ভিত্তিতে ডেটা স্পষ্টভাবে শ্রেণীবদ্ধ করারও একটি উপায় — কোন ডেটা "সাধারণ" আর কোনটা "সাবধানে হ্যান্ডল করতে হবে" তা কোডেই স্পষ্ট থাকে।

প্র ০২ base64 এনকোডিং কি এনক্রিপশন? একটি Secret কি by default নিরাপদ?

না — base64 শুধু একটি এনকোডিং ফরম্যাট, কোনো "কী" ছাড়াই সহজে ডিকোড করা যায়। একটি Secret যদি এনক্রিপশন-at-rest ছাড়া এবং যথাযথ RBAC নিয়ন্ত্রণ ছাড়া কনফিগার করা হয়, তাহলে এটি আসলে খুব বেশি নিরাপদ নয় — যে কেউ etcd-তে বা একটি ভুলভাবে-অনুমোদিত API কলের মাধ্যমে অ্যাক্সেস পায় সে সহজেই আসল মান দেখতে পারবে। প্রকৃত নিরাপত্তার জন্য এনক্রিপশন-at-rest সক্রিয় করা এবং RBAC দিয়ে কঠোরভাবে সীমিত করা কে কোন Secret পড়তে পারে, উভয়ই প্রয়োজন।

প্র ০৩ একই ইমেজ, ভিন্ন ConfigMap — এই প্যাটার্নের প্রধান সুবিধা কী?

এটি L23/L25-এর ইমিউটেবল-ইমেজ দর্শনকে অক্ষত রাখে — dev-এ পরীক্ষিত হুবহু একই ইমেজ production-এও চলে, শুধু কনফিগারেশন ভিন্ন। যদি প্রতিটি পরিবেশের জন্য আলাদা ইমেজ বিল্ড করতে হতো, তাহলে "dev-এ যা পরীক্ষা করেছি সেটাই কি production-এ চলছে" এই নিশ্চয়তা হারিয়ে যেত — একই ইমেজ পুনর্ব্যবহার করাই "build once, run anywhere" (L22)-এর আসল শক্তি।

অনুশীলন

  1. চিন্তা করুন: উপরের কোডে একটি তৃতীয় configmap_staging যোগ করুন (উদাহরণ: API_ENDPOINT="https://staging-internal.example/api", FEATURE_NEW_CHECKOUT="true") এবং build_pod_env() দিয়ে একটি staging_env তৈরি করে প্রিন্ট করুন।

    build_pod_env(base_config, configmap_staging) কল করলে APP_NAME ও LOG_LEVEL dev/prod-এর মতোই অভিন্ন থাকবে, কিন্তু API_ENDPOINT ও FEATURE_NEW_CHECKOUT staging-এর নিজস্ব মান নেবে — এটি দেখায় একই প্যাটার্ন যতগুলো পরিবেশ দরকার ততগুলোতেই স্কেল করে, কোনো নতুন লজিক ছাড়াই।

  2. পরীক্ষা করুন: configmap_dev থেকে LOG_LEVEL এন্ট্রি (যদি থাকত) সরিয়ে দেখুন build_pod_env() কী মান ফেরত দেয় — base_config-এর ডিফল্ট মানই কি টিকে থাকে?

    হ্যাঁ — যেহেতু env = dict(base_config) দিয়ে শুরু হয় এবং শুধু ConfigMap-এ যা আছে তাই update() করে, ConfigMap-এ অনুপস্থিত যেকোনো কী স্বয়ংক্রিয়ভাবে base_config-এর ডিফল্ট মান বজায় রাখে। এটি দেখায় কেন এই merge-প্যাটার্ন নিরাপদ — একটি environment ConfigMap-এ ভুলে একটি কী বাদ পড়লেও অ্যাপ্লিকেশন একটি যুক্তিসঙ্গত ডিফল্ট নিয়ে চলতে থাকে, ক্র্যাশ করে না।

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

পাঠ ২৯
Kubernetes Service ও Ingress