এই পর্বে যা শিখবেন
- Snowflake server-এর সমস্যা আর “pets vs cattle” ধারণা
- একটি machine image-এর ভেতরে কী থাকে, আর কোন image বিশ্বাস করবেন
- একটি সঠিক
#cloud-configলেখা এবং boot-এর প্রতিটি stage পড়া - Launch time আর ব্যর্থতার হিসাব দিয়ে bake ও bootstrap-এর মধ্যে বেছে নেওয়া
- Golden image, launch template, patch-এর ছন্দ আর পুরোনো image অবসরের নিয়ম
১ · হাতে বানানো server কেন ফাঁদ
পর্ব ১৪-তে আপনি হাতে একটি server সাজিয়েছিলেন: package বসানো, Nginx-এর config, firewall, certificate. একটির জন্য এটি ঠিক আছে। এবার ভাবুন, একটি কাল্পনিক অনলাইন বাজার অ্যাপে ঈদের আগে ১০টি server লাগবে, আর একটি রাত তিনটায় নষ্ট হয়ে গেছে। কেউ কি ঠিক মনে করতে পারবেন, ছয় মাস আগে কোন কমান্ডগুলো কোন ক্রমে চালানো হয়েছিল?
এভাবে হাতে বদলাতে বদলাতে একটি server অনন্য হয়ে যায়। Martin Fowler ২০১২ সালে নিজের লেখায় একে বলেছেন snowflake server, কারণ দুটি তুষারকণা হুবহু এক হয় না। এমন server-এর সমস্যা তিনটি:
- নকল করা যায় না: নতুন server বানালে কোনো একটি ছোট setting বাদ পড়ে যায়।
- বদলাতে ভয় লাগে: কেউ জানেন না কোন ফাইলে কী বদলালে কী ভাঙবে।
- ধীরে ধীরে আলাদা হয়: একই কাজের server-গুলোর মধ্যে অমিল তৈরি হয়। একে বলে drift.
পাড়ার পুরোনো CNG-র কথা ভাবুন। ইঞ্জিন এক মিস্ত্রির, গিয়ার আরেকজনের, আর তার জোড়া দেওয়া আছে এমনভাবে যা শুধু একজন মিস্ত্রিই বোঝেন। তিনি ছুটিতে গেলে গাড়ি বন্ধ। কারখানার নতুন গাড়ি আলাদা: নকশা আছে, যন্ত্রাংশ এক রকম, আর একটি নষ্ট হলে হুবহু আরেকটি আনা যায়।
Pets vs cattle
এই পার্থক্য বোঝাতে cloud জগতে একটি তুলনা খুব চালু: pets vs cattle. পোষা প্রাণীর নাম থাকে, অসুখ হলে যত্ন করে সারানো হয়। খামারের পালের প্রতিটি প্রাণী নম্বরে চেনা, আর পালটিই আসল। পোষা server হলো db-rahim-01, যাকে সবাই চেনেন। পালের server হলো web-0417; সমস্যা হলে সরিয়ে নতুন একটি আনা হয়।
তুলনাটি cloud-এর আলোচনায় ছড়িয়েছেন মূলত Randy Bias, ২০১২ সালের দিকে। তিনি নিজেই লিখেছেন, ধারণাটি পেয়েছেন Microsoft-এর Bill Baker-এর একটি বক্তৃতা থেকে। একই সময়ে Martin Fowler phoenix server-এর কথা লেখেন: server-কে নিয়মিত পুড়িয়ে নতুন করে জন্ম দেওয়া। ২০১৩ সালে Chad Fowler “immutable” শব্দটি দিয়ে একই চিন্তা জনপ্রিয় করেন, যা আজ immutable infrastructure নামে পরিচিত।
লক্ষ্যটি পরিষ্কার: server-এর জ্ঞান মানুষের মাথায় নয়, একটি নকশায় থাকবে। Cloud-এ এই নকশার দুটি অংশ: machine image আর user data. তবে যে server-এ data থাকে, সেটি অনেকটা পোষাই থেকে যায়। তাকে কীভাবে সামলাবেন, তা ভাবনার প্রশ্নে দেখব।
২ · Machine image-এর ভেতরে কী থাকে
Machine image হলো একটি boot করার মতো disk-এর সংরক্ষিত ছাঁচ, সাথে সেই disk চালাতে যা জানা দরকার তার তথ্য। পর্ব ১৫-তে যে VM চালু হয়েছিল, তার disk এমন একটি ছাঁচ থেকেই নকল হয়েছিল। ছাপাখানার প্লেটের মতো ভাবুন: একবার প্লেট তৈরি হলে হাজারটি কার্ড হুবহু ছাপা যায়।
| অংশ | কী থাকে | কেন জরুরি |
|---|---|---|
| Root volume-এর ছবি | Kernel, OS ফাইল, package, config, আপনার বসানো agent | এটিই server-এর শরীর |
| CPU architecture | x86_64 বা arm64 | ভুল architecture-এর instance type-এ চলবে না |
| Boot তথ্য | Boot mode (BIOS বা UEFI), virtualization-এর ধরন | Instance type-এর সঙ্গে মিলতে হয় |
| Block device mapping | কোন disk কত বড়, কোন ধরনের | Instance চালুর সময় disk তৈরি হয় |
| অনুমতি | কে এই image দিয়ে launch করতে পারবেন | ব্যক্তিগত, ভাগ করা, না সবার জন্য খোলা |
Image আর snapshot এক নয়। Snapshot হলো একটি disk-এর একটি মুহূর্তের ছবি। Image সেই ছবির সঙ্গে boot করার তথ্য যোগ করে। AWS-এ একটি AMI সাধারণত ভেতরে এক বা একাধিক snapshot-এর ওপর দাঁড়িয়ে থাকে। ভেতরের virtual disk কীভাবে কাজ করে, তা পড়তে পারেন Operating Systems · Virtual machine পর্বে।
| ধারণা | AWS | Azure | Google Cloud |
|---|---|---|---|
| নিজের image | AMI | Managed image, বা Azure Compute Gallery-র image version | Custom image |
| Image-এর দল | নামের নিয়ম, tag, parameter | Gallery-র image definition | Image family |
| পরিধি (লেখার সময়ে) | Region-ভিত্তিক; অন্য region-এ copy লাগে | Gallery-তে বহু region-এ replicate করা যায় | Global resource, project-এর ভেতরে |
| Boot-এর নির্দেশ | User data | Custom data, user data | Metadata-র user-data বা startup-script |
| Launch-এর নকশা | Launch template | Scale set-এর model | Instance template |
AWS-এ একই AMI-এর ID প্রতিটি region-এ আলাদা। একটি region-এর ID অন্য region-এর script-এ বসালে launch ব্যর্থ হবে। তাই বহু region-এ কাজ করলে region অনুযায়ী ID-র তালিকা রাখতে হয়, অথবা নাম দিয়ে খুঁজতে হয়।
Image বানানোর আগে পরিষ্কার করা
একটি চলমান server থেকে image বানালে তার ব্যক্তিগত জিনিসও চলে যায় প্রতিটি নকলে। তাই আগে generalization লাগে, মানে একটি নির্দিষ্ট machine-এর পরিচয় মুছে ফেলা। সবচেয়ে জরুরি: SSH host key, /etc/machine-id, shell history, authorized_keys, log আর cloud-init-এর পুরোনো অবস্থা। Host key না মুছলে সব server একই পরিচয় দেখাবে, যা পর্ব ১২-র নিরাপত্তাকে দুর্বল করে।
# Run inside the build VM, just before making the image. Never on a live server.
sudo cloud-init clean --logs # next boot behaves like a first boot
sudo rm -f /etc/ssh/ssh_host_* # new host keys are made on first boot
sudo truncate -s 0 /etc/machine-id # a new machine id is made on first boot
rm -f ~/.bash_history৩ · Image কোথা থেকে নেবেন — বিশ্বাসের প্রশ্ন
Image মানে অন্য কারও disk দিয়ে আপনার server চালানো। ভেতরে যা আছে, তা root অধিকার নিয়েই চলবে। অচেনা লোকের রান্না করা খাবার আর দোকানের সিল করা প্যাকেটের মধ্যে যে পার্থক্য, এখানেও তাই।
Provider-এর public image
Provider বা OS-এর মূল প্রকাশক (Ubuntu, Debian, Red Hat ইত্যাদি) নিজে প্রকাশ করেন। নিয়মিত হালনাগাদ হয়। শুরুর জন্য সবচেয়ে নিরাপদ।
Base হিসেবে এটিই ভালোMarketplace image
বাণিজ্যিক বিক্রেতার প্রস্তুত করা image, যেমন firewall বা database. Software-এর আলাদা খরচ থাকতে পারে।
বিক্রেতা ও মূল্য যাচাই করুনCommunity image
যে কেউ প্রকাশ করতে পারেন। প্রকাশকের কোনো কঠোর যাচাই নাও হতে পারে। ভেতরে পুরোনো software বা ক্ষতিকর জিনিস থাকতে পারে।
Production-এ এড়িয়ে চলুনআপনার নিজের image
বিশ্বস্ত base থেকে আপনার pipeline-এ তৈরি, পরীক্ষিত ও version দেওয়া। একে বলে golden image.
Production-এর লক্ষ্যনামে নয়, প্রকাশকের পরিচয়ে খুঁজুন
Image-এর নাম যে কেউ নকল করতে পারেন। “ubuntu-24.04-server” নামটি দেখে বিশ্বাস করা তাই ভুল। ২০২৫ সালে Datadog-এর গবেষকেরা “whoAMI” নামে একটি ঝুঁকি প্রকাশ করেন: কোনো script যদি শুধু নামের ধরন দিয়ে “সবচেয়ে নতুন” AMI খোঁজে আর প্রকাশক না বলে, তবে একই নামের অচেনা image বেছে নেওয়া সম্ভব। প্রতিরক্ষা সহজ:
- Owner দিন: খোঁজার সময় সবসময় প্রকাশকের account বা project বেঁধে দিন।
- ID pin করুন: Production-এ “latest” নয়, নির্দিষ্ট image ID ব্যবহার করুন।
- স্বাক্ষর মিলিয়ে নিন: Image ফাইল নিজে নামালে প্রকাশকের checksum আর digital signature যাচাই করুন। Ubuntu-র মতো প্রকল্প স্বাক্ষরিত checksum প্রকাশ করে।
- নিয়মে আটকে দিন: AWS-এর Allowed AMIs-এর মতো নিয়ম বা governance policy দিয়ে অনুমোদিত প্রকাশক ঠিক করে রাখুন (পর্ব ৩৫)।
# The owner filter is the important part. 123456789012 is a fake account id.
aws ec2 describe-images \
--owners 123456789012 \
--filters "Name=name,Values=shop-web-*" "Name=state,Values=available" \
--query "sort_by(Images, &CreationDate)[-1].[ImageId,Name]" \
--output text৪ · Instance launch: image + user data
Image সব server-এর জন্য এক। কিন্তু প্রতিটি server-এর কিছু আলাদা কথা জানা দরকার: কোন environment, কোন app version, কোন নাম। এই আলাদা কথা পাঠানো হয় user data দিয়ে। বিয়ের কার্ডের মতো ভাবুন: ছাপা এক, শুধু খামে অতিথির নাম হাতে লেখা।
Image + user data → চলমান instance
One image and one set of instructions become many running instances
Instance নিজের user data পায় কীভাবে? প্রতিটি VM-এর ভেতর থেকে একটি বিশেষ ঠিকানায় instance metadata সেবা পাওয়া যায়, সাধারণত 169.254.169.254. এই link-local ঠিকানা VM-এর বাইরে থেকে পৌঁছানো যায় না। এখান থেকে VM জানে নিজের instance ID, region, network আর user data.
নিচে তিন provider-এ একই কাজ দেখুন। এগুলো শুধু উদাহরণ। চালালে খরচ হতে পারে, আর আপনার account না থাকলে চালানোর দরকার নেই। পরীক্ষা শেষে instance মুছে ফেলার কমান্ডও দেওয়া আছে।
aws ec2 run-instances \
--image-id ami-0123456789abcdef0 \
--instance-type t3.micro \
--user-data file://cloud-config.yaml \
--dry-run # checks permission only; remove it for a real launch
# clean up after a real launch
aws ec2 terminate-instances --instance-ids i-0123456789abcdef0az group create --name rg-demo --location southeastasia
az vm create \
--resource-group rg-demo \
--name web-1 \
--image Ubuntu2404 \
--custom-data cloud-config.yaml \
--generate-ssh-keys
# clean up (deletes every resource in the group)
az group delete --name rg-demogcloud compute instances create web-1 \
--zone=asia-south1-a \
--machine-type=e2-micro \
--image-family=ubuntu-2404-lts-amd64 \
--image-project=ubuntu-os-cloud \
--metadata-from-file=user-data=cloud-config.yaml
# clean up
gcloud compute instances delete web-1 --zone=asia-south1-aনাম এক হলেও আচরণ এক নয়। Google Cloud-এর startup-script সাধারণত প্রতি boot-এ চলে। AWS-এর user data script ডিফল্টে প্রতি instance-এ একবার চলে। আর cloud-init সব image-এ থাকে না, যেমন Windows-এ আলাদা agent কাজ করে। User data-র আকারেরও সীমা আছে; AWS-এ লেখার সময়ে তা ১৬ KB, অন্য provider-এ আলাদা। বড় script নিজে না পাঠিয়ে সেটি নামিয়ে আনার নির্দেশ পাঠানোই ভালো।
৫ · cloud-init: প্রথম boot-এর ভেতরে কী ঘটে
cloud-init হলো image-এর ভেতরে থাকা একটি প্রোগ্রাম, যা boot-এর সময় চলে আর user data পড়ে কাজ করে। Canonical-এর Ubuntu দিয়ে শুরু হলেও এখন বেশিরভাগ বড় Linux distribution আর cloud-এ এটি পাওয়া যায়। User data-র প্রথম লাইন দেখে সে বোঝে কী করতে হবে: #! দিয়ে শুরু হলে shell script, আর #cloud-config হলে YAML নির্দেশ। Cloud-config-এ আপনি কমান্ড নয়, চাওয়া অবস্থা লেখেন, তাই সাধারণত এটিই ভালো।
#cloud-config
# Fictional shop web server. No passwords or keys here.
hostname: shop-web
package_update: true
packages:
- nginx
- curl
write_files:
- path: /etc/nginx/conf.d/health.conf
owner: root:root
permissions: '0644'
content: |
server {
listen 8080;
location = /healthz {
default_type text/plain;
return 200 "ok\n";
}
}
bootcmd:
- echo "boot seen" >> /var/log/boot-seen.log
runcmd:
- systemctl enable --now nginx
- curl -fsS http://127.0.0.1:8080/healthz
final_message: "cloud-init finished in $UPTIME seconds"প্রথম লাইনের #cloud-config লেখাটি বাধ্যতামূলক; এটি বাদ দিলে পুরো ফাইলটি কাজ না করেই পড়ে থাকতে পারে। ফাইলটি পাঠানোর আগে পরীক্ষা করা যায়: cloud-init schema --config-file . Stage-গুলো নিচের ক্রমে চলে।
| Stage | systemd unit (উদাহরণ) | কী ঘটে |
|---|---|---|
| Detect | generator, ds-identify | কোন cloud-এ চলছে, cloud-init চালানো দরকার কি না ঠিক করা। এর উৎসকে বলে datasource. |
| Local | cloud-init-local | Network চালুর আগে datasource খোঁজা, network-এর config লেখা |
| Network | cloud-init-network (পুরোনো version-এ cloud-init) | User data পড়া; bootcmd, write_files, disk বড় করা, hostname, user, SSH key |
| Config | cloud-config | NTP, locale, package-এর উৎসের মতো config; runcmd এখানে script হিসেবে শুধু লেখা হয় |
| Final | cloud-final | Package install, runcmd-এর script চালানো, final_message |
এই ক্রম থেকে একটি ফাঁদ আসে। write_files চলে package install-এর আগে। তাই owner: www-data লিখলে তখনো সেই user না থাকায় সমস্যা হতে পারে। সমাধান হলো ঐ entry-তে defer: true দেওয়া, যা ফাইল লেখাকে Final-এ পাঠায়। নিচে একটি instance-এর boot ধাপে ধাপে দেখুন। সময়গুলো ধরে নেওয়া, শুধু ক্রমটি বোঝার জন্য।
| Uptime | |
| কে চলছে | |
| Network | |
| health.conf | |
| Nginx | |
| Health check |
- Power-on. Control plane image থেকে disk বানিয়ে VM চালু করল। Firmware থেকে bootloader, তারপর kernel উঠল। cloud-init এখনো ঘুমিয়ে।
- Detect. systemd চালু হলো।
ds-identifyবুঝল এটি একটি cloud VM, তাই cloud-init-এর unit-গুলো চালু রাখল। - Local. Datasource খুঁজে পেল। Instance ID নতুন, তাই এটি “প্রথম boot” বলে গণ্য হলো। Network-এর config লেখা হলো, network এখনো ওঠেনি।
- Network. Network উঠল। User data পড়া হলো।
bootcmdচলল,write_fileshealth.conf লিখল, disk বড় হলো, hostname আর SSH key বসল। - Config. সময়, locale আর package-এর উৎস ঠিক হলো।
runcmd-এর লাইনগুলো একটি script ফাইলে লেখা হলো, কিন্তু চলেনি। - Final: package.
apt-get updateআর nginx, curl install হলো। সবচেয়ে সময় লাগল এই ধাপে, প্রায় ৪৭ সেকেন্ড। Provider এখনো দেখাচ্ছে “running”, কিন্তু app প্রস্তুত নয়। - Final: runcmd. Nginx চালু হলো।
curlনিজের/healthzথেকেokপেল। Health check সফল। - শেষ।
final_messageছাপা হলো, আরboot-finishedচিহ্ন তৈরি হলো। Load balancer এখন traffic পাঠাতে পারে।
কোনটি একবার, কোনটি প্রতি boot-এ
cloud-init প্রতিটি কাজের একটি চিহ্ন রাখে /var/lib/cloud/ ফোল্ডারে। পরের boot-এ চিহ্ন দেখে কাজটি বাদ দেয়। এই হিসাব instance ID-র সঙ্গে বাঁধা। তাই সাধারণ reboot বা stop-start-এ ID একই থাকে, আর নতুন instance-এ ID নতুন হওয়ায় কাজগুলো আবার চলে।
| কী | কতবার চলে | কোন কাজে |
|---|---|---|
bootcmd | প্রতি boot-এ, শুরুর দিকে | খুব প্রাথমিক কাজ |
write_files, packages, runcmd | প্রতি instance-এ একবার | সাধারণ সেটআপ |
/var/lib/cloud/scripts/per-boot/ | প্রতি boot-এ | Image-এ রাখা script, প্রতিবার চালাতে হলে |
/var/lib/cloud/scripts/per-instance/ | প্রতি instance-এ একবার | Image-এ রাখা নতুন instance-এর script |
/var/lib/cloud/scripts/per-once/ | মোটের ওপর একবারই | ID বদলালেও আর চলবে না |
সমস্যা হলে কোথায় দেখবেন
Boot-এর সমস্যা ধরতে এই কয়েকটি জায়গা মনে রাখুন। /var/log/-এ আছে আপনার কমান্ডের আউটপুট, আর /var/log/-এ cloud-init-এর নিজের বিস্তারিত log. নিচের আউটপুট নমুনা — version-ভেদে আলাদা হতে পারে।
$ cloud-init status --wait # wait until finished, then report
status: done
$ sudo cloud-init analyze blame # which module took how long (sample output)
-- Boot Record 01 --
46.81200s (modules-final/config-package_update_upgrade_install)
2.34100s (init-network/config-growpart)
1.10700s (init-local/search-Ec2Local)
$ sudo tail -n 20 /var/log/cloud-init-output.log
$ sudo cat /var/lib/cloud/instance/user-data.txt # root onlyruncmd-এর একটি কমান্ড ব্যর্থ হলেও পরের লাইনগুলো সাধারণত চলতে থাকে, কারণ সেটি একটি সাধারণ shell script. Script-এর শেষ ফলই ধরা হয়। তাই ফল নিশ্চিত হতে চাইলে নিজে set -e ব্যবহার করুন, অথবা শেষে যাচাইয়ের কমান্ড রাখুন। নতুন version-এ cloud-init status-এর exit code-ও সাহায্য করে: সফল হলে 0, ব্যর্থ হলে 1, আর আংশিক সমস্যায় 2.
৬ · User data-তে secret নয়, আর script হোক idempotent
User data দেখতে ব্যক্তিগত মনে হয়, কিন্তু আসলে তা নয়। এটি encrypted নয়; API-তে base64 আকারে থাকা মানে শুধু অন্য রকম করে লেখা। নিচের জায়গাগুলোতে এটি পড়া সম্ভব:
- VM-এর ভেতর থেকে: Metadata সেবা থেকে; সাধারণ user বা কোনো দুর্বল app-ও এটি পড়তে পারে।
- Cloud API থেকে: Instance-এর তথ্য পড়ার অনুমতি যাঁর আছে, তিনিও অনেক ক্ষেত্রে পড়তে পারেন।
- Disk আর log থেকে: cloud-init user data-র কপি রাখে, আর কমান্ড ছাপালে তা log-এ যায়।
- Launch template আর image থেকে: নকল হলে secret-ও নকল হয়।
ঠিক পথ হলো instance-কে পরিচয় দেওয়া, secret নয়। Instance-এর সঙ্গে একটি instance role যুক্ত করুন (পর্ব ৩১)। Boot-এর সময় বা app চালুর সময় সে নিজের অস্থায়ী পরিচয়ে secret manager থেকে শুধু নিজের secret পড়বে (পর্ব ৩৩)। User data-তে থাকবে শুধু secret-এর নাম, মান নয়।
# User data holds only the secret's NAME. The role gives permission at run time.
umask 077
aws secretsmanager get-secret-value \
--secret-id shop/db-password \
--query SecretString --output text > /run/shop/db-password
# Azure Key Vault and Google Secret Manager work the same way.
# Do not use "set -x" here: it would print commands into the log.Metadata সেবাও একটি ঝুঁকি। কোনো web app-কে দিয়ে ভেতরের ঠিকানায় অনুরোধ পাঠানোর ত্রুটিকে বলে SSRF. এ থেকে বাঁচতে AWS ২০১৯ সালে session token-ভিত্তিক IMDSv2 আনে। Launch template-এ একে বাধ্যতামূলক করুন। অন্য provider-ও অনুরোধে বিশেষ header চায়।
Idempotent script
User-data script আবার চলতে পারে: per-boot-এ রাখলে, image build পুনরায় চালালে, বা হাতে পরীক্ষা করলে। তাই script-কে idempotent করুন, মানে একবার চালালে যা হয়, দশবার চালালেও তাই হবে। পর্ব ১০-এর নিরাপদ script-এর নিয়ম এখানে কাজে লাগে। মূল কৌশল হলো “কাজটি করা” নয়, “এই অবস্থা নিশ্চিত করা”। নিচের script একটি temp ফোল্ডারের ভেতর ভুয়া /etc বানিয়ে কাজ করে, আসল /etc ছোঁয় না।
set -euo pipefail
ROOT=$(mktemp -d) # a fake root, not the real /etc
trap 'rm -rf "$ROOT"' EXIT
changed=0
report() { printf '%-8s %s\n' "$1" "$2"; [ "$1" = ok ] || changed=$((changed + 1)); }
ensure_dir() { # create the folder only if missing
if [ -d "$ROOT$1" ]; then report ok "$1"
else mkdir -p "$ROOT$1"; report changed "$1"; fi
}
ensure_line() { # add the line only if absent
touch "$ROOT$1"
if grep -qxF "$2" "$ROOT$1"; then report ok "$1: $2"
else echo "$2" >> "$ROOT$1"; report changed "$1: $2"; fi
}
ensure_file() { # rewrite only if the content differs
if [ -f "$ROOT$1" ] && [ "$(cat "$ROOT$1")" = "$2" ]; then report ok "$1"
else echo "$2" > "$ROOT$1.tmp"; mv "$ROOT$1.tmp" "$ROOT$1"; report changed "$1"; fi
}
provision() {
changed=0
ensure_dir /etc/shop
ensure_line /etc/shop/limits.conf "nofile 65535"
ensure_file /etc/shop/health.conf "listen 8080"
echo "result: $changed changed"
}
echo "== first run"; provision
echo "== second run"; provision
echo "== someone edits one file by hand"
echo "listen 9999" > "$ROOT/etc/shop/health.conf"
provision
for run in 1 2 3; do echo "nofile 65535" >> "$ROOT/naive.conf"; done
echo "a naive append, run 3 times: $(wc -l < "$ROOT/naive.conf") lines"প্রথম চালানোয় result: 3 changed, দ্বিতীয়বার result: 0 changed: কোনো কাজই দ্বিগুণ হয়নি। হাতে ফাইল বদলানোর পর script শুধু সেই একটি ফাইল ঠিক করে দিল, result: 1 changed. এটিই drift সারানোর ছোট রূপ। শেষ লাইনে সাধারণ >> তিনবার চলে 3 lines বানিয়েছে, যা idempotent নয়। ফাইল লেখার সময় আগে .tmp-এ লিখে mv করা হয়েছে, যাতে অর্ধেক লেখা ফাইল কখনো দেখা না যায়।
৭ · Bake বনাম bootstrap
একটি server-কে প্রস্তুত করার দুটি সময় আছে: launch-এর আগে, আর launch-এর পরে।
- Baking: সব কিছু আগেই image-এ ভরে রাখা। Boot-এ প্রায় কিছুই বসাতে হয় না।
- Bootstrapping: সাধারণ base image নিয়ে boot-এর সময় সব বসানো।
- Half-baked: ধীর ও কম বদলানো অংশ (OS patch, runtime, agent) image-এ, আর app-এর নতুন version boot-এ।
বিয়েবাড়ির ক্যাটারিং ভাবুন। Baking হলো আগের রাতেই মাংস মেখে, মসলা বেটে, হাঁড়ি প্রস্তুত রাখা; অতিথি এলে শুধু চুলা জ্বালালেই হয়। Bootstrapping হলো অতিথি আসার পর বাজারে যাওয়া। তাজা জিনিস পাবেন, নতুন পদও যোগ করতে পারবেন। কিন্তু সময় বেশি, আর সেদিন বাজার বন্ধ থাকলে সবাই না খেয়ে থাকবেন।
| বিষয় | Bake | Bootstrap | Half-baked |
|---|---|---|---|
| Launch time | সবচেয়ে কম | সবচেয়ে বেশি | মাঝামাঝি |
| Boot-এ বাইরের নির্ভরতা | প্রায় নেই | Mirror, registry, app store সবই | শুধু app store |
| Instance-গুলো কি এক রকম? | হুবহু এক | Launch-এর দিনের ওপর নির্ভর | OS এক, app নির্দিষ্ট version |
| ছোট পরিবর্তন | নতুন image লাগে, সময় বেশি | Script বদলালেই হয় | App-এর জন্য image লাগে না |
| পরিচালনার খরচ | Pipeline আর বহু image | কম, কিন্তু boot ভাঙে বেশি | দুটোরই কিছুটা |
হিসাব: ধীর launch-এর দাম
ধরুন ঈদের আগে চাহিদা এমনভাবে বাড়ছে যে প্রতি মিনিটে ২টি বাড়তি instance লাগে। নতুন instance প্রস্তুত হতে যতক্ষণ লাগে, ততক্ষণের চাহিদা আগে থেকেই ফাঁকা ক্ষমতা হিসেবে রাখতে হবে।
- Bootstrap, ৪ মিনিট: ২ × ৪ = ৮টি বাড়তি instance সবসময় চালু রাখতে হবে।
- Bake, ১ মিনিট: ২ × ১ = ২টি।
- পার্থক্য: ৬টি। ধরে নিই প্রতিটির দাম ঘণ্টায় $০.১০, আর মাসে ৭২০ ঘণ্টা। তাহলে ৬ × ০.১০ × ৭২০ = মাসে $৪৩২ বাড়তি।
ব্যর্থতারও হিসাব আছে। Boot-এ n-টি স্বাধীন ধাপ থাকলে আর প্রতিটির ব্যর্থতার সম্ভাবনা p হলে, মোট ব্যর্থতা = ১ − (১ − p)n. প্রতিটিতে ০.৫% করে ৬টি ধাপে তা প্রায় ২.৯৬%. অর্থাৎ ১,০০০ launch-এ গড়ে প্রায় ৩০টি ব্যর্থ। আর স্বাধীনতার ধারণাটি বিপদের সময় খাটে না: Mirror বন্ধ থাকলে সব launch একসাথে ব্যর্থ হয়। নিচের সিমুলেটর দুটো প্রভাবই দেখায়। এখানে সব সংখ্যা ধরে নেওয়া, আসল সংখ্যা নয়।
// Bake vs bootstrap over 2000 launches. All numbers are assumed.
function mulberry32(a) { return () => { a = a + 0x6D2B79F5 | 0;
let t = Math.imul(a ^ a >>> 15, 1 | a);
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
return ((t ^ t >>> 14) >>> 0) / 4294967296; }; }
const rnd = mulberry32(2026);
const between = (lo, hi) => lo + (hi - lo) * rnd();
const FAIL = 0.004, N = 2000, OUTAGE = [1200, 1300]; // mirror down: launch 1200-1299
// each step: [min s, max s, can fail?, needs package mirror?]
const boot = [35, 55, false, false], health = [10, 15, false, false];
const apt = [20, 40, true, true], pkgs = [60, 120, true, true];
const app = [10, 30, true, false], agent = [15, 35, true, true];
const plans = {
"bootstrap ": [boot, apt, pkgs, agent, app, health],
"half-baked": [boot, app, health],
"full bake ": [boot, health],
};
for (const [name, steps] of Object.entries(plans)) {
const ok = []; let fail = 0, inOutage = 0;
for (let i = 0; i < N; i++) {
const down = i >= OUTAGE[0] && i < OUTAGE[1];
let t = 0, dead = false;
for (const [lo, hi, risky, mirror] of steps) {
t += between(lo, hi);
if ((risky && rnd() < FAIL) || (mirror && down)) { dead = true; break; }
}
if (dead) { fail++; if (down) inOutage++; } else ok.push(t);
}
ok.sort((a, b) => a - b);
const mean = ok.reduce((s, x) => s + x, 0) / ok.length;
console.log(name, "failed", String(fail).padStart(3), "(" + (fail * 100 / N).toFixed(2) + "%)",
"in outage", String(inOutage).padStart(3), " mean", mean.toFixed(0) + "s",
" p99", ok[Math.floor(ok.length * 0.99)].toFixed(0) + "s");
}আউটপুট: bootstrap failed 134 (6.70%) in outage 100 mean 222s p99 268s, half-baked failed 4 (0.20%) in outage 0 mean 77s p99 95s, full bake failed 0 (0.00%) in outage 0 mean 57s p99 68s. Bootstrap-এর ১৩৪টি ব্যর্থতার ১০০টি mirror বিভ্রাটের সময়ে, মানে ঐ ১০০টি launch-এর সবগুলোই। এই নির্ভরতা না থাকায় half-baked আর bake-এর গায়ে আঁচ লাগেনি। একে বলে static stability: বাইরের কিছু নষ্ট হলেও নতুন ক্ষমতা তৈরি করা যায়। তবে “০ ব্যর্থ” এসেছে কারণ মডেলে bake-এ ঝুঁকিপূর্ণ ধাপই রাখা হয়নি। বাস্তবে capacity বা boot-এর সমস্যায় এটিও ব্যর্থ হতে পারে। FAIL বা OUTAGE বদলে দেখুন।
বেছে নেওয়ার সহজ নিয়ম: যা ধীর আর কম বদলায়, তা bake করুন। যা environment-ভেদে আলাদা, তা boot-এ দিন। Secret কখনোই image-এ নয়। Autoscaling-এর পালের জন্য bake বা half-baked সাধারণত ভালো। অল্প দিন চলা পরীক্ষার server-এ bootstrap-ই যথেষ্ট।
মাঝপথে bootstrap ব্যর্থ হলে
এবার দেখা যাক boot-এর মাঝখানে package mirror বন্ধ হলে কী ঘটে। লক্ষ করুন, provider-এর চোখে VM সারাক্ষণ ঠিকই আছে। সময়গুলো ধরে নেওয়া।
| Uptime | |
| Provider-এর অবস্থা | |
| কী চলছে | |
| ফলাফল | |
| Health check-এ ব্যর্থ |
- Launch. Autoscaling নতুন instance চাইল। কয়েক সেকেন্ডেই provider দেখাল “running”. মনে রাখবেন, এর মানে VM চলছে, app নয়।
- Update সফল। Final stage-এ package-এর তালিকা ঠিকমতো এলো। বিভ্রাটটি আংশিক: তালিকার ফাইল পাওয়া গেছে, কিন্তু package-এর ফাইল নয়।
- Install ব্যর্থ।
nginxনামাতে গিয়ে mirror দিল 503.apt-getশেষ হলো exit code 100 দিয়ে। - ভুল ধারণা।
runcmdতবু চলল, কারণ cloud-init পরের module-এ এগিয়ে যায়।systemctl enable --now nginxবলল, unit নেই। - Error লেখা হলো।
cloud-init statusএখনerrorদেখাচ্ছে। কিন্তু কেউ না দেখলে এই তথ্য log-এই পড়ে থাকে। - Health check ব্যর্থ। ধরে নিই, load balancer ৩০ সেকেন্ড পরপর দেখে, প্রথমবার ৬০ সেকেন্ডে। Port-এ সাড়া নেই। এখনো instance-টি কোনো traffic পায়নি, কিন্তু টাকা খরচ হচ্ছে।
- Unhealthy. পরপর ৩ বার ব্যর্থ হওয়ায় instance-টি unhealthy হলো। ৩ বারের এই সীমাটিও ধরে নেওয়া।
- লুপ। Autoscaling এটি সরিয়ে নতুন একটি আনল। Mirror তখনো বন্ধ, তাই সেটিও একইভাবে ব্যর্থ হবে। চাহিদা বাড়ছে, ক্ষমতা বাড়ছে না, আর log-সহ প্রমাণ মুছে যাচ্ছে। সমাধান: bake বা half-baked, boot-এ retry, log অন্য কোথাও পাঠানো, আর ব্যর্থ launch-এর ওপর alert.
এমন log পড়ার কাজে পর্ব ৯-এর হাতিয়ারই যথেষ্ট। নিচের script একটি নমুনা cloud-init-output.log নিজেই তৈরি করে, প্রথম error খুঁজে বের করে আর প্রতিটি stage কত সেকেন্ডে শুরু হয়েছে তা দেখায়।
set -euo pipefail
log=$(mktemp); trap 'rm -f "$log"' EXIT
cat > "$log" <<'EOF'
Cloud-init v. 24.4 running 'init-local' at Fri, 30 Oct 2026 04:12:03 +0000. Up 6.10 seconds.
Cloud-init v. 24.4 running 'init' at Fri, 30 Oct 2026 04:12:06 +0000. Up 9.02 seconds.
Cloud-init v. 24.4 running 'modules:config' at Fri, 30 Oct 2026 04:12:10 +0000. Up 13.21 seconds.
Cloud-init v. 24.4 running 'modules:final' at Fri, 30 Oct 2026 04:12:12 +0000. Up 15.44 seconds.
Reading package lists...
Err:1 http://mirror.example.net/ubuntu noble-updates/main amd64 nginx 1.24.0
503 Service Unavailable [IP: 192.0.2.10 80]
E: Unable to fetch some archives, maybe run apt-get update
Failed to enable unit: Unit file nginx.service does not exist.
Cloud-init v. 24.4 finished at Fri, 30 Oct 2026 04:12:39 +0000. Up 42.07 seconds
EOF
echo "--- stage start times"
awk '/running/ { gsub(/[^a-z:-]/, "", $5); printf "%-16s %6.2f s\n", $5, $(NF-1) }' "$log"
echo "--- first real error"
grep -n -m1 -E '^(E:|Err:)' "$log" | cut -c1-60
echo "--- problem lines: $(grep -c -E '^(E:|Err:|Failed)' "$log")"
echo "--- finished at: $(awk '/finished at/ { print $(NF-1) }' "$log") s"আউটপুট বলছে, modules:final শুরু হয়েছে 15.44 s-এ, আর 6:Err:1 http://mirror.example.net/... হলো ৬ নম্বর লাইনের প্রথম আসল error. মোট সমস্যার লাইন problem lines: 3: mirror-এর Err, apt-এর E:, আর unit না পাওয়ার Failed. শেষ লাইনটি দেখে ভুল করবেন না: finished at: 42.07 s মানে cloud-init থেমেছে, সফল হয়েছে তা নয়। সবসময় প্রথম error থেকে পড়া শুরু করুন, কারণ পরেরগুলো প্রায়ই তারই ফল। Log-এর লেখাটি নমুনা — version-ভেদে আলাদা হতে পারে।
৮ · Golden image pipeline আর versioning
Golden image হাতে বানালে আপনি আবার snowflake বানাচ্ছেন, শুধু একধাপ পিছিয়ে। তাই image-ও বানাতে হয় একটি স্বয়ংক্রিয় pipeline-এ। ধারণাটি নিচের ছবিতে; আসল হাতিয়ার Packer আসবে পর্ব ৫৬-তে। AWS-এর EC2 Image Builder আর Azure-এর VM Image Builder-ও একই কাজ করে।
Golden image-এর কারখানা
From a trusted base image to a tested, versioned image
- Base image
owner + ID pinবিশ্বস্ত উৎস - Build VM
patch · hardenঅস্থায়ী server - পরীক্ষা
boot · scanব্যর্থ হলে বাতিল - প্রকাশ
shop-web-v42version আর tag - Promote
test → prodএকই image
- Base: বিশ্বস্ত প্রকাশকের নির্দিষ্ট image থেকে শুরু। পর্ব ৮-এর hardening এখানেই একবার করে দিলে প্রতিটি server জন্ম থেকেই শক্ত হয়।
- Build: Patch, runtime, log ও monitoring agent বসানো; তারপর পরিষ্কার করা।
- পরীক্ষা: নতুন image থেকে সত্যিই একটি instance চালিয়ে দেখা, boot হয় কি না আর service ওঠে কি না। সাথে CVE scan.
- প্রকাশ: নাম, version আর উৎসের তথ্য লিখে রাখা। ব্যর্থ হলে image প্রকাশই হবে না।
- Promote: Test-এ যে image পাস করল, হুবহু সেটিই production-এ যাবে। Production-এর জন্য নতুন করে build নয়। পর্ব ৫৮-র “একবার build, সব জায়গায় deploy” এখানেও খাটে।
Version আর tag
Image একবার প্রকাশ হলে আর বদলাবে না। বদলাতে হলে নতুন version. প্রতিটি image-এর সাথে এমন তথ্য রাখুন, যা পরে তদন্তে কাজে লাগে:
| Tag | উদাহরণ | কোন প্রশ্নের উত্তর দেয় |
|---|---|---|
version | shop-web-v42 | এখন কোনটি চলছে? |
base-image | ubuntu-24.04-20261015 | কোন ভিত্তি থেকে এসেছে? |
git-commit | a1b2c3d | কোন কোড থেকে বানানো? |
built-on | 2026-10-30 | Image কত পুরোনো? |
scan-result | critical=0 | ছাড়পত্র আছে কি? |
“সবচেয়ে নতুন image” বলে কিছু production-এ ব্যবহার করবেন না। Google Cloud-এর image family বা AWS-এর public parameter dev-এ সুবিধাজনক। কিন্তু production-এ নির্দিষ্ট ID থাকলে দুই সপ্তাহ পরের launch আজকের মতোই হবে, আর rollback মানে আগের ID-তে ফেরা।
৯ · Launch template, rollout আর image-এর অবসর
প্রতিবার হাতে দশটি setting দিলে ভুল হবেই। Launch template হলো instance চালুর একটি সংরক্ষিত ফর্ম: image, instance type, subnet, security group, instance role, user data, tag আর metadata-র নিয়ম। পর্ব ১৭-র autoscaling এই ফর্ম দেখেই নতুন instance বানায়। AWS-এর launch template-এ version থাকে। Google Cloud-এর instance template বদলানো যায় না, তাই নতুন একটি বানাতে হয়। Azure-এ scale set-এর model প্রায় এই কাজটিই করে।
# Version 8 = version 7 with only the image changed. Fake ids.
aws ec2 create-launch-template-version \
--launch-template-name shop-web \
--source-version 7 \
--launch-template-data '{"ImageId":"ami-0fedcba9876543210"}'
aws ec2 modify-launch-template \
--launch-template-name shop-web \
--default-version 8একটি গুরুত্বপূর্ণ কথা: Template বদলালে চলমান instance-এ কিছুই বদলায় না। সে শুধু পরের launch-এর ফর্ম। তাই পুরোনো server সরাতে আলাদা rollout লাগে। নিচে একটি জরুরি patch-এর পুরো যাত্রা দেখুন। ফ্লিটে আছে ৬টি instance, আর প্রতিবার ২টি করে বদলানো হবে।
| Template → image | |
| v41 instance | |
| v42 instance | |
| মোট চলছে | |
| v42 image | |
| v41 image |
- CVE ঘোষণা। একটি গুরুত্বপূর্ণ library-তে দুর্বলতা জানা গেল। ফ্লিটের ৬টি instance চলছে v41 থেকে। কেউ server-এ ঢুকে হাতে patch করছেন না।
- Build. Pipeline নিজে চলল। অস্থায়ী VM-এ patch বসল, পরিষ্কার হলো, আর image তৈরি হলো। ফ্লিটে এখনো কোনো পরিবর্তন নেই।
- পরীক্ষা। v42 থেকে একটি পরীক্ষার instance চলল। Boot, service, CVE scan সব পাস। ব্যর্থ হলে এখানেই থামত, production ছুঁত না।
- Template বদল। Template-এর version 8 এখন v42-কে দেখাচ্ছে। লক্ষ করুন, v41 instance এখনো ৬টি: Template চলমান server বদলায় না।
- নতুন ২টি। আগে নতুন ২টি চালু হলো, মোট ৮। ক্ষমতা কখনো ৬-এর নিচে নামছে না। নতুনগুলোর health check পাস না হলে পুরোনো সরানো হবে না।
- পুরোনো ২টি সরল। Load balancer আগে সংযোগ শেষ হতে দিল, তারপর সরাল। মোট আবার ৬: v41 ৪টি, v42 ২টি।
- পরের ব্যাচ। একই নিয়মে আরও ২টি বদলাল। এখন v41 ২টি, v42 ৪টি। Error বাড়লে এখানেই থেমে আগের version-এ ফেরা যায়।
- শেষ ব্যাচ। সব ৬টি v42. v41 মোছা হয়নি, কারণ সমস্যা হলে সেখানেই ফিরতে হবে।
- অবসরের শুরু। নির্দিষ্ট সময় পর কোনো সমস্যা না থাকায় v41 deprecated হলো: নতুন launch-এ আর ব্যবহার হবে না। পরে যাচাই করে মোছা হবে।
এই পদ্ধতির নাম rolling replacement. Blue-green আর canary-র মতো অন্য কৌশল পর্ব ৫৯-এ। AWS Auto Scaling-এর instance refresh, Azure scale set-এর rolling upgrade আর Google-এর managed instance group-এর rolling update এই কাজটিই স্বয়ংক্রিয়ভাবে করে।
Patch-এর ছন্দ
- নিয়মিত: ধরুন প্রতি মাসে একটি নতুন image, base হালনাগাদ করে। ছন্দটি ঝুঁকি আর দলের সামর্থ্য দেখে ঠিক করুন।
- জরুরি: গুরুতর CVE-তে নিয়মিত সময়ের অপেক্ষা না করে একই pipeline চালান। সে জন্যই pipeline-টি দ্রুত আর স্বয়ংক্রিয় হওয়া দরকার।
- বয়সের সীমা: কোনো instance বেশি দিন চললে তাকে বদলে দিন। AWS Auto Scaling-এ maximum instance lifetime ঠিক এই কাজ করে।
- Boot-এ upgrade নয়: User data-তে
package_upgrade: trueদিলে মঙ্গলবারের instance আর বুধবারের instance আলাদা হতে পারে। Boot-ও ধীর হয়।
Image-এর অবসর
পুরোনো image জমতে থাকলে দুটি সমস্যা হয়: কেউ ভুলে অরক্ষিত পুরোনো image চালিয়ে দেন, আর তার storage-এর বিল আসে। ধরুন ৪০ GB-র ২৪টি image, আর প্রতি GB-র দাম মাসে ধরে নেওয়া $০.০৫। সবচেয়ে খারাপ অবস্থায় ২৪ × ৪০ × ০.০৫ = মাসে $৪৮। Snapshot incremental হলে বিল কম হতে পারে, তবে provider-এর দাম নিজে দেখে নিন।
| ধাপ | কী হয় | কী যাচাই করবেন |
|---|---|---|
| Active | Launch-এ ব্যবহার হয় | Scan পরিষ্কার কি না |
| Deprecated | নতুন ব্যবহার নিরুৎসাহিত, rollback-এর জন্য আছে | কোন template এখনো একে দেখাচ্ছে |
| নিষ্ক্রিয় | নতুন launch বন্ধ | কোনো autoscaling নির্ভর করছে কি না |
| মোছা | Image আর snapshot মুছে ফেলা | Audit-এর জন্য তথ্য রাখা আছে কি না |
AWS-এ AMI deregister করলে চলমান instance-এর ক্ষতি হয় না, কিন্তু পেছনের snapshot সাধারণত নিজে থেকে মোছে না, তাই বিল চলতেই থাকে। Google Cloud-এ image-এর DEPRECATED, OBSOLETE আর DELETED অবস্থা আছে। Azure Compute Gallery-তে version-এ end-of-life তারিখ দেওয়া যায়। মোছার আগে দেখে নিন, কোনো launch template সেই image-কে দেখাচ্ছে কি না; নইলে পরের autoscaling ব্যর্থ হবে।
Drift: হাতে রাখা বনাম image দিয়ে বদলানো
Image-ভিত্তিক বদলানোর আসল লাভ সময়ের সাথে বোঝা যায়। নিচের সিমুলেটরে ২০টি করে server-এর দুটি ফ্লিট, ১২ মাস। ধরে নেওয়া হয়েছে, প্রতি মাসে একটি patch আসে, হাতে রাখা ফ্লিটে প্রতিটি server-এ তা বাদ পড়ার সম্ভাবনা ১০%. আর দুই ফ্লিটেই প্রতিটি server-এ মাসে ৩৫% সম্ভাবনায় কেউ একটি জরুরি হাতের পরিবর্তন করেন। Image ফ্লিট প্রতি মাসের শেষে পুরোটা বদলে যায়।
// Drift over 12 months: 20 hand-kept servers vs 20 replaced from a monthly image.
function mulberry32(a) { return () => { a = a + 0x6D2B79F5 | 0;
let t = Math.imul(a ^ a >>> 15, 1 | a);
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
return ((t ^ t >>> 14) >>> 0) / 4294967296; }; }
const rnd = mulberry32(16);
const SERVERS = 20, HOTFIX = 0.35, MISS = 0.10; // assumed monthly chances
let hand = Array.from({ length: SERVERS }, () => new Set());
let image = Array.from({ length: SERVERS }, () => new Set());
let wanted = new Set(), next = 0;
const diff = s => [...s].filter(k => !wanted.has(k)).length
+ [...wanted].filter(k => !s.has(k)).length;
const avg = fleet => fleet.reduce((sum, s) => sum + diff(s), 0) / fleet.length;
const kinds = fleet => new Set(fleet.map(s => [...s].sort().join())).size;
console.log("month | hand: kinds avg-diff | image: before replace -> after");
for (let m = 1; m <= 12; m++) {
const patch = "patch" + m; wanted = new Set(wanted).add(patch);
for (const s of hand) if (rnd() >= MISS) s.add(patch); // someone may skip one
for (const s of image) s.add(patch); // patch came in the image
for (const fleet of [hand, image]) for (const s of fleet)
if (rnd() < HOTFIX) s.add("hotfix" + next++); // unique hand edit
const before = [kinds(image), avg(image).toFixed(1)];
image = image.map(() => new Set(wanted)); // replace all from image
if (m % 2 === 0) console.log(String(m).padStart(5), "|",
String(kinds(hand)).padStart(5), avg(hand).toFixed(1).padStart(8), "|",
"kinds", String(before[0]).padStart(2), "diff", before[1], "-> kinds",
kinds(image), "diff", avg(image).toFixed(1));
}kinds মানে ফ্লিটে কত রকম আলাদা server আছে, আর diff মানে চাওয়া অবস্থা থেকে গড়ে কত অমিল। ১২ মাসে হাতে রাখা ফ্লিট: 12 | 20 5.5, মানে ২০টি server-ই আলাদা, আর গড়ে সাড়ে ৫টি অমিল। শুরুতে মাস ২-এ ছিল 12 0.7. অমিল প্রায় সরলরেখায় বাড়ছে, কারণ কিছুই একে কমায় না। Image ফ্লিটেও মাসের মধ্যে হাতের পরিবর্তন হয় (kinds 8 diff 0.3), কিন্তু প্রতি মাসে তা শূন্যে ফেরে: kinds 1 diff 0.0. দামটিও দেখুন: হাতের জরুরি সংশোধন pipeline-এ না তুললে replacement-এ তা হারিয়ে যায়। তাই জরুরি কাজ হাতে করলেও পরে নকশায় তুলতে হয়।
আরও গভীরে: cloud-init নতুন instance চিনে datasource-এর instance ID দিয়ে, আর /var/lib/cloud/instance হলো সেই ID-র ফোল্ডারের একটি symlink. কোনো cloud ছাড়াই পরীক্ষা করতে NoCloud datasource আছে, যেখানে user data একটি স্থানীয় disk থেকে আসে। Fedora CoreOS আর Flatcar-এর মতো OS প্রথম boot-এ Ignition ব্যবহার করে, যা সফল না হলে boot-ই থামিয়ে দেয়। Snapshot থেকে বানানো disk-এর data প্রায়ই প্রথম পড়ার সময় ধীরে ধীরে আসে, তাই নতুন volume-এর প্রথম I/O আর boot ধীর হতে পারে।
পরীক্ষা ও ইন্টারভিউতে:
- Snapshot আর image-এর পার্থক্য? Snapshot একটি disk-এর ছবি; image-এ এর সাথে boot-এর তথ্য ও অনুমতি থাকে।
runcmdআরbootcmd-এর পার্থক্য?bootcmdপ্রতি boot-এ শুরুর দিকে;runcmdপ্রতি instance-এ একবার, শেষের দিকে।- Bake কখন, bootstrap কখন? দ্রুত scale দরকার হলে bake; ঘন ঘন বদলানো বা অল্প দিনের server-এ bootstrap; বাস্তবে প্রায়ই দুটির মিশ্রণ।
- Secret কোথায় রাখবেন? Secret manager-এ। Instance role দিয়ে চলার সময় পড়বেন, user data বা image-এ নয়।
- Immutable infrastructure মানে? চলমান server-এ পরিবর্তন না করে নতুন image থেকে বদলে ফেলা।
১০ · AI-এর যুগে image আর cloud-init
AI খুব দ্রুত cloud-config লিখে দিতে পারে। কিন্তু সেটি ভুল হলে ব্যর্থতা দেখা যাবে boot-এর সময়, প্রায়ই নিঃশব্দে। Image-এর ভুল আবার একশো server-এ একসাথে নকল হয়। এই কাজে AI সাধারণত যে ভুলগুলো করে:
| AI-এর ভুল | ফল | যাচাই |
|---|---|---|
User data-তে password বা API_KEY | Metadata, log আর template-এ secret ফাঁস | Secret manager আর instance role |
| Owner ছাড়া নাম দিয়ে “latest” image | অচেনা image চলার ঝুঁকি | Owner filter আর ID pin |
| নিজের বানানো cloud-config key | Key নিঃশব্দে উপেক্ষিত হতে পারে | cloud-init schema আর official docs |
SSH-এর জন্য 0.0.0.0/0 | Port সবার জন্য খোলা | Security group, session manager |
curl ... | bash, chmod 777 | অযাচাই করা কোড root হিসেবে; সবার লেখার অধিকার | Checksum, নির্দিষ্ট version, কম অনুমতি |
| Instance বা image মোছার কমান্ড, সতর্কতা ছাড়া | Production হারানো, rollback বন্ধ | ID নিজে পড়ুন, আগে --dry-run |
AI-কে কাজ দেওয়ার সময় সীমাগুলো আগেই বলে দিন, আর শেষে তাকে দিয়ে নিজের ঝুঁকি লেখান। নিচের prompt-এ কোনো আসল account ID, key বা IP দেওয়া নেই, আপনিও দেবেন না।
AI-এর লেখা user data হাতে পেলে — চেকলিস্ট
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।
প্র ০১“Pets vs cattle” কি সব server-এ খাটে? Database server কি সত্যিই ফেলে দেওয়ার মতো?
তুলনাটি চমৎকার, কিন্তু একে সর্বজনীন নিয়ম ভাবলে বিপদ। Randy Bias নিজেও পরে লিখেছেন, তুলনাটি ঠিকভাবে ব্যবহার করতে হয়: এটি মূলত নকশার ধরনের কথা বলে, মানে একটি একক machine-এর নষ্ট হওয়াকে সিস্টেম স্বাভাবিক ঘটনা হিসেবে মেনে নেয় কি না।
Web server সহজেই পালের প্রাণী, কারণ সেটি stateless: ভেতরে এমন কিছু নেই যা অন্য কোথাও নেই। Database-এ আছে data, যা নকল করা ধীর আর হারানো ভয়ংকর। তাই পুরো database server হুট করে মুছে দেওয়া যায় না।
তবে “কখনো নয়”, এই উত্তরও ঠিক নয়। আসল কৌশল হলো state আর compute আলাদা করা। Data থাকবে আলাদা disk, replica বা managed সেবায় (পর্ব ২২)। তাহলে যে machine-এ database চলছে, সেটি বদলানো যায়। Replica-কে নতুন image দিয়ে বদলে, তাকে primary করে, পুরোনোটি সরানো হলে একটি পোষা server-কেও পালের মতো সামলানো যায়। Kubernetes-এর StatefulSet-ও (পর্ব ৪৭) একই চিন্তার একটি রূপ: পরিচয় স্থায়ী, machine নয়।
আরেকটি ব্যতিক্রম হলো দামি বিশেষ হার্ডওয়্যার, লাইসেন্সের সাথে বাঁধা পুরোনো ব্যবসায়িক সিস্টেম আর legacy app. এগুলো বাস্তবে পোষা থাকবে, আর সেটি লজ্জার নয়। তাদের জন্য ভালো backup, runbook আর পরিষ্কার পুনরুদ্ধার প্রক্রিয়া দরকার (পর্ব ২৪)। শব্দটির একটি নরম দিকও আছে: অনেকে প্রাণীর তুলনাটি অপছন্দ করেন, তাই কোথাও “disposable” বা “replaceable” শব্দ ব্যবহার হয়।
মূল উপলব্ধি: প্রশ্নটি “server পোষা না পালের” নয়। প্রশ্ন হলো, “এই server-টি এখনই হারালে আমরা কত দ্রুত, কত কম ক্ষতিতে আগের অবস্থায় ফিরতে পারব?”
প্র ০২Log4Shell-এর মতো জরুরি দুর্বলতায় কোনটি দ্রুত: চলমান server-এ patch, নাকি নতুন image?
২০২১ সালের ডিসেম্বরে Log4j library-তে Log4Shell (CVE-2021-44228) প্রকাশ পেলে পৃথিবী জুড়ে দলগুলো একটি প্রশ্নের মুখে পড়ে: “আমাদের কোথায় কোথায় এটি আছে?” প্রশ্নটি শুনতে সহজ, কিন্তু হাতে রাখা ফ্লিটে এর উত্তর পাওয়াই দিনের পর দিন লাগতে পারে। কারণ প্রতিটি server-এর ইতিহাস আলাদা।
Image-ভিত্তিক ফ্লিটে উত্তরটি একটি ডেটা অনুসন্ধানের মতো: কোন image-এ এই library আছে, আর সেই image কোন কোন instance চালাচ্ছে। Tag আর software তালিকা (SBOM, পর্ব ৪১) এখানে খুব কাজে লাগে।
গতির হিসাবে দুটি পথের নিজস্ব শক্তি আছে। হাতে বা Ansible-এ চলমান server patch করা প্রথম ঘণ্টায় দ্রুত হতে পারে, কারণ build, পরীক্ষা আর rollout-এর অপেক্ষা নেই। কিন্তু সব server-এ ঠিকমতো হলো কি না নিশ্চিত হওয়া কঠিন, আর একটি ব্যর্থ মাঝপথের অবস্থা তৈরি হতে পারে। নতুন image-এর পথে শুরুতে সময় লাগে, কিন্তু একবার pipeline চললে প্রতিটি server-এর অবস্থা নিশ্চিত, আর rollback-ও সহজ।
Netflix ২০১৩ সালে নিজের ব্লগে Aminator নামে AMI বানানোর হাতিয়ার প্রকাশের কথা জানিয়েছিল, যেখানে প্রতি release-এ baked image ব্যবহারের বর্ণনা ছিল। এমন দলের কাছে জরুরি patch কোনো বিশেষ ঘটনা নয়, প্রতিদিনের একই পথ। এখানেই আসল শিক্ষা: যে পথ প্রতিদিন চলে, জরুরি সময়ে সেটিই নির্ভরযোগ্য। বছরে একবার ব্যবহার হওয়া জরুরি প্রক্রিয়া ঠিক দরকারের সময় ভেঙে যায়।
বাস্তবে অনেক দল দুটিই রাখে: খুব জরুরি হলে আগে সাময়িক ব্যবস্থা (যেমন WAF-এর নিয়ম বা config পরিবর্তন), তারপর স্থায়ী image.
মূল উপলব্ধি: নিরাপত্তার গতি নির্ভর করে জরুরি মুহূর্তের চেষ্টার ওপর নয়, স্বাভাবিক দিনের pipeline-এর ওপর। আগে জানা, পরে দ্রুত বদলানো, এই দুটোই image নকশায় পাওয়া যায়।
প্র ০৩Metadata সেবা তো শুধু VM-এর ভেতর থেকে পাওয়া যায়। তাহলে সেখানে secret থাকলে ক্ষতি কী?
“শুধু ভেতর থেকে” কথাটি শুনতে নিরাপদ। কিন্তু একটি web app যদি ব্যবহারকারীর দেওয়া URL নিজে পড়ে, তবে “ভেতরের” অনুরোধ তৈরি করছে app নিজেই। এই ধরনের ত্রুটিকে বলে Server-Side Request Forgery বা SSRF. OWASP Top 10 (২০২১)-এ এটি আলাদা একটি বিভাগ।
২০১৯ সালে Capital One-এর বড় data ফাঁসের প্রকাশ্য বিবরণে এই ধরনটি উঠে আসে: ভুলভাবে সাজানো একটি firewall-এর মাধ্যমে metadata সেবা থেকে role-এর credential পাওয়া গিয়েছিল, আর তা দিয়ে storage-এর data পড়া হয়েছিল। ঘটনাটি মার্কিন আদালতের নথি ও সংবাদে এসেছে, আর এর বিস্তারিত নিয়ে নানা বর্ণনা আছে। মূল শিক্ষাটি প্রকৌশলের: সুরক্ষার একটি স্তরকে একমাত্র ভরসা ভাবলে সেটি ভেঙে গেলেই সব শেষ।
এর কয়েক মাস পরে, ২০১৯ সালের শেষ দিকে, AWS IMDSv2 আনে। এতে metadata পড়ার আগে একটি session token নিতে হয়, যা সাধারণ SSRF-এর জন্য কঠিন। Hop limit কম রাখলে container-এর ভেতর থেকেও পৌঁছানো সীমিত হয়। Azure আর Google Cloud-ও বিশেষ header চায়, যাতে সাধারণ অনুরোধ আটকে যায়।
User data-র ক্ষেত্রে আরও একটি কথা। Role-এর credential অন্তত অস্থায়ী, আর নিজে নিজে বদলায়। User data-র password কিন্তু স্থায়ী, আর অনেক সময় বছরের পর বছর একই থাকে। তাছাড়া user data সেই instance-এর সব সাধারণ process-এর হাতের নাগালে থাকতে পারে, তাই একটি দুর্বল library-র মাধ্যমেও তা বেরিয়ে যেতে পারে।
প্রতিরক্ষা তাই স্তরে স্তরে: IMDSv2 বাধ্যতামূলক, role-এ least privilege, app-এ URL যাচাই, outbound traffic-এ সীমা, আর audit log-এ অস্বাভাবিক ব্যবহারের alert.
মূল উপলব্ধি: “কে পৌঁছাতে পারে” আর “কে নিজের ইচ্ছায় পৌঁছাতে পারে” এক কথা নয়। যে জিনিস app পড়তে পারে, app-এর দুর্বলতাও তা পড়তে পারে। তাই secret রাখুন স্বল্পমেয়াদি আর সংকীর্ণ অনুমতিতে।
প্র ০৪Docker আর Kubernetes-এর যুগে machine image কি অপ্রয়োজনীয় হয়ে গেছে?
না, শুধু তার কাজের জায়গা বদলেছে। Container image (পর্ব ৩৬–৩৭) আর machine image একই চিন্তা থেকে আসে: যা চলবে, তা আগে থেকে প্যাক করে নকল করা। পার্থক্য হলো সীমানায়। Container image-এ kernel থাকে না; সে host-এর kernel ব্যবহার করে। Machine image-এ kernel, boot-এর জিনিস আর পুরো OS থাকে।
কিন্তু container কোথায় চলে? শেষ পর্যন্ত একটি VM বা physical machine-এ। Kubernetes-এর প্রতিটি worker node একটি server, যার kernel, container runtime, kubelet আর নিরাপত্তা patch দরকার। Managed Kubernetes-এর সেবাগুলো node-এর জন্য বিশেষ image দেয়, আর node pool upgrade মানে আসলে নতুন image থেকে node বদলানো। অর্থাৎ এই পর্বের rolling replacement সেখানেও চলছে।
Container জনপ্রিয় হওয়ার পর VM image-এ কাজ কমেছে, এটি সত্য। আগে app সহ পুরো image bake করা হতো; এখন app যায় container-এ, আর image-এ থাকে শুধু OS ও runtime. এটি মূলত একটি half-baked নকশা, যেখানে পরিবর্তনের দ্রুত অংশটি অন্য স্তরে সরে গেছে। Launch-এর ধীর অংশ node-এ, আর app-এর গতি container-এ।
একই সঙ্গে node OS-গুলোও আরও ছোট আর immutable হচ্ছে। AWS-এর Bottlerocket, Flatcar বা Fedora CoreOS-এর মতো OS-এ root filesystem প্রায় read-only রাখার চেষ্টা থাকে, আর সেগুলোতে হাতে package বসানো স্বাভাবিক নিয়ম নয়। মানে snowflake হওয়ার সুযোগই কম।
তবে VM সরাসরি এখনো যথেষ্ট কারণে চলে: kernel-ঘনিষ্ঠ workload, লাইসেন্স, শক্ত isolation, পুরোনো app, GPU driver-এর জটিলতা। পর্ব ১৯-এ এই তুলনা আবার আসবে।
মূল উপলব্ধি: Image ধারণাটি এক স্তর ওপরে উঠেছে, হারিয়ে যায়নি। প্রতিটি স্তরে একই প্রশ্ন: কী আগে থেকে প্যাক করব, কী চলার সময় দেব, আর পুরোনোটি কীভাবে বদলাব?
প্র ০৫Image-এর বিশ্বাস দুই দিকের: অন্যের image আপনার ক্ষতি করতে পারে, আবার আপনার image-ও অন্যের হাতে গিয়ে ক্ষতি করতে পারে। কীভাবে?
প্রথম দিকটি হলো অন্যের image নেওয়ার ঝুঁকি। Community image-এ মাঝে মাঝে পুরোনো, অরক্ষিত software পাওয়া যায়। ২০২০ সালে Mitiga নামের একটি নিরাপত্তা প্রতিষ্ঠান জানিয়েছিল, একটি community AMI-তে তারা cryptocurrency mining-এর প্রোগ্রাম পেয়েছে। আর ২০২৫ সালের whoAMI প্রকাশনা দেখিয়েছে, শুধু নাম দিয়ে image খোঁজার অভ্যাসই একটি ঝুঁকি হতে পারে। এর প্রতিকার সরল: বিশ্বস্ত প্রকাশক, owner filter, ID pin, আর নিজের scan.
দ্বিতীয় দিকটি হলো নিজের image ভাগ করার ঝুঁকি। ২০১১ সালের “AmazonIA” গবেষণায় (Bugiel ও সহলেখক, ACM CCS) আর ২০১২ সালের Balduzzi ও সহলেখকদের বিশ্লেষণে দেখা যায়, অনেক public AMI-তে রেখে যাওয়া SSH key, API credential বা shell history পাওয়া গিয়েছিল। প্রকাশকেরা হয়তো খেয়ালই করেননি। মুছে ফেলা ফাইলও সব সময় disk থেকে পুরোপুরি যায় না, কারণ block level-এ তা পড়া যেতে পারে।
একটি golden image-এর ঝুঁকির মাপও বড়। একটি ক্ষতিকর বা ভুল জিনিস image-এ ঢুকলে তা একসাথে সব instance-এ ছড়ায়, মানে এর blast radius পুরো ফ্লিট। সেজন্য image pipeline নিজেই একটি উচ্চ-মূল্যের লক্ষ্য। ২০২৪ সালের xz ঘটনা (Linux-এর একটি compression library-তে লুকানো backdoor) মনে করিয়ে দেয়, base-এ আসা জিনিসও পরীক্ষা ছাড়া নিরাপদ নয়।
করণীয়: pipeline-এর অনুমতি সীমিত রাখুন, build পরিবেশ অস্থায়ী রাখুন, উৎসের তথ্য লিখে রাখুন, আর SLSA-র মতো কাঠামোর ধারণা অনুসরণ করুন (পর্ব ৬১)। Image কখনো ভুল করে public করবেন না; AWS-এ account পর্যায়ে AMI-এর public ভাগ বন্ধ করার নিয়মও আছে। পরীক্ষার ধাপে secret scanning যোগ করা ভালো অভ্যাস।
মূল উপলব্ধি: Image শুধু একটি সুবিধা নয়, একটি সরবরাহ শৃঙ্খলের অংশ। উৎস যাচাই আর প্রকাশের আগে পরিষ্কার করা, দুটোই সমান জরুরি।
অনুশীলন
এগুলোর জন্য কোনো cloud account লাগবে না। কাগজ-কলম আর একটু ভাবনাই যথেষ্ট।
-
হিসাব করুন: একটি bootstrap script-এ ৭টি স্বাধীন ধাপ আছে, প্রতিটির ব্যর্থতার সম্ভাবনা ০.৩%. (ক) ১,৫০০ launch-এ গড়ে কতটি ব্যর্থ হবে? (খ) চাহিদা বাড়ে প্রতি মিনিটে ৩টি instance সমান। Bootstrap-এ প্রস্তুত হতে ৫ মিনিট, half-baked-এ ১.৫ মিনিট লাগে। পূর্ণসংখ্যায় ওপরের দিকে নিয়ে ফাঁকা ক্ষমতার পার্থক্য কত? (গ) প্রতি instance-এর দাম ঘণ্টায় ধরে নেওয়া $০.০৮, মাসে ৭২০ ঘণ্টা হলে মাসিক পার্থক্য কত?
(ক) ব্যর্থতা = ১ − ০.৯৯৭৭ ≈ ০.০২০৮, মানে প্রায় ২.০৮%. ১,৫০০ × ০.০২০৮ ≈ ৩১টি launch.
(খ) Bootstrap: ৩ × ৫ = ১৫টি। Half-baked: ৩ × ১.৫ = ৪.৫, ওপরের দিকে ৫টি। পার্থক্য ১০টি।
(গ) ১০ × ০.০৮ × ৭২০ = মাসে $৫৭৬। Image pipeline-এর খরচ এর চেয়ে কম হলে half-baked লাভজনক। মনে রাখবেন, সংখ্যাগুলো ধরে নেওয়া।
-
ফলাফল অনুমান করুন: একটি Linux instance A-র cloud-config-এ আছে
bootcmd, যা/data/logফাইলে একটি লাইনBযোগ করে, আরruncmd, যা একটি লাইনRযোগ করে। ঘটনার ক্রম: A প্রথমবার চালু হলো → reboot → stop করে আবার start (ID একই)। তারপর reboot ছাড়াই, cloud-init পরিষ্কার না করে, A-র disk থেকে image বানানো হলো, আর সেই image থেকে একই user data দিয়ে নতুন instance C চালু হলো। A আর C-তে/data/log-এ লাইনের ক্রম কী?A:
B R B B. প্রথম boot-এ দুটিই, তারপর reboot আর start-এ শুধুbootcmd.C:
B R B B B R. Disk-এর ফাইলটি নকল হয়ে এসেছে, তাই আগের চারটি লাইন আছে। C-র instance ID নতুন, তাই per-instance কাজ আবার চলেছে।দুটি শিক্ষা: image-এ পুরোনো log ও state চলে আসে, আর per-instance মানে “এই ID-তে একবার”, “এই disk-এ একবার” নয়। তাই script idempotent হওয়া দরকার।
-
সমালোচনা করুন: নিচের user data production-এর autoscaling-এর জন্য লেখা হয়েছে। অন্তত ৫টি সমস্যা ধরুন, আর ভালো নকশা প্রস্তাব করুন।
#cloud-config package_update: true package_upgrade: true runcmd: - curl -s http://203.0.113.10/install.sh | bash - echo "DB_PASSWORD=Sample-Not-Real-123" >> /etc/shop.env - chmod 777 /etc/shop.env - systemctl restart shop- Secret: Password user data-তে, তাই metadata, log আর template-এ দেখা যাবে। Secret manager আর instance role ব্যবহার করুন।
chmod 777: সবাই ফাইলটি পড়তে ও লিখতে পারবে।0600আর নির্দিষ্ট owner দিন।curl | bashover HTTP: Encrypted নয়, যাচাই নেই, version নেই। Artifact store থেকে নির্দিষ্ট version আর checksum মিলিয়ে নিন, অথবা image-এ bake করুন।package_upgrade: Boot ধীর হয়, আর প্রতিটি instance আলাদা হতে পারে। Patch image-এ যাবে।- যাচাই নেই: এক লাইন ব্যর্থ হলেও পরেরটি চলবে। Health check আর ব্যর্থ boot-এর alert দরকার।
- নির্ভরতা: একটি IP-র ওপর পুরো scale-out দাঁড়িয়ে। সেটি বন্ধ হলে নতুন server আসবে না।
ভালো নকশা: Golden বা half-baked image, নির্দিষ্ট ID, ছোট user data যাতে শুধু environment আর version থাকবে, আর চলার সময় secret manager থেকে পড়া।
-
কমান্ড লিখুন: একটি build pipeline-এ নতুন image-এর পরীক্ষার instance-এর ভেতরে চালানোর জন্য ছোট shell অংশ লিখুন। এটি cloud-init শেষ হওয়া পর্যন্ত অপেক্ষা করবে, ব্যর্থ হলে শেষ ২০ লাইন log দেখিয়ে থামবে, আর সফল হলে
http://127.0.0.1:8080/healthzযাচাই করবে। ৪০টি instance-এর ফ্লিটে ২৫% ব্যাচে, প্রতি ব্যাচ ৬ মিনিটে, এরপর পুরো rollout কতক্ষণ নেবে?set -euo pipefail if ! cloud-init status --wait; then sudo tail -n 20 /var/log/cloud-init-output.log exit 1 fi curl -fsS http://127.0.0.1:8080/healthzcurl -fHTTP error-এ non-zero exit দেয়, আরset -eতখন script থামায়। Pipeline এই exit code দেখেই image প্রকাশ বাতিল করবে।Rollout: ৪০-এর ২৫% = ১০টি প্রতি ব্যাচে, মোট ৪টি ব্যাচ। ৪ × ৬ = ২৪ মিনিট।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমএকটি নতুন Linux cloud instance-এর boot-এর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- Firmware থেকে kernel পর্যন্ত boot
- Local: datasource খোঁজা, network-এর config লেখা
- Network: user data পড়া,
write_files, hostname, SSH key - Config: সময়, locale, package-এর উৎস
- Final: package install আর
runcmdচালানো - Load balancer-এর health check সফল
একটি cloud-init চালিত instance reboot করা হলো, instance ID বদলায়নি। ডিফল্ট আচরণে আবার কোনটি চলবে?
- শুধু
runcmd - শুধু
bootcmd bootcmd,runcmdআরpackagesসবই- কোনোটিই নয়
একটি দল user data-তে database password রাখতে চায়, যুক্তি: base64 করা আছে। সবচেয়ে ভালো জবাব কোনটি?
- Base64 যথেষ্ট, কারণ সাধারণ চোখে পড়া যায় না
- Password image-এ bake করা ভালো
- User data-তে শুধু secret-এর নাম রেখে, instance role দিয়ে secret manager থেকে পড়া উচিত
- User data ঠিক আছে, শুধু cloud-init-এর log বন্ধ করলেই হয়
একটি launch template-এর ডিফল্ট version-এ নতুন image বসানো হলো। ১০টি চলমান instance-এর কী হবে?
- কিছুই হবে না; আলাদা rollout না করলে পুরোনো image-এই চলবে
- সবগুলো নিজে থেকে reboot হয়ে নতুন image নেবে
- চলমান disk-এ নতুন ফাইলগুলো copy হয়ে যাবে
- পুরোনো ১০টি সাথে সাথে বন্ধ হয়ে যাবে
একটি bootstrap-এ ৫টি স্বাধীন ধাপ আছে, প্রতিটিতে ব্যর্থতার সম্ভাবনা ১%. একটি launch ব্যর্থ হওয়ার সম্ভাবনা প্রায় কত?
- ১%
- ০.০১%
- ১০%
- প্রায় ৪.৯%
একটি deployment script শুধু “ubuntu-24.04-*” নামের ধরন দিয়ে সবচেয়ে নতুন public image বেছে নেয়। প্রধান ঝুঁকি কী?
- Boot একটু ধীর হতে পারে
- একই নামের অচেনা প্রকাশকের image চলে যেতে পারে
- অন্য region-এ এটি কখনো চলবে না
- SSH key দেওয়া যাবে না
Package mirror বন্ধ থাকায় user data-র install ব্যর্থ হলো। তবু cloud console-এ instance “running” দেখাচ্ছে। কেন?
- Console-এর তথ্য সবসময় ভুল
- cloud-init ব্যর্থ হলে নিজে থেকে আবার চলতে থাকে
- “running” শুধু VM-এর অবস্থা বলে, app প্রস্তুত কি না তা বলে না
- Provider ধরে নিয়েছে install সফল হয়েছে, কারণ user data সঠিক ছিল
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- হাতে বানানো server snowflake হয়ে যায়। জ্ঞান রাখুন নকশায়, মানুষের মাথায় নয়।
- Image সবার জন্য এক ছাঁচ; user data প্রতি launch-এর নির্দেশ। বিশ্বাস করুন প্রকাশককে, নামকে নয়।
- cloud-init-এর ক্রম: Local → Network → Config → Final.
bootcmdপ্রতি boot-এ,runcmdপ্রতি instance-এ একবার। - যা ধীর আর কম বদলায় তা bake করুন; যা environment-ভেদে আলাদা তা boot-এ দিন; secret কখনোই নয়, role দিয়ে পড়ুন।
- Image-এ version দিন, pipeline-এ বানান, template বদলের পর rollout করুন, আর পুরোনো image অবসরে পাঠান।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ১৭ · Autoscaling — scaling policy, health check আর instance groupপরবর্তী পর্বLaunch template দিয়ে নিজে নিজে ক্ষমতা বাড়ানো ও কমানো।
- ক্লাউড কম্পিউটিং ও DevOps · কোর্স হোম৮১টি পর্বপুরো কোর্সের রোডম্যাপ।
- পর্ব ১০ · Bash automationআবার দেখুননিরাপদ script আর idempotent কাজের অভ্যাস।
- Operating Systems · Virtual machineগভীরে যানHypervisor আর virtual disk ভেতরে কীভাবে কাজ করে।
- System Design · Deployment আর releaseপাশের ট্র্যাকনিরাপদে নতুন version ছাড়ার নকশা।
- Software Engineering · Continuous delivery আর DevOpsপাশের ট্র্যাকএকবার build করে ধাপে ধাপে ছাড়ার ধারণা।