VPS snapshot, backup ও clone-এর পার্থক্য কী
Snapshot provider-এর infrastructure-এ থাকে, তাই এটি backup নয়। কোনটি কী restore করে এবং cloned VPS চালুর আগে identity ও network কীভাবে ঠিক করবেন, তা জানুন।
Snapshot, backup এবং clone আসলে কী
একটি VPS snapshot হলো আপনার server-এর disk image, যা আপনার provider তাদের infrastructure-এ, আপনার account-এর মধ্যে সংরক্ষণ করে। Backup হলো আপনার data-এর একটি স্বাধীন copy, যা মূল copy সংরক্ষণকারী provider-এর সহায়তা ছাড়াই অন্য কোথাও restore করতে পারেন। Clone হলো snapshot থেকে তৈরি একটি নতুন instance। তাই এটি শুরুতেই মূল instance-এর identity-সহ হুবহু copy হিসেবে চালু হয়।
এগুলো ভিন্ন সমস্যার সমাধান করে। Snapshot কয়েক মিনিটের মধ্যে ব্যর্থ upgrade আগের অবস্থায় ফিরিয়ে নিতে পারে, কিন্তু account বন্ধ হয়ে গেলে এটি কোনো কাজে আসে না। Backup provider বন্ধ হয়ে গেলেও টিকে থাকে, তবে restore করতে বেশি সময় লাগে, কারণ আগে machine পুনর্নির্মাণ করতে হয়। Clone এক ধাপে একটি দ্বিতীয় running server তৈরি করে। তবে এর ফলে এমন দুটি machine তৈরি হয়, যেগুলো নিজেদের একই machine বলে মনে করে।
কেন VPS snapshot backup নয়
সমস্যাটি image-এর মান নয়; failure domain। snapshot আপনার provider-এর storage platform-এ থাকে। সাধারণত এটি সেই একই region-এ থাকে, যেখান থেকে server তৈরি হয়েছে। এটি সবসময় একই account-এর অধীনেও থাকে। একটি ঘটনায় server এবং তার snapshot দুটিই একসঙ্গে হারিয়ে যেতে পারে।
- Account suspend হতে পারে, payment ব্যর্থ হতে পারে, অথবা কেউ login চুরি করতে পারে।
- API access থাকা কোনো ব্যক্তি বা script instance মুছে দিতে পারে। অনেক provider-এর ক্ষেত্রে instance মুছে ফেললে তার snapshot-ও মুছে যায়। অন্য কিছু ধরে নেওয়ার আগে আপনার provider-এর documented behaviour পড়ুন।
- Region-এ বড় ধরনের সমস্যা হলে সেখানকার সবকিছু একসঙ্গে unreachable হয়ে যেতে পারে।
- Server-এ root হিসেবে চলা কোনো কিছু
/root-এ রাখা provider API token খুঁজে পেতে পারে এবং disk-এ হাত দেওয়ার আগে snapshot-গুলো মুছে দিতে পারে।
Backup হলো এমন copy, যা এই চারটি পরিস্থিতির পরেও টিকে থাকে। পরীক্ষা করার জন্য একটি প্রশ্ন করুন: আজ বিকেলে আপনার provider account আর না থাকলে আপনি কী restore করতে পারতেন, এবং কোথায় restore করতেন? যে কোনো copy এই প্রশ্নে ব্যর্থ হলে সেটি rollback tool, backup নয়। Snapshot নেওয়া চালিয়ে যান, কারণ কোনো কিছুই এর চেয়ে দ্রুত restore হয় না। এরপর provider-এর নিয়ন্ত্রণের বাইরে থাকা storage-এ একটি দ্বিতীয় copy রাখুন।
পুরোনো নিয়মটি এখনও প্রযোজ্য: data-এর তিনটি copy, দুই ধরনের storage-এ, যার একটি platform-এর বাইরে। একটি provider snapshot এবং আলাদা infrastructure-এ restic backup repository—এই দুইটি moving part দিয়ে সেই নিয়ম পূরণ করা যায়।
চলমান database-এর snapshot কেন নষ্ট অবস্থায় restore হতে পারে
একটি provider snapshot একটি নির্দিষ্ট মুহূর্তে block device-এর বর্তমান অবস্থা কপি করে। এটি আগে আপনার application-গুলোকে থামতে বলে না এবং page cache-এ থাকা কোনো data দেখতে পারে না। তাই সর্বোচ্চ যা পাওয়া যায়, তা হলো crash-consistent image। বিদ্যুৎ cable খুলে দিলে disk-এর যে অবস্থা হতো, image-টি ঠিক সেই অবস্থার মতো দেখায়।
Stack-এর বেশিরভাগ অংশ এটি সামলে নেয়। ext4 এবং XFS mount হওয়ার সময় journal replay করে, তাই filesystem চালু হয়। PostgreSQL start হওয়ার সময় তার write-ahead log replay করে, এবং log-এ তা দেখা যায়:
LOG: database system was not properly shut down; automatic recovery in progressInnoDB-ও একই কাজ করে এবং startup-এর সময় নিজস্ব crash recovery line লিখে। এই recovery database-এর প্রত্যাশিত আচরণের অংশ। তাই একটি শান্ত PostgreSQL বা MySQL-এর single-volume snapshot সাধারণত ঠিকভাবে restore হয়।
যেসব ক্ষেত্রে crash-consistent যথেষ্ট নয়, সেগুলো বাস্তব এবং গুরুতর। আপনার data যদি দুইটি volume-এ থাকে, তাহলে root disk এবং আলাদা data disk ভিন্ন সময়ে snapshot হয়। ফলে data file এবং log directory-এর অবস্থা মিল নাও থাকতে পারে, এবং recovery করার মতো সঠিক কিছু থাকে না। কোনো application fsync না ডেকে file লিখলে, যেমন অর্ধেক পাওয়া upload বা queue file, সেটি truncated অবস্থায় ফিরে আসতে পারে। Application memory-তে ধরে রাখা এবং নির্দিষ্ট সময় পর flush করা কোনো data image-এ থাকেই না।
তাই snapshot নেওয়ার আগে disk-এ একটি dump লিখুন। এতে image-এর মধ্যে এমন একটি file থাকবে, যার অভ্যন্তরীণ সামঞ্জস্য আপনি নিশ্চিত করতে পারেন, live data file-গুলোর অবস্থা যাই হোক না কেন।
sudo -u postgres pg_dumpall --clean --file=/var/backups/pg-$(date +%F).sql
sudo mysqldump --single-transaction --routines --all-databases > /var/backups/mysql-$(date +%F).sql--single-transaction writer-দের block না করে InnoDB table-এর consistent dump তৈরি করে, কারণ dump-টি একটি repeatable-read transaction-এর মধ্যে চলে। এটি MyISAM table অন্তর্ভুক্ত করে না; এসব table-এর জন্য lock দিতে হবে অথবা server থামাতে হবে। Dump-টি নির্ভরযোগ্য ধরে নেওয়ার আগে সেটি empty বা truncated কি না পরীক্ষা করুন: সম্পূর্ণ mysqldump-এর শেষে tail -n 1 /var/backups/mysql-$(date +%F).sql একটি Dump completed comment থাকে।
আলাদা data volume থাকলে snapshot নেওয়ার জন্য প্রয়োজনীয় কয়েক সেকেন্ড সেটি freeze করতে পারেন:
sudo fsfreeze -f /srv
# take the snapshot from your provider's panel or API
sudo fsfreeze -u /srvশুধু data volume freeze করুন। কখনোই / freeze করবেন না। Frozen root filesystem পুরো machine-এর প্রতিটি write block করে, সেই shell-ও যার মাধ্যমে unfreeze command লিখতেন। ফলে আপনি নিজেকেই system থেকে বিচ্ছিন্ন করে ফেলবেন এবং hard reset-এর জন্য অপেক্ষা করতে হবে।
অফসাইট অংশ: restic অথবা Borg
Snapshot হলো দ্রুত অংশ। Offsite copy হলো আপনার provider টিকে গেলেও যে অংশটি থাকবে। restic একটি ভালো default, কারণ এটি deduplication করে, client side-এ encryption করে এবং S3-compatible object storage, SFTP অথবা সাধারণ directory-তে লেখে। offsite target হিসেবে storage VPS এখানে ভালোভাবে কাজ করে, কারণ backup repository-এর IOPS-এর চেয়ে capacity বেশি প্রয়োজন।
sudo apt update && sudo apt install -y restic
sudo sh -c 'umask 077; head -c 24 /dev/urandom | base64 > /root/.restic-pass'
sudo chmod 600 /root/.restic-pass
sudo cat /root/.restic-passএই passphrase এখনই একটি password manager-এ কপি করুন, এমন একটি device-এ যা এই server নয়। এটি ছাড়া restic repository খোলা যায় না এবং recovery-এর কোনো পথ নেই। আপনি যে server হারিয়েছেন, সেখানে password-এর একমাত্র copy থাকলে backup কেবল encrypted noise হয়ে থাকবে।
export RESTIC_REPOSITORY="s3:https://s3.example.com/vps-backups"
export RESTIC_PASSWORD_FILE=/root/.restic-pass
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
sudo -E restic init
sudo -E restic backup /etc /srv /var/backups
sudo -E restic snapshotssudo -E এই variable-গুলো সংরক্ষণ করে, কারণ এটি না থাকলে root একটি clean environment পায় এবং restic জানায় যে কোনো repository location নির্দিষ্ট করা হয়নি। restic snapshots-এ আপনার এইমাত্র চালানো run-টি, host ও path-সহ তালিকাভুক্ত হওয়া উচিত। নির্দিষ্ট schedule অনুযায়ী repository নিজেই verify করুন এবং শুধু structure পরীক্ষা না করে কিছু data পড়ে দেখুন:
sudo -E restic check --read-data-subset=5%
sudo -E restic restore latest --target /tmp/restore-check
sudo -E restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --pruneপরীক্ষা না করা backup কেবল একটি অনুমান। অন্তত একবার অন্য একটি VPS-এ restore করুন, এতে কত সময় লাগে তা মাপুন এবং সময়টি লিখে রাখুন, কারণ এই সংখ্যাটিই আপনার প্রকৃত recovery target। Borg-ও একটি নির্ভরযোগ্য বিকল্প এবং object storage-এর বদলে SSH-এর মাধ্যমে repository সংরক্ষণ করে; trade-off-গুলো restic ও BorgBackup-এর তুলনা-এ ব্যাখ্যা করা হয়েছে।
Production-এ ব্যবহারের আগে cloned VPS-এ যা ঠিক করতে হবে
Clone হলো হুবহু replica। এটাই এর মূল সুবিধা এবং সমস্যাও। Original-কে স্বতন্ত্র করে এমন সবকিছু duplicate হয়, আর duplicate-গুলোর মধ্যে সংঘাত তৈরি হয়।
SSH host key পুনরায় তৈরি করুন। Clone-এ original-এর /etc/ssh/ssh_host_* file থাকে, তাই দুটি server একই host identity উপস্থাপন করে। যে ব্যক্তি একটির নিয়ন্ত্রণ নিতে পারে, সে সেই key গ্রহণ করা প্রতিটি client-এর কাছে অন্য server সেজে থাকতে পারে। SSH কোনো warning দেখায় না, কারণ client যে key প্রত্যাশা করেছিল, এটিই সেই key।
sudo rm -f /etc/ssh/ssh_host_*
sudo ssh-keygen -A
sudo systemctl restart ssh
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubssh-keygen -A daemon-এর প্রত্যাশিত প্রতিটি type-এর জন্য নতুন key লেখে। শেষ command-এর fingerprint অবশ্যই original-এর fingerprint থেকে আলাদা হতে হবে। বর্তমান session restart-এর পরও চালু থাকে, কারণ sshd restart করলে প্রতিষ্ঠিত connection বন্ধ হয় না। কেউ clone-এ connect করার আগে এটি করুন। পরে করলে, ইতিমধ্যে উত্তরাধিকারসূত্রে পাওয়া key-তে trust করা প্রতিটি client WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! পাবে এবং প্রথমে ssh-keygen -R <host> চালাতে হবে।
Machine ID reset করুন। /etc/machine-id হলো একটি unique identifier, যা systemd প্রথম boot-এ একবার generate করে এবং clone সেটিই পায়।
sudo truncate -s 0 /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id
sudo ln -s /etc/machine-id /var/lib/dbus/machine-id
sudo rebootখালি /etc/machine-id systemd-কে পরবর্তী boot-এ নতুন value generate করতে বলে। তাই file-টি delete না করে truncate করুন। এটি duplicate থাকলে দুটি সমস্যা হয়। যেসব image DHCP-এর মাধ্যমে address পায়, সেগুলোতে systemd-networkd default হিসেবে machine ID থেকে DHCP client identifier তৈরি করে। ফলে দুই clone একই client হিসেবে lease চায় এবং server তাদের একই address দেয়। এছাড়া journald প্রতিটি entry-তে machine ID যোগ করে, তাই central log collector দুই server-এর log-ই একটি machine-এর অধীনে রাখে। reboot-এর পরে cat /etc/machine-id চালিয়ে value পরিবর্তিত হয়েছে কি না নিশ্চিত করুন।
Hostname পরিবর্তন করুন।
sudo hostnamectl set-hostname web-02
grep 127.0.1.1 /etc/hostshostnamectl /etc/hostname লেখে এবং name তাৎক্ষণিকভাবে প্রয়োগ করে। এটি /etc/hosts পরিবর্তন করে না, তাই 127.0.1.1 line-টি সম্পাদনা করে hostname-এর সঙ্গে মিলিয়ে নিন। এটি না করলে নতুন name কোথাও resolve হবে না। ফলে প্রতিটি sudo call ব্যর্থ lookup-এর জন্য অপেক্ষা করবে এবং sudo: unable to resolve host web-02: Name or service not known দেখাবে।
Image-এ অন্তর্ভুক্ত প্রতিটি credential পরিবর্তন করুন। Clone-এ original-এর secret থাকে, তাই এখন দুটি machine original-এর মতো কাজ করতে পারে। SSH authorized_keys file, provider ও DNS API token, application .env file, database password, TLS private key, monitoring enrolment token এবং restic repository password পরীক্ষা করুন। এগুলোর অধিকাংশ এভাবে খুঁজে পাওয়া যায়:
sudo grep -rIlE 'PASSWORD|SECRET|TOKEN|API_KEY' /etc /srv /opt /home 2>/dev/null
sudo find / -name '.env' -not -path '/proc/*' -not -path '/sys/*' 2>/dev/nullClone যদি এমন test copy হয় যা কখনও traffic serve করবে না, তাহলে credential rotate না করে revoke করুন। Live production API token থাকা staging box দুর্বল patching-সহ একটি production box-এরই সমতুল্য।
এখন duplicate হয়ে চলা job বন্ধ করুন। একই crontab-সহ দুটি server একই minute-এ একই external system-এ request পাঠায়।
systemctl list-timers --all
sudo crontab -l
sudo ls -l /etc/cron.d /etc/cron.dailyrestic-এর বিষয়টি বিস্তারিতভাবে বোঝা দরকার, কারণ এটি শুধু স্পষ্টভাবে ব্যর্থ হয় না; retention-ও নষ্ট করে। restic প্রতিটি snapshot-এ host name tag করে এবং restic forget --keep-daily 7 প্রতি host অনুযায়ী policy প্রয়োগ করে। একই host name জানানো দুটি machine-কে একটি host হিসেবে ধরা হয়। তাই সাতটি "daily" snapshot clone থেকে আসতে পারে, আর original-এর snapshot prune হয়ে যেতে পারে। প্রথম backup run-এর আগেই hostname ঠিক করুন, অথবা clone-এ timer বন্ধ করুন। certbot-এর ক্ষেত্রে বিষয়টি সহজ: একই name renew করতে থাকা দুটি server certificate authority-এর duplicate certificate rate limit-এ পৌঁছায়, এবং যে run হেরে যায় সেটি ওই নির্দিষ্ট name set-এর জন্য ইতিমধ্যে অতিরিক্ত certificate issue হয়েছে—এমন error দেখিয়ে ব্যর্থ হয়। যে clone-এর domain এখনও original-এর দিকে নির্দেশ করে, সেটি HTTP challenge-ও পাস করতে পারে না। তাই সেখানে renewal বন্ধ করুন।
Monitoring agent-এর ব্যবস্থা নিন। অধিকাংশ agent hostname অথবা install-এর সময় লেখা ID file দিয়ে identify করে। তাই একটি host হিসেবে report করা দুটি agent তাদের metric একই series-এ interleave করে। ফলে CPU graph-এ এমন value দেখা যায় যা কোনো একক machine তৈরি করেনি এবং alert বারবার flap করে। Clone-এ agent বন্ধ করে remove করুন, অথবা vendor-এর documented procedure অনুসরণ করে নতুন hostname-এর অধীনে পুনরায় enrol করুন।
Original-এর address-এর জন্য network configuration পরীক্ষা করুন। Image-এ netplan-এর static address থাকলে clone অন্য machine-এর জন্য বরাদ্দ IP claim করবে।
ip -br addr
sudo grep -r addresses /etc/netplan/এই clone template হলে cloud-init state পরিষ্কার করুন।
sudo cloud-init clean --logsএটি /var/lib/cloud-এর অধীনে থাকা cloud-init state সরিয়ে দেয়। ফলে পরবর্তী boot-এ first-boot module আবার চলে। এর মধ্যে কোনো SSH host key না থাকলে নতুন SSH host key তৈরি করাও অন্তর্ভুক্ত। কিছু version machine ID reset করার জন্য একটি flag-ও দেয়। অন্য কোথাও পাওয়া flag list-এর ওপর নির্ভর না করে আপনার নিজের image-এ cloud-init clean --help চালিয়ে সেটি কী সমর্থন করে তা দেখুন।
কখন কোনটি ব্যবহার করবেন
ঝুঁকিপূর্ণ upgrade ফিরিয়ে নিতে: snapshot নিন। পরিবর্তন করার কয়েক মিনিট আগে snapshot নিন, upgrade চালান, এবং সমস্যা হলে image restore করুন। Restore করলে snapshot নেওয়ার পরের সব write বাতিল হয়ে যায়। তাই live traffic গ্রহণকারী server-এ আগে database dump করুন এবং ঠিক কোন সময়সীমার পরিবর্তন হারাবেন তা জেনে নিন। এমন একটি do-release-upgrade-এর ক্ষেত্রে, যেটিকে দশ মিনিট offline রাখা যায়, snapshot-ই সম্পূর্ণ পরিকল্পনা হতে পারে।
বড় plan-এ migrate করতে: clone deploy করুন। snapshot থেকে বড় plan-এ clone তৈরি করুন। উপরের identity তালিকা অনুযায়ী সবকিছু পরীক্ষা করুন। এরপর কোনো traffic সরানোর আগে clone-টিকে নিজস্ব IP-তে পরীক্ষা করুন। Cutover দ্রুত করতে এক দিন আগে DNS TTL কমিয়ে দিন। নতুন server বাস্তব traffic সামলানোর পরও original server চালু রাখুন। আগে নিশ্চিত করুন যে বড় plan আপনার workload-এর জন্য সত্যিই দ্রুততর। এজন্য উভয় server-এ একই benchmark পদ্ধতি ব্যবহার করুন, কারণ বেশি ব্যস্ত hardware-এ বেশি vCPU থাকলেই তা সবসময় upgrade হয় না।
Template তৈরি করতে: পরিষ্কার machine-এর snapshot নিন। একটি server install ও harden করুন। Image তৈরি করার আগে machine-টির সঙ্গে নির্দিষ্ট সবকিছু সরিয়ে ফেলুন। কোনো host key রাখবেন না। machine ID খালি রাখুন। ব্যক্তিগত কোনো authorized_keys রাখবেন না। কোনো credential রাখবেন না। cloud-init পরিষ্কার করুন। এরপর snapshot নিন। এটি থেকে deploy করা প্রতিটি instance প্রথম boot-এর সময় নিজস্ব identity তৈরি করবে। ফলে উপরের checklist আর checklist হিসেবে অনুসরণ করতে হবে না। এটিকে নতুন VPS-এ প্রথম দশ মিনিটের standard কাজের সঙ্গে যুক্ত করুন, যাতে template-এ এমন কাজ আগে থেকেই থাকে যা অন্যথায় প্রতিবার পুনরাবৃত্তি করতে হতো।
FAQ
VPS snapshot কি backup?
না, কারণ এটি যে server থেকে তৈরি হয়েছে, তার সঙ্গেই একই failure domain ভাগ করে। Snapshot আপনার provider-এর storage-এ, আপনার account-এর মধ্যে, সাধারণত একই region-এ থাকে। Account suspension, চুরি হওয়া API key বা ভুল করে instance মুছে ফেলার কারণে server এবং তার snapshot-গুলো একবারেই মুছে যেতে পারে। অনেক provider-এর ক্ষেত্রে instance মুছে ফেললে নকশাগতভাবেই তার snapshot-গুলোও মুছে যায়। Snapshot হলো আপনার কাছে থাকা দ্রুততম rollback ব্যবস্থা। তাই snapshot নেওয়া চালিয়ে যান এবং provider-এর নিয়ন্ত্রণের বাইরে থাকা infrastructure-এ দ্বিতীয় একটি encrypted copy রাখুন।
Snapshot নেওয়ার আগে কি database বন্ধ করতে হবে?
সবসময় নয়, তবে snapshot থেকে আপনি কী পাবেন তা মেনে নিতে হবে। Provider snapshot crash-consistent হয়। অর্থাৎ, power cut-এর পরে disk যেমন দেখাত, image-টি তার সঙ্গে সামঞ্জস্যপূর্ণ থাকে। PostgreSQL এবং InnoDB start হওয়ার সময় এই অবস্থা থেকে recovery করতে পারে। PostgreSQL সেই সময় database system was not properly shut down; automatic recovery in progress log করে। তবে ভিন্ন সময়ে snapshot নেওয়া দুটি volume-এ data ছড়িয়ে থাকলে recovery নিশ্চিত নয়। fsync ছাড়া কোনো application লিখলেও recovery নিশ্চিত নয়। আগে disk-এ একটি pg_dumpall অথবা mysqldump --single-transaction লিখুন, যাতে image-এ এমন একটি file থাকে যার consistency আপনি নিশ্চিতভাবে জানেন।
দুটি cloned server একই IP address নিয়ে কেন সংঘর্ষে জড়ায়?
কারণ তারা একই /etc/machine-id share করে। DHCP ব্যবহার করা image-এ systemd-networkd ডিফল্টভাবে machine ID থেকে DHCP client identifier তৈরি করে। ফলে উভয় clone একই client হিসেবে lease চায় এবং DHCP server উভয়কেই একই address দেয়। /etc/machine-id-কে zero bytes-এ truncate করুন, /var/lib/dbus/machine-id সরিয়ে ফেলুন, সেটিকে আবার /etc/machine-id-এ symlink করুন এবং reboot করুন, যাতে systemd নতুন value তৈরি করে। আরেকটি সাধারণ কারণ হলো /etc/netplan/-এ লেখা static address, যা clone হুবহু copy করেছে। ip -br addr দিয়ে পরীক্ষা করুন।
কোনো clone production-এ ব্যবহারের জন্য নিরাপদ কি না দ্রুততম উপায়ে কীভাবে পরীক্ষা করব?
Original server-এর সঙ্গে চারটি বিষয় তুলনা করুন। উভয় server-এ ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub চালিয়ে নিশ্চিত করুন যে fingerprint আলাদা। উভয় server-এ cat /etc/machine-id চালিয়ে নিশ্চিত করুন যে value আলাদা। hostnamectl status চালিয়ে নিশ্চিত করুন যে name নতুন এবং resolve হয়, যাতে sudo warning না দেয়। এরপর systemctl list-timers --all চালান এবং shared system-এর সঙ্গে যোগাযোগ করে এমন প্রতিটি timer বন্ধ রাখুন। এর মধ্যে backup, certificate renewal বা monitoring agent থাকতে পারে। কোন machine সেই কাজের মালিক হবে তা নির্ধারণ না করা পর্যন্ত timer-গুলো বন্ধ রাখুন।