SSD Nodes Learn 🎉 VPS $5.50/aydan başlayan
Rehberler Matt ConnorYazan Matt Connor

Sunucuyu Yeni Bir VPS'ye Sorunsuz Taşıma Rehberi

Canlı bir sunucuyu yeni bir VPS'ye taşırken veri kaybını önlemek için izlenmesi gereken adımlar. DNS TTL ayarlarını düşürme, veritabanı aktarımı ve geçiş süreci detayları.

Bir sunucuyu yeni bir VPS'ye planlı geçiş ile taşıma

Bir sunucuyu yeni bir VPS'ye taşırken, işlemi basit bir kopyalama yerine planlı bir geçiş süreci olarak ele alın. Yeni sunucuyu sıfırdan kurun, verileri iki kez eşitleyin, DNS kayıtlarına dokunmadan önce yeni sunucunun kendi IP adresi üzerinde çalıştığını doğrulayın, ardından kayıtları yönlendirin ve emin olana kadar eski sunucuyu çalışır durumda bırakın. Baytları kopyalamak işin kolay kısmıdır. İşlem sırası, taşınmanın sorunsuz mu yoksa maliyetli mi olacağını belirler.

Bu kılavuz, bir web uygulaması, bir veritabanı ve bir TLS (transport layer security) sertifikası çalıştıran tek bir Linux sunucusunu kapsamaktadır. Bu, çoğu tek sunuculu kurulum için geçerlidir. İki ana bilgisayar söz konusudur, bu nedenle her örnekte hangi ana bilgisayarda çalıştırılacağı bir yorum satırında belirtilmiştir. Adresler dokümantasyon aralıklarından alınmıştır: 198.51.100.10 eski sunucudur, 203.0.113.20 ise yenisidir.

Başlamadan önce tüm operasyon kılavuzunu okuyun. İlk adım olan DNS TTL değerini düşürme işlemi, asıl önemli adımdan günler önce gerçekleştirilmelidir.

Herhangi bir şey inşa etmeden önce envanter çıkarın

Tanımlamadığınız bir sunucuyu yeniden inşa edemezsiniz. Eski sunucunun ne iş yaptığını yazmak için bir saat ayırın; çünkü bir taşıma işleminden sonra bozulan şey her zaman kimsenin hatırlamadığı bir detaydır: bir cron job, bir güvenlik duvarı istisnası veya uygulama dizininin dışında duran bir environment dosyası.

Bunları eski sunucuda çalıştırın ve çıktıları yeni sunucudan erişebileceğiniz bir yerde saklayın.

# old server: packages you asked for, not the dependencies they pulled in
apt-mark showmanual > ~/inv-packages.txt

# old server: what runs now, and what starts at boot
systemctl list-units --type=service --state=running --no-pager > ~/inv-services.txt
systemctl list-unit-files --state=enabled --no-pager >> ~/inv-services.txt
systemctl list-timers --all --no-pager > ~/inv-timers.txt

# old server: what is listening, on which address and port
sudo ss -tulpn > ~/inv-ports.txt

# old server: human accounts, skipping the system ones
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $3, $6, $7}' /etc/passwd

apt-mark showmanual, bağımlılık olarak gelen her şeyi elediği için sahip olunması gereken bir listedir. Beş yıllık bir sunucuda tam bir dpkg --get-selections komutu iki bin satır döndürür ve size niyet hakkında hiçbir şey söylemez.

Zamanlanmış işler iki yerde gizlenir, bu yüzden ikisini de kontrol edin. Sadece ayda bir çalışan bir iş, taşıma işleminden altı hafta sonra keşfedeceğiniz iştir.

# old server: per-user crontabs, then the system drop-ins
for u in $(cut -d: -f1 /etc/passwd); do sudo crontab -lu "$u" 2>/dev/null | sed "s/^/$u: /"; done
sudo ls -la /etc/cron.d /etc/cron.daily /etc/cron.hourly

Ardından normal dosyalar olmayan kısımlar: güvenlik duvarı kuralları, sertifikalar, veritabanları ve aslında ne kadar veri taşıdığınız.

# old server
sudo ufw status verbose        # or: sudo nft list ruleset
sudo certbot certificates
sudo -u postgres psql -c '\l'  # or: sudo mysql -e 'SHOW DATABASES;'
sudo du -xh --max-depth=1 / | sort -h

certbot certificates her sertifika adını, kapsadığı alan adlarını, son kullanma tarihini ve diskteki dosya yollarını yazdırır. Bu çıktı sizin TLS kontrol listenizdir. du -x tek bir dosya sistemi üzerinde kalır, bu yüzden mount edilmiş bir yedekleme birimine girip olması gerekenden on kat daha büyük bir sayı rapor etmez.

İki öğe sunucunun dışında yaşar ve her seferinde unutulur. Birincisi, sunucunuzun IP adresini izin verilenler listesine (allowlist) ekleyen herhangi bir üçüncü taraf: bir ödeme geçidi, yönetilen bir veritabanı, bir SMTP aktarıcısı veya bir iş ortağı API'si. Yeni sunucunun yeni bir adresi vardır, bu nedenle bu izin listelerine yeni IP'nin geçişten sonra değil, önce eklenmesi gerekir. İkincisi, MX kaydı veya metin içinde eski IP'yi belirten bir SPF kaydı gibi sizin oluşturmadığınız DNS kayıtlarıdır.

Eski kök dosya sistemini klonlamak yerine neden yeniden oluşturmalısınız?

Tüm kök dosya sistemini yeni bir VPS üzerine klonlamak daha hızlı görünebilir ve bir noktaya kadar öyledir. Yıllardır üretim ortamında çalışan bir kök dosya sistemi; kimsenin belgelemediği elle düzenlenmiş yapılandırmaları, artık var olmayan depolardan gelen paketleri ve eski platformun sanal donanımı için oluşturulmuş bir önyükleme (boot) düzenini beraberinde getirir. Taşıma işleminin asıl nedeni dahil olmak üzere her şeyi olduğu gibi aktarırsınız.

Yeniden oluşturma süreci ilk gün daha yavaştır ancak sonraki her gün daha düşük maliyetlidir. Güncel sürümü kurun, temel güvenlik sıkılaştırmalarınızı uygulayın ve ardından yalnızca verileri kopyalayın: uygulama dizini, site yapılandırmaları, veritabanı dökümü, sertifikalar ve kullanıcı yüklemeleri. Açıklayamadığınız hiçbir şey yeni sisteme geçmemelidir. Yeni sunucuyu, yeni bir VPS üzerindeki ilk on dakika rehberinde olduğu gibi başlatın, ardından envanterinizdeki servisleri tek tek ekleyin ve her birini doğrulamadan diğerine geçmeyin.

Görüntü veya anlık görüntü geri yüklemenin doğru tercih olduğu durumlar

Yeniden oluşturma işlemine karşı dürüst bir istisna mevcuttur. Eski sunucu önyüklenemiyorsa veya uygulama artık kaynak kodundan yeniden derlenemeyecek bir yapıdaysa, sağlayıcı görüntüsü veya anlık görüntü (snapshot) geri yüklemesi pragmatik bir çözümdür. Bunun gerçek sınırları vardır: Bu yöntem tek bir sağlayıcı içinde ve genellikle sadece aynı plan ailesi dahilinde çalışır; çünkü geri yüklenen disk, o platformun sanal aygıtlarını ve ağ adlandırma düzenini bekler.

Çalışan bir sunucunun anlık görüntüsü, canlı bir veritabanının dosya düzeyindeki diğer kopyalarıyla aynı tutarlılık sorununu taşır. Görüntü geri yüklemeyi bir taşıma planından ziyade bir kurtarma yolu olarak değerlendirin ve bir plan oluşturmadan önce anlık görüntünün neden yedekleme ile aynı şey olmadığı konusunu okuyun.

Dosyalar nasıl taşınır: SSH üzerinden rsync

Eski sunucudan yeni sunucuya veri göndermek için rsync komutunu çalıştırın. Veriyi göndermek genellikle daha basittir; çünkü eski sunucu veriye zaten sahiptir ve sudo altında tümünü okuyabilir.

# old server: dry run first, and read what it says it will do
sudo rsync -aHAX --dry-run --itemize-changes \
  -e 'ssh -i /root/.ssh/id_ed25519' \
  /srv/app/ deploy@203.0.113.20:/srv/app/

# old server: the real bulk pass
sudo rsync -aHAX --info=progress2 \
  -e 'ssh -i /root/.ssh/id_ed25519' \
  /srv/app/ deploy@203.0.113.20:/srv/app/

Kullanılan bayraklar önemlidir. -a izinleri, zaman damgalarını, sembolik bağlantıları ve sahiplik bilgilerini korur. -H, sabit bağlantıları (hard links) ayrı kopyalar haline getirmek yerine sabit bağlantı olarak tutar. -A, POSIX ACL'leri (erişim denetim listeleri) kopyalar; -X ise genişletilmiş öznitelikleri kopyalar. Bu son ikisi olmadan, aynı görünen bir dosya farklı davranabilir; çünkü SELinux etiketleri ve ACL'ler genişletilmiş özniteliklerde saklanır ve başka hiçbir yöntem bunları kaydetmez.

Buradaki hataların çoğu iki ayrıntıdan kaynaklanır.

Sondaki eğik çizgi (trailing slash), verinin nereye yerleşeceğini belirler. /srv/app/, o dizinin içeriği anlamına gelir. /srv/app ise dizinin kendisi anlamına gelir. Bunu yanlış yaparsanız yeni sunucuda /srv/app/app ile karşılaşırsınız; uygulama başlar ancak yapılandırıldığı yollar bir seviye yukarıda kaldığı için eksik dosya hatası verir.

sudo altında tilde işareti, root kullanıcısının ev dizinidir. sudo rsync içinde -e 'ssh -i ~/.ssh/id_ed25519' yazmak, anahtarı kendi ev dizininizde değil, /root/.ssh içinde arar. Anahtar orada değilse, SSH Permission denied (publickey) çıktısını verir, rsync rsync: connection unexpectedly closed hatasını döndürür ve sıfır olmayan bir kodla sonlanır. Anahtar yolunu tam olarak yazın. Yolu düzelttikten sonra kimlik doğrulama mesajı gelmeye devam ederse, publickey hatasının kısa bir neden listesi vardır ve yeni sunucudaki dizin izinleri kontrol edilmesi gereken bir sonraki adımdır.

Sahiplik konusunda bir karar vermeniz gerekir. Root olarak çalıştırıldığında rsync, sahip ve grup bilgilerini varsayılan olarak isim üzerinden eşleştirir. Bu nedenle, eski sunucuda www-data'ye ait bir dosya, sayısal UID (kullanıcı kimliği) farklı olsa bile yeni sunucuda www-data'e ait olur. Yeniden kurulum için istediğiniz durum budur. --numeric-ids bayrağını yalnızca hedefte hesapları bulunmayan bir dosya sistemini kopyalarken ekleyin. Ardından sonucu ls -ln ile kontrol edin; çünkü eşleşen hesabı olmayan bir UID'ye sahip dosyalar çıplak bir sayı olarak görünür ve dosyayı okumaya çalışan her servis erişim reddi alır.

Toplu kopyalama işlemini, eski sunucu hala trafiği karşılamaya devam ederken günler öncesinden başlatın. İşlemi istediğiniz kadar tekrarlayın; rsync yalnızca değişen verileri gönderdiği için ikinci geçiş saatler yerine dakikalar sürer. Geçiş penceresi içindeki son geçişte --delete bayrağını ekleyin; böylece eski sunucuda silinen dosyalar yeni sunucudan da kaldırılır.

# old server: final pass, inside the window, after the app has stopped writing
sudo rsync -aHAX --delete --info=progress2 \
  -e 'ssh -i /root/.ssh/id_ed25519' \
  /srv/app/ deploy@203.0.113.20:/srv/app/

--delete, kaynakta bulunmayan dosyaları hedefte siler; bu nedenle yanlış bir kaynak yolu ve --delete kullanımı hedef dizini tamamen boşaltabilir. Her seferinde önce --dry-run ile deneme yapın. Uzun süreli aktarımlar, dizüstü bilgisayarınızın SSH oturumu koptuğunda kesilebilir; bu yüzden işlemleri eski sunucuda tmux veya screen içinde başlatın. Kopyalama işlemi, eski sunucu hala kullanıcılara hizmet verirken ağ bağlantısını doyuruyorsa --bwlimit=20M bayrağını ekleyin.

Veritabanı taşıma yöntemi: yerel bir döküm

Bir veritabanı, her ne kadar öyle görünse de dosyalardan oluşan bir dizin değildir. Veritabanı; dosya kümesi, bellek içi durum ve yazma öncesi günlük (write-ahead log) bileşenlerinden oluşur ve yalnızca veritabanının kendi tanımladığı anlarda tutarlıdır. Bu nedenle kendi aracını kullanın.

PostgreSQL iki ayrı döküm gerektirir; çünkü roller tüm küme (cluster) genelindedir ve pg_dump bunları içermez:

# old server
sudo -u postgres pg_dumpall --globals-only -f /var/backups/globals.sql
sudo -u postgres pg_dump -Fc -f /var/backups/appdb.dump appdb
# new server: restore in this order
sudo -u postgres psql -f /var/backups/globals.sql
sudo -u postgres createdb -O appuser appdb
sudo -u postgres pg_restore -d appdb --no-owner /var/backups/appdb.dump

globals.sql komutunu atlarsanız tüm tablolar geri yüklenir ancak hiçbir uygulama rolü bunları okuyamaz; çünkü GRANT ifadeleri mevcut olmayan bir kullanıcıya referans verir. -Fc, yalnızca pg_restore tarafından okunabilen ve daha sonra seçili tabloları geri yüklemenize olanak tanıyan özel arşiv formatında yazma yapar. Geri yükleme işlemini aynı ana sürüme veya daha yeni bir sürüme yapın. Örneğin 17'den 16'ya gibi geriye dönük işlemler desteklenmez ve pg_restore, herhangi bir yazma işlemi yapmadan önce dosya başlığındaki desteklenmeyen sürüm hatası nedeniyle arşivi reddeder.

MySQL ve MariaDB, varsayılan olmayan dört seçenekle birlikte tek bir komut kullanır:

# old server
sudo mysqldump --single-transaction --routines --triggers --events \
  --databases appdb > /var/backups/appdb.sql
# new server
sudo mysql < /var/backups/appdb.sql

--single-transaction, yalnızca InnoDB tabloları için yazma işlemlerini engellemeden tutarlı bir anlık görüntü alır. Aynı veritabanındaki bir MyISAM tablosu bu garanti olmadan kopyalanır; bu nedenle döküme güvenmeden önce depolama motorlarınızı kontrol edin. --routines, --triggers ve --events varsayılan olarak kapalıdır; bu da basit bir dökümün verilerinizi geri yükleyeceği ancak saklı yordamlarınızı (stored procedures) ve zamanlanmış görevlerinizi (scheduled events) sessizce geride bırakacağı anlamına gelir. Veritabanı kullanıcıları ve yetkileri, --databases appdb dökümünün asla dokunmadığı mysql sistem veritabanında bulunur; bu yüzden bunları yeni sunucuda CREATE USER ve GRANT ile yeniden oluşturun. MariaDB 11, mariadb-dump ile aynı aracı sunar ve mysqldump dosyasını sembolik bağlantı olarak tutar; bu nedenle Ağustos 2026 itibarıyla her iki isim de çalışır.

SQLite tek bir dosyadır ve uygulama yazma yaparken kopyalamak, bozuk bir dosya ile sonuçlanmanıza neden olur. Kendine ait güvenli bir yolu vardır:

# old server
sqlite3 /var/lib/app/app.db ".backup '/var/backups/app.db'"

Motor ne olursa olsun, güvenmeden önce dökümü kontrol edin. Disk dolduğu için erken duran bir döküm, kesildiği noktaya kadar hiçbir hata vermeden geri yüklenecektir.

# old server: a complete mysqldump ends with a line reading "-- Dump completed on ..."
tail -n 3 /var/backups/appdb.sql

# new server: after restore, count rows in a table whose size you know
sudo mysql -e 'SELECT COUNT(*) FROM appdb.orders;'

Çalışan bir veritabanını neden rsync ile kopyalayamazsınız

rsync dosyaları tek tek kopyalar. Çalışan bir veritabanı aynı anda birden fazla dosyaya yazma işlemi yapar; bu nedenle rsync son dosyaya ulaştığında, ilk dosya çoktan güncelliğini yitirmiş olur. Kopyalanan veriler farklı zaman dilimlerine ait sayfalar içerir; bu, veritabanının hiçbir zaman bulunmadığı tutarsız bir durumdur. Sonuç ya sunucunun başlamayı reddetmesi ya da daha kötüsü; sunucunun başlaması, bir hafta boyunca doğru yanıtlar vermesi ve bir sorgu nihayet hasarlı sayfaya ulaştığında çökmesidir. Bu süreçte herhangi bir uyarı alınmaz.

Dosyaların kendisini taşımak için iki güvenli yol vardır. Veritabanını durdurun, kopyalayın ve tekrar başlatın: bu yöntem doğru ve basittir, ancak kopyalama süresi kadar kesinti yaşamanıza neden olur. Alternatif olarak, çalışan bir sunucunun fiziksel kopyasını almak için tasarlanmış aracı kullanın. PostgreSQL için bu, kopyanın tutarlı olmasını sağlamak adına sunucu ile koordineli çalışan pg_basebackup aracıdır:

# new server: pull a physical copy from the old one
pg_basebackup -h 198.51.100.10 -U replicator -D /var/lib/postgresql/16/main -X stream -P

Bu işlem, REPLICATION özniteliğine sahip bir role ve eski sunucuda eşleşen bir pg_hba.conf kaydına ihtiyaç duyar; bu nedenle kurulumu bir dump işleminden daha karmaşıktır. Veritabanı, dump ve geri yükleme işleminin kesinti sürenize sığmayacağı kadar büyük olduğunda bu yöntem tercih edilmelidir. Normal bir tek sunuculu taşıma işlemi için dump yöntemi daha avantajlıdır.

Sertifikaları geçişten sonra değil, önce yeniden oluşturun

TLS sertifikası IP adresine değil alan adına bağlıdır, bu nedenle sertifika dosyası sorunsuz bir şekilde taşınır. Sorunsuz taşınmayan kısım yenileme işlemidir. Certbot'un varsayılan HTTP-01 sınaması, sertifika yetkilisinden sertifikalandırılan isim üzerinden 80 numaralı portta bir dosya getirmesini ister. DNS yeni sunucuyu işaret edene kadar bu istek eski sunucuya ulaşır ve yeni sunucunun yenileme işlemi başarısız olur.

İlk seçenek, mevcut sertifikaları ve bunların yenileme durumlarını kopyalamaktır. Bu sertifikalar, hangi sunucuda bulunurlarsa bulunsunlar son kullanma tarihlerine kadar geçerli kalırlar.

# old server
sudo rsync -aHAX -e 'ssh -i /root/.ssh/id_ed25519' \
  /etc/letsencrypt/ root@203.0.113.20:/etc/letsencrypt/

/etc/letsencrypt/renewal/ altındaki her dosya, sertifikayı düzenleyen doğrulayıcı eklentisini belirtir. Bu nedenle yeni sunucuya aynı eklentiyi kurun (örneğin python3-certbot-nginx); aksi takdirde ilk yenileme işlemi bilinmeyen bir doğrulayıcı hakkında hata vererek başarısız olur. Yenileme işleminin çalıştığını ona güvenmeden önce doğrulayın:

# new server, after DNS has moved
sudo certbot renew --dry-run

İkinci seçenek, yeni sunucuda DNS-01 sınamasını kullanarak yeni bir sertifika düzenlemektir. Bu yöntem, kontrolü bir TXT kaydı üzerinden kanıtlar ve 80 numaralı porta hiç dokunmaz. Bu yöntem, alan adı hala eski sunucuya yönlenmişken geçiş öncesinde çalışır; DNS sağlayıcınızı otomatize edebiliyorsanız bu daha temiz bir tercihtir. DNS-01 sınaması ile sertifika düzenleme bölümü, eklenti ve kimlik bilgisi kurulumunu ele alır.

Her iki durumda da, DNS değişikliği yapmadan yeni sunucunun gerçekte ne sunduğunu kontrol edin:

# your laptop
echo | openssl s_client -connect 203.0.113.20:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -subject -dates -issuer

-servername, web sunucusunun doğru sanal ana bilgisayarı (virtual host) seçmesini sağlayan SNI (server name indication) bilgisini gönderir. Bu parametreyi kullanmazsanız, o IP adresi için varsayılan sertifikayı alırsınız; bu da gerçek bir sorun gibi görünen ancak aslında sorun olmayan bir uyumsuzluğa yol açar.

Geçişten günler önce DNS TTL değerini düşürün

DNS, dikkatli bir geçiş sürecinde bile hataların yaşanabileceği bir noktadır; çünkü gecikme sistemin doğasında vardır ve geçiş günü bu süreyi kısaltamazsınız. A kaydınızı önbelleğe alan bir çözümleyici (resolver), kendisine iletilen TTL (yaşam süresi) süresi boyunca bu kaydı sunmaya devam eder. TTL değerini şimdi düşürmek, kaydı on dakika önce eski değerle önbelleğe alan bir çözümleyici için hiçbir şey ifade etmez: çözümleyici, eski TTL süresinin geri kalanı boyunca eski değeri tutmaya devam eder ve ancak bu süre dolduğunda yeni, daha kısa değeri öğrenir. Bu nedenle, TTL değerini geçişten en az bir tam eski TTL süresi kadar önce düşürün. Bir gün öncesi, güvenli bir zaman dilimidir. Buradaki süreçler sizin için yeniyse, kayıtlar, çözümleyiciler ve önbellekleme hakkındaki kılavuz temel bilgileri sağlar.

Aşağıdaki sayılar TTL değerinin aritmetik sonucudur, bir ölçüm değildir.

ChartHow long a stale IP can survive, by record TTL
The data behind this chart
[
  {
    "label": "TTL 3600 s (common default)",
    "ttl_seconds": 3600,
    "worst_case_stale_minutes": 60
  },
  {
    "label": "TTL 900 s",
    "ttl_seconds": 900,
    "worst_case_stale_minutes": 15
  },
  {
    "label": "TTL 300 s (lowered for cutover)",
    "ttl_seconds": 300,
    "worst_case_stale_minutes": 5
  },
  {
    "label": "TTL 60 s (short window)",
    "ttl_seconds": 60,
    "worst_case_stale_minutes": 1
  }
]

3600 saniyelik bir TTL ile yayınlanan bir A kaydı, siz değişikliği yaptıktan sonra bile kullanıcıları 60 dakika boyunca eski IP adresine yönlendirmeye devam edebilir. Değeri 300 saniyeye düşürdüğünüzde, bu en kötü durum senaryosu 5 dakikaya iner. Bu rakamları bir garanti olarak değil, bir alt sınır olarak değerlendirin. Bazı çözümleyiciler kendi minimum TTL değerlerini uygular ve daha kısa değerleri göz ardı eder; ayrıca bazı uygulama çalışma zamanları (runtimes), çözümlenen bir adresi sürecin ömrü boyunca önbellekte tutar. Bu nedenle, değişikliğinizden önce başlayan bir istemci, uygulama yeniden başlatılana kadar asla yeni sorgu yapmayabilir.

Düşük TTL değerinin aktif olduğunu kontrol ederken kendi önbelleğinize değil, yetkili (authoritative) cevaba bakın:

# your laptop: ask the zone's own nameserver, so no cache is involved
dig +short NS example.com
dig +noall +answer @$(dig +short NS example.com | head -n1) example.com A

Bu cevap satırındaki ikinci alan, saniye cinsinden TTL değeridir. Ardından insanların unuttuğu kayıtları gözden geçirin: eski sunucunun IPv6 adresi varsa AAAA kaydı, CNAME yerine ayrı bir A kaydı olarak tanımlanmışsa www adı, doğrudan sunucuya işaret eden tüm MX kayıtları, eski IP adresini listeleyen bir SPF kaydı ve yeni adres üzerindeki ters DNS (PTR) kaydı. Sunucu e-posta gönderiyorsa, geçişten önce PTR kaydını servis sağlayıcınızın kontrol paneli üzerinden ayarlayın; çünkü gelen e-posta sunucuları bunu kontrol eder ve eksik bir PTR kaydı, diğer her şey düzgün görünse bile saatler sonra e-postaların reddedilmesine neden olur.

DNS ayarlarını değiştirmeden önce yeni sunucuyu IP adresi üzerinden doğrulayın

DNS kayıtları hala eski sunucuyu işaret ederken, tüm uygulamayı yeni sunucu üzerinde test edebilirsiniz. Tek bir istek için isim çözümlemesini geçersiz kılın:

# your laptop: force one name to the new IP, for this request only
curl -sS --resolve example.com:443:203.0.113.20 \
  -o /dev/null -w '%{http_code} %{ssl_verify_result}\n' https://example.com/

--resolve yalnızca bağlantının nereye gideceğini değiştirir. TLS sertifikası hala gerçek alan adı üzerinden kontrol edildiğinden, bu işlem hem sertifikayı hem de servisi doğrular. %{ssl_verify_result}, zincir doğrulandığında 0 çıktısını verir.

Siteyi tarayıcı üzerinden incelemek için, dizüstü bilgisayarınızdaki /etc/hosts dosyasına veya Windows üzerinde C:\Windows\System32\drivers\etc\hosts dosyasına tek bir satır ekleyerek isim çözümlemesini tüm makineniz için geçersiz kılın:

203.0.113.20 example.com www.example.com

Ardından uygulamayı bir kullanıcının yapacağı gibi test edin. Giriş yapın. Veritabanından veri okuyan bir sayfayı yükleyin. Veritabanına yazan bir formu gönderin. Bir dosya yükleyin ve diske ulaştığından emin olun. E-posta gönderimini tetikleyin ve ulaştığını kontrol edin; çünkü yeni bir IP adresinden yapılan giden SMTP trafiği genellikle beklenmedik sorunlara yol açar. İşleminiz biter bitmez hosts satırını kaldırın. Bu satırı orada bırakmak, herkesin sorunsuz gördüğü bir siteyi neden göremediğinizi anlamak için bir saatinizi harcamanıza neden olur.

Geçiş süreci, adım adım

  1. Günler öncesinden: TTL değerini düşürün, toplu rsync işlemini çalıştırın, yeni sunucuyu kurun ve bir hosts geçersiz kılma (override) ayarıyla test edin.
  2. Geçiş günü, pencere öncesinde: Yeni IP adresini tüm üçüncü taraf izin listelerine ekleyin ve yeni sunucunun yedekleme işinin yapılandırıldığını ve deponuzu işaret ettiğini doğrulayın.
  3. Pencereyi açın: Yazma işlemlerini durdurmak için uygulamayı eski sunucuda bakım moduna alın.
  4. Son veritabanı dökümünü alın, ardından --delete ile son rsync geçişini çalıştırın.
  5. Dökümü yeni sunucuda geri yükleyin ve servisleri başlatın.
  6. --resolve ve hosts geçersiz kılma ayarı üzerinden, gerçek bir yazma işlemi de dahil olmak üzere tekrar test edin.
  7. A ve AAAA kayıtlarını yeni IP adresine yönlendirin.
  8. Her iki sunucuyu da izleyin. Eski sunucunun erişim logları hala oraya gelenleri gösterir; bu sayı TTL süresi boyunca sıfıra doğru düşmelidir.
  9. Bakım sayfasını kaldırın.
  10. Eski sunucuyu en az bir hafta boyunca çalışır ve dokunulmamış halde bırakın.

Bakım modu adımı, insanların atladığı ancak sizi koruyan tek adımdır. Yeni veritabanı bir kez yazma işlemi kabul ettiğinde, geri dönüş yapmak ya o veriyi kaybetmek ya da yeni veritabanını döküp eski sunucuya geri yüklemek anlamına gelir. Birkaç dakikalık salt okunur bir pencere maliyetsizdir. Her ikisi de yazma işlemi almış iki veritabanı, günlerce sürecek manuel mutabakat demektir.

Geri alma planı

Geri alma işlemi tek bir eylemden ibarettir: DNS kayıtlarını 198.51.100.10 değerine geri döndürmek. Bu yöntem yalnızca daha önce yaptığınız dört hazırlık sayesinde çalışır.

  • Eski sunucu, servisleri çalışır ve verileri bozulmamış halde durmaktadır. Oradaki yazma işlemlerini durdurdunuz, sunucuyu devre dışı bırakmadınız.
  • TTL değeri hala düşüktür, bu nedenle geri dönüş yolu da ileri gidiş yolu kadar hızlıdır.
  • Üçüncü taraf izin listelerine eski IP'yi değiştirmek yerine yeni IP'yi eklediniz. Eski adresi kaldırırsanız, ödeme ağ geçidinde geri alma yolunuz başarısız olur.
  • Yeni sunucu, tanımlayamayacağınız hiçbir yazma işlemi almamıştır; çünkü şu ana kadarki tek yazma işlemleri kendi test işlemlerinizdir.

Pencere açılmadan önce geri almayı neyin tetikleyeceğine karar verin. İki tetikleyici yeterlidir: Belirli bir dakika içerisinde teşhis edemediğiniz herhangi bir hata ve herhangi bir veri kaybı. Bunları önceden yazılı hale getirmek, on dakikalık bir kesintiyi uzun bir kesintiye dönüştürecek olan saatler süren tahmin yürütme sürecini engeller.

Taşımanın başarılı olduğunu doğrulama

Bir taşıma işlemi, site yüklendiğinde bitmiş sayılmaz. Yalnızca daha sonra hata veren durumları kontrol edin.

# new server
systemctl --failed
journalctl -p err -b --no-pager | tail -n 40
sudo certbot certificates
sudo systemctl list-timers --all --no-pager

systemctl --failed raporlaması 0 loaded units listed, elde etmek istediğiniz sonuçtur. certbot certificates beklediğiniz son kullanma tarihlerini göstermeli ve list-timers, envanterinizdeki her zamanlanmış görevi, boş bir değer yerine gerçek bir sonraki çalışma zamanıyla listelemelidir.

Ardından, yeni sunucuyu siz izlerken kasten bir kez yeniden başlatın. Birisi tarafından manuel olarak başlatılan ve etkinleştirilmeyen bir servis, sabahın üçündeki plansız bir yeniden başlatmaya kadar kusursuz çalışır.

# new server
sudo reboot

# your laptop, once it comes back
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/

Uygulama container içinde çalışıyorsa, aynı tuzak farklı bir biçimde karşınıza çıkar; çünkü bir compose yığınının yeniden başlatma sonrasında ayağa kalkması için açık bir restart politikasına ihtiyacı vardır.

Son kontrol, ertelenmesi en kolay ancak en önemli olanıdır: yedekleme görevi. Yedeklenmemiş bir sunucuyla sonuçlanan taşıma işlemi, bir riski başka bir riskle değiştirmiş olur. Yedekleme işlemini yeni sunucuda manuel olarak çalıştırın, ardından yedekten tek bir dosyayı geçici bir dizine geri yükleyin. Geri yükleme işlemini bizzat test ettiğiniz bir restic deposu, ihtiyaç duyduğunuz anda işe yarayacak olan sürümdür. Eski ve yeni sunucuları bir hafta boyunca yan yana çalıştırıyorsanız, her iki sunucuya erişmek ve yapılandırmak için tutarlı bir yöntem, her ikisi de aktifken aralarındaki yapılandırma farklarının açılmasını engeller.

Geçiş sonrası: eski sunucu ve son işlemler

Eski sunucuyu bir veya iki hafta boyunca tutun. İptal etmek üzere olduğunuz bir planın bir aylık maliyetine denk gelir ve sahip olduğunuz tek geri dönüş (rollback) imkanıdır. Ardından kalan işlemleri tamamlayın.

  • Yeni sunucunuz için ~/.ssh/config dosyasında aynı hostname değerini yeniden kullanmak, ilk bağlantıda WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! hatasına neden olur; çünkü bu isim artık farklı bir host anahtarı ile yanıt vermektedir. Değişikliğin nedenini anladığınızdan emin olduğunuzda, ezbere değil bilinçli bir şekilde, ssh-keygen -R example.com komutu ile eski kaydı temizleyin; çünkü aynı uyarı bir araya girme (interception) saldırısında da görülür. Bir geçiş süreci, hangi anahtarların nereye erişebileceğini gözden geçirmek için de iyi bir fırsattır; küçük bir sunucu grubunda SSH anahtar yönetimi konusu bunun içindir.
  • Eski sunucunun son bir snapshot veya yedeğini alın ve bunu eski sağlayıcınızın dışında bir yerde saklayın.
  • Eski IP adresini sırasıyla izleme kontrollerinden, SPF kayıtlarından ve üçüncü taraf izin listelerinden kaldırın; bu işlemi en son yapın.
  • Eski planı, ancak bu son kopyanın başka bir yerde okunabilir olduğu doğrulandıktan sonra iptal edin.

FAQ

Bir sunucuyu yeni bir VPS'e taşımak ne kadar sürer?

Kullanıcı tarafından fark edilen kesinti süresi genellikle son veritabanı yedeğinin alınması, son rsync geçişi ve servisin başlatılmasıyla sınırlıdır; bu da küçük bir uygulama için on ila otuz dakika sürer. Takvim süresi daha uzundur, çünkü DNS TTL değerinin geçişten en az bir eski-TTL süresi kadar önce düşürülmesi gerekir; bir gün önceden yapmak daha güvenlidir. Büyük veri kopyalama işlemlerini de günler öncesinden planlayın. Bu işlem canlı bir sunucu üzerinde çalışır ve daha sonra tekrarlamak yalnızca son geçişten bu yana değişen verileri aktarır.

Çalışan bir MySQL veya PostgreSQL veritabanını dump almak yerine rsync ile kopyalayabilir miyim?

Hayır. rsync dosyaları tek tek kopyalarken veritabanı aynı anda birden fazla dosyaya yazar; bu nedenle kopyalanan veriler farklı zaman dilimlerinden sayfalar içerir ve veritabanının hiçbir zaman sahip olmadığı tutarsız bir durumu temsil eder. Veritabanı başlatılmayı reddedebilir veya başlatılsa bile bir sorgu hasarlı bir sayfaya ulaştığında hata verebilir. pg_dump ile pg_dumpall --globals-only veya mysqldump --single-transaction kullanın ya da önce veritabanını durdurup dosyaları öyle kopyalayın. Büyük bir PostgreSQL kümesi için pg_basebackup, çalışan bir sunucunun tutarlı bir fiziksel kopyasını oluşturur.

DNS değişikliğini yapmadan önce yeni VPS'i nasıl test edebilirim?

Kendi makinenizdeki isim çözümleme ayarını geçersiz kılın. Tek bir istek için curl --resolve example.com:443:203.0.113.20 https://example.com/, bağlantıyı yeni IP adresine gönderirken sertifikayı gerçek isim üzerinden kontrol etmeye devam eder. Tarayıcı üzerinden test etmek için dizüstü bilgisayarınızdaki /etc/hosts dosyasına 203.0.113.20 example.com satırını ekleyin, giriş yapın, veritabanı okuma, form yazma ve dosya yükleme işlemlerini gerçekleştirin, ardından satırı silin. Yalnızca sertifikayı incelemek için openssl s_client -connect 203.0.113.20:443 -servername example.com komutunu çalıştırın.

Hangi TTL değerini ayarlamalıyım ve ne zaman düşürmeliyim?

A ve AAAA kayıtlarını 300 saniyeye düşürün ve bunu geçişten en az bir tam eski-TTL süresi kadar önce yapın. Kaydı siz değiştirmeden önce önbelleğe alan bir çözümleyici, eski TTL süresi bitene kadar eski değeri tutmaya devam eder; bu nedenle eski TTL 86400 ise bir saat önceden düşürmek hiçbir işe yaramaz. Eski sunucunun erişim logları sessizleştiğinde, yani geçişten birkaç gün sonra değeri normal seviyenize geri yükseltin.

TLS sertifikasını kopyalamalı mıyım yoksa yeni sunucuda yeni bir tane mi oluşturmalıyım?

Her iki yöntem de çalışır. /etc/letsencrypt/ dizinini kopyalamak sertifikayı mevcut son kullanma tarihine kadar geçerli tutar, ancak yeni sunucuya aynı certbot doğrulama eklentisini kurmanız gerekir; aksi takdirde ilk yenileme başarısız olur. Bu yüzden DNS geçişinden sonra certbot renew --dry-run komutunu çalıştırarak durumu doğrulayın. DNS-01 challenge yöntemini kullanabiliyorsanız, yeni bir sertifika oluşturmak daha temiz bir yöntemdir; çünkü bu yöntem kontrolü bir TXT kaydı üzerinden kanıtlar ve DNS yeni sunucuya yönlenmeden önce çalışır. HTTP-01 challenge yöntemi, doğrulama isteği eski sunucuya ulaşacağı için DNS taşınana kadar yeni sunucuda kullanılamaz.