Klonlanmış VPS'lerde /etc/machine-id Hatası Nasıl Çözülür?
Aynı /etc/machine-id değerine sahip iki VPS, DHCP çakışmalarına yol açar. Dosyayı güvenli şekilde sıfırlamak, yeniden oluşturmak ve imaj almadan önce temizlemek için gereken adımlar.
/etc/machine-id nedir ve neden bir kopyası sorun yaratır
Klonlanmış bir VPS, klonlandığı sunucuyla aynı /etc/machine-id ile açılır; oysa bu değerin yalnızca tek bir kuruluma ait olması gerekir. Çözüm dört komuttan oluşur: dosyayı boşaltın, eğer gerçek bir dosya ise D-Bus kopyasını silin, yeniden oluşturun ve sistemi yeniden başlatın. Yeniden başlatma adımı genellikle atlanır, ancak değişikliğin geçerli olmasını sağlayan adım budur.
/etc/machine-id, satır sonu karakteriyle biten, küçük harfli, 32 karakterlik onaltılık (hexadecimal) bir dizge içerir. Bu, kod çözüldüğünde 16 baytlık (128-bit) bir değere karşılık gelir. machine-id(5) kılavuz sayfası bu değeri gizli olarak tanımlar ve ağ üzerinde ifşa edilmemesi gerektiğini belirtir; çünkü bu değeri okuyan herhangi bir yapı, makinenizi daha sonra tekrar tanıyabilir. Bu değer sistem kurulduğunda bir kez yazılır ve sonrasında hiçbir şey tarafından değiştirilmez.
Burada üç farklı tanımlayıcı birbirine karıştırılmaktadır, bu yüzden bunları birbirinden ayırmak faydalıdır. Hostname, seçtiğiniz ve istediğiniz zaman değiştirebileceğiniz bir etikettir. /sys/class/dmi/id/product_uuid içindeki DMI (desktop management interface) ürün UUID'si, hipervizörden gelir ve yalnızca root tarafından okunabilir. Machine ID ise üçüncüsüdür: işletim sistemi tarafından oluşturulur ve sunucudaki her kullanıcı tarafından okunabilir.
Makine kimliğini gerçekte ne okur
DHCP istemci tanımlayıcısı. Sorun yaratan budur. systemd.network(5), [DHCPv4] bölümünde ClientIdentifier= değerinin varsayılan olarak duid olduğunu belgeler; bu da bir IAID ve DUID'den (DHCP benzersiz tanımlayıcısı) oluşturulan bir RFC 4361 istemci kimliği gönderir. networkd.conf(5), varsayılan DUID türünü vendor olarak belgeler; burada DUID değeri, satıcı tanımlayıcısı (systemd) olarak 43793 ve makine kimliğinin hash'lenmiş içeriği kullanılarak oluşturulur. DHCPv6 aynı DUID'i kullanır. Aynı makine kimliğine sahip iki klon, aynı DUID'i üretir ve eğer aynı arayüz adını korurlarsa, bayt bazında aynı olan bir istemci tanımlayıcısı gönderirler. DHCP sunucusu bu durumda iki istemci yerine tek bir istemci görür ve her iki kutuya da aynı kira (lease) teklifini sunar. Belirti, adresin iki sunucu arasında gidip gelmesi veya diğeri yenileme yaptığında bir sunucunun adresini kaybetmesidir.
journald. Günlük dosyaları /var/log/journal/<machine-id>/ içinde yaşar. Dizin, doğrudan kimliğin adını taşır. İki klonun günlüklerini tek bir toplayıcıya gönderirseniz, bunlar tek bir dizin altında toplanır ve tek bir ana bilgisayar olarak okunur.
D-Bus. /var/lib/dbus/machine-id, bu dosya biçiminin başladığı yerdir. Debian ve Ubuntu üzerinde bu, /etc/machine-id dosyasına giden bir sembolik bağdır. Bazı sistemlerde ise kendi kopyasını tutan ayrı bir gerçek dosyadır ve bu kopya, aşağıdaki prosedürdeki tuzaktır.
Ana bilgisayar bazlı aracılar. İzleme aracıları, lisans kontrolleri, envanter araçları ve yedekleme istemcileri, kararlı olduğu ve yapılandırma gerektirmediği için genellikle makine kimliğini varsayılan ana bilgisayar tanımlayıcısı olarak kullanır. Tek bir kimlik bildiren iki sunucu, birleştirilmiş bir metrik serisi veya iki makineyi kapsayan tek bir lisans koltuğu anlamına gelir. Aracınızın ana bilgisayar kimliğini hostname kullandığını varsaymak yerine, nasıl türettiğini kontrol edin.
Kopya olup olmadığını anlama
Bunu her iki sunucuda da çalıştırın ve çıktıları karşılaştırın.
cat /etc/machine-id
ls -l /var/lib/dbus/machine-id
sudo cat /sys/class/dmi/id/product_uuidcat /etc/machine-id
İki canlı sunucuda aynı makine kimliklerinin bulunması, birinin diğerinden kopyalandığı anlamına gelir. Tek bir komut tercih ederseniz, hostnamectl komutu Machine ID: satırında aynı değeri yazdırır.
ls -l sonucu bir sonraki adımı belirler. Sembolik bir bağlantı (symlink) şu şekilde görünür:
lrwxrwxrwx 1 root root 15 Aug 21 09:12 /var/lib/dbus/machine-id -> /etc/machine-idlrwxrwxrwx 1 root root 32 ... /etc/machine-id -> /var/lib/dbus/machine-id
-rw-r--r-- ile başlayan bir satır, bunun eski kimliğin kendi kopyasını tutan gerçek bir dosya olduğu anlamına gelir. Bunu kaldırmanız gerekir, çünkü systemd-machine-id-setup başka herhangi bir işlem yapmadan önce bu dosyayı okur.
Ürün UUID değeri de önemlidir. systemd-machine-id-setup(1), rastgele oluşturmaya geçmeden önce KVM UUID değerini kullanır; bu nedenle sağlayıcınız her iki kopyaya da aynı SMBIOS (system management BIOS) UUID değerini verdiyse, yeniden oluşturma işlemi size iki kez aynı makine kimliğini verecektir. İki sunucuda farklı ürün UUID değerleri olması, bu konuda endişelenmenize gerek olmadığı anlamına gelir.
Klonlanmış bir VPS üzerinde makine kimliğini (machine ID) yeniden oluşturma
Sıralama önemlidir. systemd-machine-id-setup(1), sistem için geçerli bir D-Bus makine kimliği zaten yapılandırılmışsa, bu D-Bus makine kimliğinin kopyalandığını ve /etc/machine-id dosyasını başlatmak için kullanıldığını belirtir. Gerçek bir /var/lib/dbus/machine-id dosyasını yerinde bırakırsanız, kurtulmaya çalıştığınız değerin aynısını yeniden oluşturursunuz.
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Önce dosyanın içeriğini boşaltmak (truncate) gereklidir; çünkü araç yalnızca dosya eksik veya boş olduğunda işlem yapar ve halihazırda geçerli bir kimlik barındıran dosyaya müdahale etmez. systemd-machine-id-setup, yaptığı işlemi standart hata çıktısında raporlar. Bir KVM VPS üzerinde genellikle şunları görürsünüz:
Initializing machine ID from KVM UUID.Initializing machine ID from random generator., herhangi bir hipervizör UUID değeri bulunamadığında verilen mesajdır. cat /etc/machine-id artık diğer sunucudan farklı bir değer yazdırdığı sürece her iki sonuç da kabul edilebilir.
Sembolik bağ (symlink), D-Bus ve systemd değerlerini aynı tutar. Eğer ayrı ve gerçek bir dosya tercih ederseniz, bunun yerine sudo dbus-uuidgen --ensure komutunu çalıştırın: bu komut, dosya mevcut değilse yeni bir UUID ile dosyayı oluşturur. Eğer dbus yüklü değilse /var/lib/dbus dizini hiç yoktur, ln komutu No such file or directory hatasıyla başarısız olur ve bu iki satırı atlayabilirsiniz.
Ardından sistemi yeniden başlatın.
sudo rebootYeniden başlatma neden isteğe bağlı değildir
Eski değeri okumuş olan her süreç, bu değeri kullanmaya devam eder. sd_id128_get_machine(), ID bilgisini çağıran sürecin içinde önbelleğe alır; bu nedenle çalışan bir daemon, dosyanın değiştiğini asla fark etmez. journald, /var/log/journal/<old-id>/system.journal dosyasını zaten açık tutar ve ona veri eklemeye devam eder. systemd-networkd, başladığı sırada DUID değerini belirlemiştir ve genellikle düzeltmeye çalıştığınız hata olan eski istemci tanımlayıcısını her yenilemede göndermeye devam eder. D-Bus da kendi ID bilgisini başlangıçta okumuştur. Servisleri tek tek yeniden başlatabilirsiniz ancak birini mutlaka gözden kaçırırsınız; ayrıca PID 1 de eski değeri tutmaya devam etmektedir.
Yeniden başlatmanın ardından her iki tarafı da kontrol edin:
cat /etc/machine-id
ls /var/log/journal//var/log/journal/ artık yeni ID ile adlandırılmış ikinci bir dizini tutar ve yeni kayıtlar buraya yazılır. Standart journalctl komutu yalnızca mevcut makinenin dizinini okur, bu nedenle klonlama öncesi geçmişiniz varsayılan görünümden kaybolur. Veriler hala disk üzerindedir: journalctl --merge, eski dizin dahil olmak üzere her günlük dizinini okur. Bu kayıtlara artık ihtiyacınız olmadığından emin olduğunuzda eski dizini silebilirsiniz.
İşlemi bir container içinde prova edememenizin nedeni de budur. Bir container, ana makinenin çekirdeğini paylaşır ve kendi PID 1 sürecini asla başlatmaz; oysa yeniden başlatma, bu işlemin temel noktasıdır. Testi üretim ortamında olduğu gibi yapın: bir VM klonlayın, komutları çalıştırın, yeniden başlatın ve ardından ID bilgisini kaynak makine ile karşılaştırın.
Klonlamadan sonra değil, snapshot almadan önce boşaltın
Klonları tek tek düzeltmek işe yarar. İmajı düzeltmek ise daha iyidir, çünkü hatalı bir snapshot'tan geri yüklenen her sunucu aynı değeri devralır. Bunu, şablonu kapatmadan önce yapacağınız son işlem haline getirin.
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 nowDosyayı silmeyin, içeriğini boşaltın. machine-id(5), birden fazla makinede kullanılan imajlar için boş bir dosya bulundurulmasını önerir; çünkü yerinde duran boş bir dosya, imaj salt okunur (read-only) modda kullanıldığında gerçek dosyanın üzerine geçici bir dosyanın bind-mount edilmesine olanak tanır. Salt okunur bir /etc üzerinde, önyükleme sırasında oluşturulan kimlik bu geçici dosyada yaşar ve dosya sistemi yazılabilir hale geldiğinde systemd-machine-id-setup --commit bunu kalıcı dosyaya yazar.
Planlanması gereken bir yan etki: içi boş bir makine kimliği, bir sonraki önyüklemeyi "ilk önyükleme" olarak işaretler; bu nedenle ConditionFirstBoot=yes taşıyan birimler o önyüklemede çalışır ve sonraki tüm önyüklemelerde atlanır. Şablonu oluşturmadan önce imajınızın grep -rl ConditionFirstBoot /usr/lib/systemd/system/ ile neleri çalıştıracağını kontrol edin.
Şablon ve snapshot farklı nesnelerdir; aralarındaki fark, kimlik bilgisinin kopyalanıp kopyalanmayacağını belirler. Şablon, bilinçli olarak hazırladığınız bir yapı çıktısıdır; snapshot ise çalışan bir sunucunun belirli bir andaki kopyasıdır ve verileriyle birlikte o sunucunun kimliğini de taşır.
Bulut imajları bunu doğru yaparken kendi snapshot'ınızın neden yapamadığı
Dağıtım bulut imajları klonlanmak üzere oluşturulmuştur; bu nedenle makine kimliği (machine ID) boş olarak gelir ve ilk önyükleme sırasında doldurulur. cloud-init, tam olarak bu işlem için belgelenmiş bir adıma sahiptir. cloud-init clean --machine-id, systemd sistemlerinde /etc/machine-id değerini uninitialized dizgisine ayarlar. cloud-init CLI referansı, bir golden image klonlanırken bunun en iyi uygulama olduğunu belirtir; böylece imajın bir sonraki önyüklemesinde benzersiz bir makine kimliği oluşturulur.
Kendi aldığınız bir snapshot ise farklı bir durumdur. Snapshot düğmesine bastığınızda dosya zaten dolu durumdadır; bu nedenle ondan geri yüklenen her sunucu aynı değeri taşır ve geri yükleme sürecinde bu değeri temizleyen bir mekanizma yoktur. Bu durum, çalışan bir sunucuyu yeni bir VPS'e taşıma işlemindeki sorunla aynı sınıftadır; kopyalama işlemi sadıktır ancak kopyalanmasını istemediğiniz kısım sunucunun kimliğidir.
Klonun kopyaladığı diğer öğeler
- SSH host anahtarları.
/etc/ssh/ssh_host_*de kopyalandığı için her iki sunucu da istemcilere aynı parmak izini sunar. Bu dosyaları silin vesudo ssh-keygen -Akomutunu çalıştırın veya Debian ve Ubuntu üzerindesudo dpkg-reconfigure openssh-serverkomutunu kullanın. İstemcileriniz daha sonra değişen bir host anahtarı hakkında uyarı verecektir; bu beklenen ve doğru bir davranıştır. - Hostname.
sudo hostnamectl set-hostname app02ile yeni ismi ayarlayın, ardından/etc/hostsdosyasının yeni ismi çözümlediğinden emin olun. - Statik ağ yapılandırması. Statik IP adresine sahip bir sunucunun klonu, ağa bağlandığı anda orijinaliyle çakışır. Klon ağa dahil olmadan önce
/etc/netplan/dokümanını okuyun. - Saat. Geri yüklenen bir snapshot, alındığı andaki zamanla çalışmaya devam eder. Geri yüklenen bir VPS'te büyük saat sapması, TLS sertifika doğrulamasını bozar ve zaman eşitlemesi tamamlanana kadar log sıralamasını karıştırır.
Klon üzerinde de yeni bir VPS için ilk on dakika kontrol listesi adımlarını uygulayın. Klonlanan sunucu; kaynak sunucunun kullanıcı hesaplarını, SSH anahtarlarını, güvenlik duvarı kurallarını ve zamanlanmış görevlerini devralır. Bu öğelerin hiçbiri, klonun üstleneceği yeni görev için gözden geçirilmemiştir.
FAQ
/etc/machine-id dosyasını değiştirdikten sonra yeniden başlatma yapmam gerekir mi?
Evet. Süreçler makine kimliğini bir kez okur ve önbelleğe alır; bu nedenle yeni değer, halihazırda çalışmakta olan hiçbir sürece ulaşmaz. journald, eski kimliğe göre adlandırılmış günlük dizinine yazmaya devam eder ve DHCP istemcisi, genellikle değiştirme nedeniniz olan eski değerden türetilmiş bir istemci tanımlayıcısı göndermeyi sürdürür. Bireysel servisleri yeniden başlatmak bazılarını düzeltse de PID 1 de eski değeri tutar. Yeniden başlatın, ardından cat /etc/machine-id ile ve diğer sunucuyla karşılaştırarak doğrulayın.
/etc/machine-id ile donanım UUID aynı şey midir?
Hayır. /sys/class/dmi/id/product_uuid içindeki DMI ürün UUID'si hipervizörden gelir ve yalnızca root tarafından okunabilir. Makine kimliği işletim sistemi tarafından oluşturulur ve herhangi bir kullanıcının okuyabileceği düz bir dosyada tutulur. Bunlar tek yönlü olarak birbirine bağlanır: Bir KVM konuğunda, kopyalanacak bir D-Bus kimliği olmadığında systemd-machine-id-setup, hipervizör UUID'sinden yeni bir makine kimliği türetir. İki kopya aynı ürün UUID'sini paylaşıyorsa, aynı makine kimliğini yeniden oluşturacaklardır; bu nedenle sonuca güvenmeden önce o dosyayı da karşılaştırın.
/etc/machine-id dosyasını silmeli miyim yoksa boş mu bırakmalıyım?
Bir imaj hazırlarken dosyayı boş bırakın. machine-id(5), imaj salt okunur bir /etc ile çalıştığında systemd'nin üzerine geçici bir dosya bağlayabilmesi (bind-mount) nedeniyle boş dosyayı tercih eder. Dosyayı silmek yazılabilir bir sistemde işe yarar ve bazı klonlama betikleri bu yöntemi kullanır, ancak boş dosya daha güvenli bir varsayılandır. cloud-init, aynı amaçla dosyanın içine uninitialized kelimesini yazar.
İki klonlanmış sunucum neden aynı DHCP adresini aldı?
Çünkü her ikisi de aynı istemci tanımlayıcısını gönderdi. systemd-networkd, DHCPv4 için varsayılan olarak ClientIdentifier=duid kullanır ve varsayılan DUID, /etc/machine-id değerinin bir özetinden (hash) oluşturulur; bu nedenle aynı arayüz ismini koruyan klonlarda, aynı makine kimlikleri aynı tanımlayıcıları üretir. DHCP sunucusu bu tanımlayıcı üzerinden eşleşme sağlar, her iki isteği de tek bir istemci olarak değerlendirir ve tek bir kira (lease) atar. Her sunucuya kendi makine kimliğini verin ve her ikisini de yeniden başlatın. Sunucu hala eski adresi teklif ediyorsa, DHCP sunucusunun kendisindeki eski kira kaydını temizleyin.