SSD Nodes Learn 🎉 VPS $5.50/মাস থেকে
নির্দেশিকা Matt Connorদ্বারা Matt Connor

ক্লোন করা VPS-এ duplicate machine-id ঠিক করার উপায়

ক্লোন করা VPS-এ একই /etc/machine-id থাকলে DHCP lease নিয়ে সংঘাত হতে পারে। নিরাপদে regenerate করুন, golden image snapshot-এর আগে file-টি খালি রাখুন।

/etc/machine-id কী এবং এর ডুপ্লিকেট কেন গুরুত্বপূর্ণ

ক্লোন করা VPS একই /etc/machine-id নিয়ে boot হয়, যা যে server থেকে ক্লোন করা হয়েছে তারও একই থাকে। অথচ এই মানটি ঠিক একটি installation-এর জন্য নির্দিষ্ট থাকার কথা। সমাধানটি চারটি command-এ করা যায়: file-টি খালি করুন, এটি সত্যিকারের file হলে D-Bus-এর copy মুছে দিন, নতুন মান তৈরি করুন, তারপর reboot করুন। অনেকেই reboot ধাপটি বাদ দেন। কিন্তু পরিবর্তন কার্যকর করার জন্য এই ধাপটিই প্রয়োজন।

/etc/machine-id-এ newline দিয়ে শেষ হওয়া lowercase 32-character hexadecimal string থাকে। Decode করলে এটি 16-byte (128-bit) মান। machine-id(5) manual page এটিকে confidential বলেছে এবং network-এ প্রকাশ না করতে নির্দেশ দিয়েছে, কারণ এটি পড়তে পারে এমন যেকোনো কিছু পরে আবার আপনার machine শনাক্ত করতে পারবে। System install করার সময় এটি একবার লেখা হয়। এরপর আর কিছু এটি পরিবর্তন করে না।

এখানে তিনটি identifier-কে প্রায়ই গুলিয়ে ফেলা হয়। তাই এগুলো আলাদা করে দেখা দরকার। Hostname হলো আপনার নির্ধারিত একটি label, যা আপনি যেকোনো সময় পরিবর্তন করতে পারেন। /sys/class/dmi/id/product_uuid-এর DMI (desktop management interface) product UUID hypervisor থেকে আসে এবং এটি শুধু root পড়তে পারে। Machine ID হলো তৃতীয়টি: operating system এটি তৈরি করে, এবং system-এর প্রত্যেক user এটি পড়তে পারে।

আসলে machine ID কোন কোন উপাদান পড়ে

DHCP client identifier। সমস্যার মূল এখানেই। systemd.network(5)-এর [DHCPv4] section-এ ClientIdentifier=-এর default হিসেবে duid উল্লেখ করা হয়েছে। এটি IAID এবং DUID (DHCP unique identifier) থেকে তৈরি একটি RFC 4361 client ID পাঠায়। networkd.conf(5)-এ default DUID type হিসেবে vendor উল্লেখ করা হয়েছে। এই ক্ষেত্রে DUID value তৈরি হয় 43793 vendor identifier (systemd) এবং machine ID-এর hash করা contents ব্যবহার করে। DHCPv6-ও একই DUID ব্যবহার করে। একই machine ID থাকা দুটি clone একই DUID তৈরি করে। তাদের interface name-ও একই থাকলে তারা byte-identical client identifier পাঠায়। ফলে DHCP server দুটি client-এর বদলে একটি client দেখতে পায় এবং উভয় server-কে একই lease দেয়। এর লক্ষণ হলো একটি server থেকে অন্য server-এ address চলে যাওয়া, অথবা অন্য server renew করলেই একটি server তার address হারানো।

journald। Journal file-গুলো /var/log/journal/<machine-id>/-এ থাকে। Directory-টির নাম সরাসরি ID থেকে নেওয়া হয়। দুটি clone-এর journal একই collector-এ পাঠালে সেগুলো একই directory-তে জমা হয় এবং একটি host হিসেবে পড়া হয়।

D-Bus। /var/lib/dbus/machine-id-এই file format-এর শুরু হয়েছিল। Debian ও Ubuntu-তে এটি /etc/machine-id-এর একটি symlink। কিছু system-এ এটি নিজস্ব copy-সহ একটি আলাদা প্রকৃত file। নিচের procedure-এ এই copy-টিই সমস্যা তৈরি করে।

Per-host agent। Monitoring agent, licence check, inventory tool এবং backup client প্রায়ই machine ID-কে default host identifier হিসেবে ব্যবহার করে। কারণ এটি স্থিতিশীল এবং কোনো configuration প্রয়োজন হয় না। দুটি server একই identity দিয়ে report করলে metrics-এর একটি merged series তৈরি হয়, অথবা একটি licence seat দুইটি machine-এর জন্য ব্যবহৃত হয়। আপনার agent কীভাবে host ID তৈরি করে তা পরীক্ষা করুন। এটি hostname ব্যবহার করে ধরে নেবেন না।

ডুপ্লিকেট আছে কি না কীভাবে বুঝবেন

উভয় সার্ভারে এটি চালিয়ে আউটপুট তুলনা করুন।

cat /etc/machine-id
ls -l /var/lib/dbus/machine-id
sudo cat /sys/class/dmi/id/product_uuid

দুটি সক্রিয় সার্ভারে অভিন্ন machine ID থাকলে একটি অন্যটি থেকে clone করা হয়েছে। আপনি যদি একটি কমান্ডেই কাজটি করতে চান, তাহলে hostnamectl তার Machine ID: লাইনে একই মান দেখায়।

পরবর্তী পদক্ষেপ ls -l-এর ফলের ওপর নির্ভর করে। একটি symlink দেখতে এমন হয়:

lrwxrwxrwx 1 root root 15 Aug 21 09:12 /var/lib/dbus/machine-id -> /etc/machine-id

-rw-r--r-- দিয়ে শুরু হওয়া লাইনটি বোঝায় যে এটি একটি প্রকৃত file, যেখানে পুরোনো ID-এর নিজস্ব copy রয়েছে। এটি সরাতে হবে, কারণ systemd-machine-id-setup অন্য কিছু করার আগে এই file পড়ে।

product UUID-ও গুরুত্বপূর্ণ। systemd-machine-id-setup(1) প্রথমে KVM UUID ব্যবহার করে, তারপর random generation-এ fallback করে। তাই provider যদি উভয় clone-কে একই SMBIOS (system management BIOS) UUID দিয়ে থাকে, তাহলে regenerate করলেও দুইবার একই machine ID তৈরি হবে। দুই সার্ভারে product UUID আলাদা হলে এই বিষয়টি নিয়ে চিন্তার কিছু নেই।

ক্লোন করা VPS-এর machine ID পুনরায় তৈরি করুন

ক্রম বজায় রাখা গুরুত্বপূর্ণ। systemd-machine-id-setup(1) জানায়, সিস্টেমে একটি বৈধ D-Bus machine ID আগে থেকেই configured থাকলে সেই D-Bus machine ID কপি করে /etc/machine-id initialize করা হয়। আসল /var/lib/dbus/machine-id রেখে দিলে যে মানটি সরাতে চেয়েছিলেন, ঠিক সেটিই আবার তৈরি হবে।

sudo truncate -s 0 /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id       # only if ls -l showed a real file
sudo systemd-machine-id-setup
sudo ln -sf /etc/machine-id /var/lib/dbus/machine-id
cat /etc/machine-id

প্রথমে file truncate করা আবশ্যক। কারণ file অনুপস্থিত বা empty থাকলেই tool কাজ করে। বৈধ ID থাকা file-এ এটি কোনো কাজ করে না। systemd-machine-id-setup standard error-এ কী করেছে তা জানায়। KVM VPS-এ সাধারণত আপনি দেখতে পাবেন:

Initializing machine ID from KVM UUID.

Hypervisor UUID না থাকলে Initializing machine ID from random generator. message দেখা যায়। যেকোনো ফলাফল গ্রহণযোগ্য, যদি cat /etc/machine-id এখন অন্য server-এর তুলনায় ভিন্ন কিছু print করে।

এই symlink-এর কারণে D-Bus এবং systemd একই value ব্যবহার করে। আলাদা একটি real file চাইলে এর পরিবর্তে sudo dbus-uuidgen --ensure চালান। File না থাকলে এটি নতুন UUID দিয়ে file তৈরি করে। dbus installed না থাকলে /var/lib/dbus directory-ই থাকে না, ln-এ No such file or directory error হয়, এবং আপনি এই দুই line বাদ দিতে পারেন।

এরপর reboot করুন।

sudo reboot

রিবুট কেন ঐচ্ছিক নয়

পুরোনো মান ইতিমধ্যে পড়ে নেওয়া প্রতিটি process সেটিই ব্যবহার করছে। sd_id128_get_machine() calling process-এর মধ্যে ID cache করে, তাই চলমান daemon ফাইলটি পরিবর্তিত হলেও তা জানতে পারে না। journald-এর কাছে /var/log/journal/<old-id>/system.journal ইতিমধ্যে open রয়েছে এবং এটি তাতে নতুন তথ্য যোগ করতে থাকে। systemd-networkd শুরু হওয়ার সময় তার DUID নির্ধারণ করেছে এবং প্রতিটি renewal-এ পুরোনো client identifier পাঠিয়ে যাচ্ছে। সাধারণত এটিই সেই সমস্যা, যা আপনি সমাধান করতে চেয়েছিলেন। D-Bus-ও startup-এর সময় তার ID পড়ে। আপনি একে একে service restart করতে পারেন, কিন্তু কোনো একটি বাদ পড়বেই। PID 1-ও পুরোনো মান ধরে রেখেছে।

রিবুটের পরে উভয় দিক পরীক্ষা করুন:

cat /etc/machine-id
ls /var/log/journal/

/var/log/journal/ এখন নতুন ID-র নামে একটি দ্বিতীয় directory ধারণ করছে, এবং নতুন entry সেখানে যাচ্ছে। সাধারণ journalctl কেবল বর্তমান machine-এর directory পড়ে। তাই clone করার আগের history default view থেকে অদৃশ্য হয়ে যায়। তবে তা disk-এ রয়েছে: journalctl --merge পুরোনো directory-সহ প্রতিটি journal directory পড়ে। আর ওই log আর প্রয়োজন নেই নিশ্চিত হলে পুরোনো directory মুছে ফেলুন।

এই কারণেই container-এ procedure আগে থেকে পরীক্ষা করা যায় না। Container host kernel share করে এবং নিজস্ব PID 1 কখনো boot করে না। এই কাজের মূল বিষয়ই হলো reboot। Production-এ যেভাবে ঘটবে, সেভাবেই পরীক্ষা করুন: একটি VM clone করুন, command-গুলো চালান, reboot করুন, তারপর source machine-এর সঙ্গে ID তুলনা করুন।

snapshot নেওয়ার আগে truncate করুন, clone করার পরে নয়

একবারে একেকটি clone ঠিক করা সম্ভব। কিন্তু image ঠিক করা আরও ভালো, কারণ খারাপ snapshot থেকে restore করা প্রতিটি server একই value পায়। template shutdown করার ঠিক আগে এটিই শেষ কাজ হিসেবে করুন।

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 shutdown -h now

File-টি খালি করুন। এটি delete করবেন না। একাধিক machine-এ ব্যবহৃত image-এর জন্য machine-id(5) একটি খালি file ব্যবহারের পরামর্শ দেয়, কারণ file-টি জায়গায় খালি অবস্থায় থাকলে image read-only হিসেবে ব্যবহৃত হওয়ার সময় একটি temporary file আসল file-এর ওপর bind-mount করা যায়। একটি read-only /etc-এ boot-এর সময় তৈরি হওয়া ID ওই temporary file-এ থাকে, এবং filesystem writable হওয়ার পরে systemd-machine-id-setup --commit সেটি একবার লিখে রাখে।

এটির একটি পার্শ্বপ্রতিক্রিয়া আগে থেকে বিবেচনা করুন: machine ID না থাকলে পরবর্তী boot-কে first boot হিসেবে চিহ্নিত করা হয়। তাই ConditionFirstBoot=yes বহনকারী unit-গুলো ওই boot-এ চলে এবং পরবর্তী প্রতিটি boot-এ বাদ পড়ে। template তৈরি করার আগে grep -rl ConditionFirstBoot /usr/lib/systemd/system/ দিয়ে আপনার image কোন কাজ চালাবে তা দেখুন।

template এবং snapshot ভিন্ন object, এবং এই পার্থক্যই নির্ধারণ করে identity কপি হবে কি না। template হলো ইচ্ছাকৃতভাবে প্রস্তুত করা build artifact, আর snapshot হলো নির্দিষ্ট সময়ে চলমান একটি server-এর copy এবং তার data-এর সঙ্গে ওই server-এর identity-ও বহন করে।

ক্লাউড image এই সমস্যা সঠিকভাবে সমাধান করে, কিন্তু আপনার snapshot করে না

Distribution cloud image-গুলো clone করার জন্য তৈরি করা হয়। তাই সেগুলোতে machine ID আগে থেকে সেট করা থাকে না, এবং প্রথম boot-এর সময় এটি নির্ধারিত হয়। cloud-init-এ এর জন্য নির্দিষ্ট documented ধাপ রয়েছে। systemd system-এ cloud-init clean --machine-id, /etc/machine-id-কে literal string uninitialized-এ সেট করে। cloud-init CLI reference-এও golden image clone করার সময় এটিকে best practice বলা হয়েছে। ফলে ওই image থেকে পরবর্তী boot-এর সময় একটি unique machine ID তৈরি হয়।

আপনি নিজে তৈরি করা snapshot-এর ক্ষেত্রে বিষয়টি আলাদা। snapshot নেওয়ার সময় file-টিতে machine ID ইতিমধ্যে সেট করা ছিল। তাই এটি থেকে restore করা প্রতিটি server একই value বহন করে। restore path-এর কোনো ধাপ সেই value মুছে দেয় না। এটি চলমান server-কে নতুন VPS-এ স্থানান্তর করার সমস্যার একই ধরন। copy-টি সম্পূর্ণ সঠিক হয়, কিন্তু identity-ই এমন অংশ যা আপনি copy করতে চাননি।

ক্লোন আর যা কপি করে

  • SSH host key। /etc/ssh/ssh_host_*-ও কপি হয়, তাই উভয় সার্ভার client-দের কাছে একই fingerprint উপস্থাপন করে। ওই ফাইলগুলো মুছে sudo ssh-keygen -A চালান, অথবা Debian ও Ubuntu-তে sudo dpkg-reconfigure openssh-server চালান। এরপর client-রা host key পরিবর্তিত হয়েছে বলে সতর্ক করবে। এটিই সঠিক আচরণ।
  • Hostname। sudo hostnamectl set-hostname app02 দিয়ে এটি সেট করুন। এরপর /etc/hosts নতুন নামটি resolve করছে কি না পরীক্ষা করুন।
  • Static network configuration। Static address-যুক্ত কোনো সার্ভারের clone চালু হওয়ার সঙ্গে সঙ্গেই মূল সার্ভারের সঙ্গে address সংঘাত তৈরি করে। Clone-টি network-এ যুক্ত হওয়ার আগে /etc/netplan/ পড়ুন।
  • Clock। Restored snapshot snapshot নেওয়ার সময়কার সময় নিয়ে আবার চালু হয়। Restored VPS-এ clock-এর বড় পরিবর্তন TLS certificate validation ব্যর্থ করে এবং time sync ঠিক না হওয়া পর্যন্ত log-এর ক্রম এলোমেলো করে দেয়।

Clone-এও নতুন VPS-এর জন্য প্রথম দশ মিনিটের checklist অনুসরণ করুন। Cloned box মূল box-এর user account, SSH key, firewall rule এবং scheduled job উত্তরাধিকারসূত্রে পায়। Clone যে কাজের জন্য তৈরি হচ্ছে, সেগুলোর জন্য এগুলোর কোনোটি পর্যালোচনা করা হয়নি।

FAQ

/etc/machine-id পরিবর্তন করার পরে কি আমাকে reboot করতে হবে?

হ্যাঁ। Process একবার machine ID পড়ে সেটি cache করে, তাই নতুন value ইতিমধ্যে চলমান কোনো process-এ প্রয়োগ হয় না। journald পুরনো ID-র নামে তৈরি journal directory-তে লেখা চালিয়ে যায়। DHCP client-ও পুরনো value থেকে তৈরি client identifier পাঠাতে থাকে। সাধারণত machine ID পরিবর্তনের এটিই কারণ। আলাদা service restart করলে কিছু ক্ষেত্রে সমস্যা ঠিক হয়, কিন্তু PID 1-ও পুরনো value ধরে রাখে। reboot করুন। এরপর cat /etc/machine-id দিয়ে যাচাই করুন এবং অন্য server-এর সঙ্গে তুলনা করুন।

/etc/machine-id কি hardware UUID-এর সমান?

না। /sys/class/dmi/id/product_uuid-এর DMI product UUID hypervisor থেকে আসে এবং এটি শুধু root পড়তে পারে। machine ID operating system তৈরি করে এবং এটি এমন একটি plain file-এ থাকে, যা যেকোনো user পড়তে পারে। দুটির মধ্যে একমুখী সম্পর্ক আছে। KVM guest-এ D-Bus ID কপি করার মতো কিছু না থাকলে systemd-machine-id-setup hypervisor UUID থেকে নতুন machine ID তৈরি করার seed হিসেবে সেটি ব্যবহার করে। দুটি clone-এর product UUID একই হলে তারা একই machine ID পুনরায় তৈরি করবে। তাই ফলাফল নির্ভরযোগ্য ধরে নেওয়ার আগে ওই file-টিও তুলনা করুন।

/etc/machine-id কি মুছে ফেলব, নাকি খালি রাখব?

Image প্রস্তুত করার সময় এটি খালি রাখুন। machine-id(5) খালি file পছন্দ করে, কারণ image read-only /etc নিয়ে চালু হলে systemd সেটির ওপর একটি অস্থায়ী file bind-mount করতে পারে। Writable system-এ file মুছে ফেললেও কাজ হয়, এবং কিছু clone script এভাবেই কাজ করে। তবে খালি file-ই নিরাপদ default। একই কারণে cloud-init file-এ uninitialized শব্দটি লিখে।

আমার দুটি cloned server একই DHCP address কেন পেল?

কারণ দুটিই একই client identifier পাঠিয়েছে। DHCPv4-এর জন্য systemd-networkd-এর default হলো ClientIdentifier=duid। Default DUID /etc/machine-id-এর hash থেকে তৈরি হয়। তাই একই machine ID থাকলে এবং interface name-ও অপরিবর্তিত থাকলে clone-গুলোর identifier একই হয়। DHCP server ওই identifier মিলিয়ে দুটির request-কে একই client হিসেবে ধরে এবং একটি lease দেয়। প্রতিটি server-এর জন্য আলাদা machine ID সেট করুন এবং দুটিই reboot করুন। Server এখনও পুরনো address দিলে DHCP server-এ থাকা পুরনো lease নিজে clear করুন।

#machine-id#systemd#cloning#snapshots#dhcp