17 puan yazan GN⁺ 11 일 전 | 1 yorum | WhatsApp'ta paylaş
  • Aylık 1.432 $ tutarındaki production altyapısı, aylık 233 $'lık dedicated server'a taşınırken işletim sistemi de değiştirildi ve buna rağmen kesinti olmadan hizmet sürekliliği korundu
  • 30 adet MySQL veritabanı ve 34 adet Nginx sanal host, GitLab EE, Neo4J, Supervisor, Gearman yeni sunucuda birebir kuruldu; gerçek zamanlı replikasyon ve son artımlı senkronizasyonla taşıma tamamlandı
  • Veritabanı taşımasının çekirdeğinde mydumper·myloader paralel işleme ile MySQL replication kombinasyonu vardı; MySQL 5.7'den 8.0'a yükseltirken ortaya çıkan sys şeması ve yetki sorunları da düzeltildi
  • Cutover süreci DNS TTL düşürme, eski sunucuda Nginx reverse proxy'ye geçiş, toplu A kaydı değişikliği sırasıyla yürütüldü; böylece DNS yayılımı sırasında eski IP'ye gelen istekler de yeni sunucuya iletildi
  • Sonuç olarak aylık 1.199 $ tasarruf, yıllık 14.388 $ tasarruf, daha yüksek CPU·bellek·depolama ve 0 dakika kesinti birlikte elde edildi

Migrasyonun arka planı

  • Türkiye'de bir yazılım şirketi işletilen ortamda hızlı enflasyon ve Türk lirasındaki değer kaybı nedeniyle dolar bazlı altyapı maliyetlerinin yükü ciddi biçimde artmış durumdaydı
  • Mevcut DigitalOcean sunucusunun maliyeti her ay 1.432 $ idi; yapılandırma 192GB RAM, 32 vCPU, 600GB SSD, 2 adet 1TB block volume ve yedeklemeleri içeriyordu
  • Yeni hedef Hetzner AX162-R dedicated server idi; AMD EPYC 9454P 48 çekirdek 96 thread, 256GB DDR5, 1.92TB NVMe Gen4 RAID1 yapılandırmasına sahipti
  • Aylık maliyet 233 $'a düştü; aylık tasarruf 1.199 $, yıllık tasarruf ise 14.388 $ seviyesine ulaştı
  • Mevcut sunucunun güvenilirliği ya da geliştirici deneyimiyle ilgili bir memnuniyetsizlik yoktu; ancak steady-state iş yüklerinde fiyat/performans artık makul değildi

Mevcut operasyon ortamı

  • Operasyon stack'i basit bir test ortamı değil, gerçek bir production ortamıydı
    • Toplam 248GB veri içeren 30 MySQL veritabanı
    • Birden fazla domain üzerinde çalışan 34 Nginx sanal host
    • 42GB GitLab EE yedeği
    • 30GB Neo4J Graph DB
    • Supervisor ile yönetilen onlarca arka plan worker'ı
    • Gearman iş kuyruğu
    • Yüz binlerce kullanıcıya hizmet veren canlı mobil uygulamalar
  • Mevcut sunucunun işletim sistemi CentOS 7 idi ve destek süresi sona ermişti
  • Yeni sunucunun işletim sistemi AlmaLinux 9.7; RHEL 9 uyumlu bir dağıtım ve CentOS sonrası için doğal bir tercih
  • Bu taşıma yalnızca maliyet düşürmek için değil, yıllardır güvenlik güncellemesi alamayan işletim sisteminden çıkmak için de bir fırsat oldu

Kesintisiz strateji

  • Basit DNS değişikliği ve servis yeniden başlatma yaklaşımı kabul edilmedi; 6 aşamalı migrasyon prosedürü ile kesintisiz taşıma yapıldı
  • 1. aşama: Yeni sunucuya tüm stack'in kurulması

    • Nginx, eski sunucudakiyle aynı flag'lerle source üzerinden derlenip kuruldu
    • PHP, Remi repo üzerinden kuruldu ve eski sunucudaki aynı .ini ayar dosyaları uygulandı
    • MySQL 8.0, Neo4J Graph DB, GitLab EE, Node.js, Supervisor, Gearman kuruldu ve mevcut davranışla aynı olacak şekilde yapılandırıldı
    • DNS kayıtlarına dokunmadan önce tüm servisler eski sunucudakiyle aynı şekilde çalışacak hale getirildi
    • SSL sertifikaları, eski sunucudaki /etc/letsencrypt/ dizininin tamamı rsync ile kopyalanarak taşındı
    • Tüm trafik yeni sunucuya geçtikten sonra certbot renew --force-renewal ile sertifikalar topluca zorla yenilendi
  • 2. aşama: Web dosyalarının rsync ile kopyalanması

    • /var/www/html dizininin tamamı, yaklaşık 65GB ve 1,5 milyon dosya, SSH tabanlı rsync ile kopyalandı
    • Bütünlük doğrulaması için --checksum seçeneği kullanıldı
    • Cutover'dan hemen önce değişen dosyaları yansıtmak için son bir artımlı senkronizasyon daha yapıldı
  • 3. aşama: MySQL master-slave replikasyonu

    • Dump alıp restore ederek veritabanını durdurmak yerine gerçek zamanlı replikasyon kuruldu
    • Eski sunucu master, yeni sunucu read-only slave olarak yapılandırıldı
    • İlk büyük veri yüklemesinde mydumper kullanıldı; sonrasında dump metadata'sında kaydedilen kesin binlog konumundan itibaren replikasyon başlatıldı
    • Cutover anına kadar iki taraftaki veritabanı gerçek zamanlı senkron halde tutuldu
  • 4. aşama: DNS TTL düşürme

    • Tüm A/AAAA kayıtlarının TTL değeri, DigitalOcean DNS API'sine script ile çağrı yapılarak 3600 saniyeden 300 saniyeye düşürüldü
    • MX ve TXT kayıtları değiştirilmedi
    • Mail kayıtlarının TTL değerini değiştirmenin iletim sorunlarına yol açabileceği düşünülerek hariç bırakıldı
    • Eski TTL'nin dünya genelinde süresinin dolması için 1 saat beklendi ve ardından 5 dakika içinde cutover'a hazır hale gelindi
  • 5. aşama: Eski sunucudaki Nginx'in reverse proxy'ye çevrilmesi

    • Python script'i, 34 Nginx site yapılandırmasının tamamındaki server {} bloklarını parse etti
    • Mevcut ayarlar yedeklendi ve yerlerine yeni sunucuya yönlendiren proxy ayarları yazıldı
    • Böylece DNS yayılımı sırasında bile eski IP'ye gelen istekler sessizce yeni sunucuya aktarıldı
    • Kullanıcı tarafında görünür bir kesinti oluşmadı
  • 6. aşama: DNS cutover ve eski sunucunun kapatılması

    • Python script'i ile DigitalOcean API çağrılarak tüm A kayıtları birkaç saniye içinde yeni sunucunun IP'siyle değiştirildi
    • Eski sunucu 1 hafta boyunca cold standby olarak tutulduktan sonra kapatıldı
    • Tüm süreç boyunca servis ya doğrudan yanıt verdi ya da proxy üzerinden yanıt verdi; böylece erişilebilirlikte boşluk oluşmadı

MySQL migrasyonu

  • Tüm işin en karmaşık kısmı MySQL taşımasıydı
  • Veri dump'ı

    • Standart mysqldump yerine mydumper kullanıldı
    • Yeni sunucunun 48 CPU çekirdeği sayesinde paralel export/import yapılarak, tek thread'li mysqldump ile günler sürecek iş birkaç saate indirildi
    • Kullanılan başlıca seçenekler arasında --threads 32, --compress, --trx-consistency-only, --skip-definer, --chunk-filesize 256 vardı
    • Ana dump içindeki metadata dosyasına snapshot anındaki binlog konumu yazıldı
      • File: mysql-bin.000004
      • Position: 21834307
    • Bu değerler daha sonra replikasyonun başlangıç noktası olarak kullanıldı
  • Dump aktarımı

    • Dump tamamlandıktan sonra SSH tabanlı rsync ile yeni sunucuya aktarıldı
    • Toplam 248GB sıkıştırılmış chunk taşındı
    • mydumper içindeki --compress seçeneği, sıkıştırılmış chunk'lar sayesinde ağ aktarım hızını artırdı
  • Veri yükleme

    • myloader kullanıldı
    • Başlıca seçenekler --threads 32, --overwrite-tables, --ignore-errors 1062, --skip-definer idi
  • MySQL 5.7'den 8.0'a geçişte yaşanan sorunlar

    • CentOS 7 ortamı nedeniyle eski sunucu MySQL 5.7'de kalmıştı
    • Taşıma öncesinde mysqlcheck --check-upgrade ile verinin MySQL 8.0 ile uyumlu olup olmadığı kontrol edildi ve sonuç sorunsuzdu
    • Yeni sunucuya güncel MySQL 8.0 Community kuruldu
    • Tüm projelerde query çalışma süreleri anlamlı biçimde azaldı; orijinal yazıda bunun nedeni olarak MySQL 8.0'ın geliştirilmiş optimizer'ı ve InnoDB iyileştirmeleri gösterildi
    • Ancak sürüm sıçraması nedeniyle bazı sorunlar da yaşandı
      • Import sonrasında mysql.user tablosundaki kolon yapısı beklenen 51 değil, 45 kolon durumundaydı
      • Bunun sonucunda mysql.infoschema eksik kaldı ve kullanıcı doğrulama sorunları ortaya çıktı
    • İlk düzeltme denemesinde aşağıdaki komutlar kullanıldı
      • systemctl stop mysqld
      • mysqld --upgrade=FORCE --user=mysql &
    • İlk deneme ERROR: 'sys.innodb_buffer_stats_by_schema' is not VIEW hatasıyla başarısız oldu
    • Bunun nedeni, sys şemasının view yerine normal tablo olarak import edilmiş olmasıydı
    • Çözüm olarak DROP DATABASE sys; çalıştırıldı ve upgrade yeniden denendi
    • Sonrasında işlem normal şekilde tamamlandı

MySQL replikasyon yapılandırması

  • Her iki sunucuda da dump yüklemesi bittikten sonra, yeni sunucu eski sunucunun replica'sı olarak yapılandırıldı
  • CHANGE MASTER TO ifadesinde eski sunucunun IP'si, replikasyon kullanıcısı, port 3306, MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=21834307 belirtildi
  • Ardından START SLAVE; çalıştırıldı
  • Neredeyse hemen ardından error 1062 Duplicate Key nedeniyle replikasyon durdu
  • Bunun nedeni, dump işleminin iki parçaya bölünmesi ve bu arada bazı tablolara yazma yapılması; böylece import edilen dump ile binlog replay aynı satırı iki kez eklemeye çalıştı
  • Bunu çözmek için aşağıdaki ayar uygulandı
    • SET GLOBAL slave_exec_mode = 'IDEMPOTENT';
    • START SLAVE;
  • IDEMPOTENT modu, duplicate key ve missing row hatalarını sessizce atlayarak ilerliyor
  • Tüm kritik veritabanları hatasız senkronize oldu ve birkaç dakika içinde Seconds_Behind_Master değeri 0'a düştü

Cutover öncesi doğrulama

  • DNS kayıtlarına dokunmadan önce tüm servislerin yeni sunucuda doğru çalıştığının doğrulanması gerekiyordu
  • Doğrulama yöntemi, yerel makinedeki /etc/hosts dosyasını geçici olarak düzenleyip domain'i yeni sunucunun IP'sine eşlemekti
  • Tarayıcı ve Postman yeni sunucuya istek gönderirken, dış kullanıcılar hâlâ eski sunucuya erişmeye devam etti
  • API endpoint'leri, yönetim paneli ve her servisin yanıt durumu kontrol edildi
  • Her şey doğrulandıktan sonra gerçek cutover yapıldı

SUPER yetkisi sorunu

  • Master-slave replikasyonu tamamen senkron hale geldikten sonra, yeni sunucuda read_only = 1 olmasına rağmen INSERT sorgularının başarılı olduğu görüldü
  • Bunun nedeni, tüm PHP uygulama kullanıcılarına SUPER yetkisi verilmiş olmasıydı
  • MySQL'de SUPER yetkisi read_only ayarını bypass eder
  • SHOW GRANTS FOR 'some_db_user'@'localhost'; çıktısında SUPER yetkisinin bulunduğu doğrulandı
  • Toplam 24 uygulama kullanıcısı için REVOKE SUPER ON *.* FROM 'some_db_user'@'localhost'; komutu tekrar tekrar çalıştırıldı
  • Ardından FLUSH PRIVILEGES; uygulandı
  • Sonrasında read_only = 1, uygulama kullanıcılarının yazmasını doğru şekilde engellerken replikasyonun devam etmesine izin verdi

DNS hazırlığı

  • Tüm domain'ler DigitalOcean DNS ile yönetiliyordu ve nameserver bağlantısı GoDaddy üzerinden yapılıyordu
  • TTL düşürme işi, DigitalOcean API hedeflenerek script'leştirildi
  • Değişiklik yalnızca A ve AAAA kayıtları ile sınırlandı
  • MX ve TXT kayıtlarına dokunulmadı
    • Google Workspace iletim sorunları yaşanma ihtimali nedeniyle mail ile ilgili kayıtların TTL değeri değiştirilmedi
  • Eski TTL'nin süresinin dolması için 1 saat beklendi ve ardından cutover'a hazır hale gelindi

Eski sunucudaki Nginx'in reverse proxy'ye çevrilmesi

  • 34 yapılandırma dosyasını elle düzenlemek yerine, Python script'iyle otomatik dönüşüm yapıldı
  • Script tüm yapılandırma dosyalarındaki server {} bloklarını parse etti, ana content block'u tespit etti ve onu proxy ayarlarıyla değiştirdi
  • Orijinal ayarlar .backup dosyaları olarak yedeklendi
  • Örnek yapılandırmada proxy_pass https://NEW_SERVER_IP;, proxy_set_header Host $host;, proxy_set_header X-Real-IP $remote_addr;, proxy_read_timeout 150; kullanıldı
  • Kritik seçenek proxy_ssl_verify off idi
    • Çünkü yeni sunucudaki SSL sertifikaları domain için geçerliydi, IP adresi için geçerli değildi
    • İki ucu da kontrol eden bir ortam olduğu için burada doğrulamanın kapatılması kabul edilebilir görüldü

Cutover prosedürü

  • Cutover öncesindeki koşullar, replikasyon gecikmesinin Seconds_Behind_Master: 0 olması ve reverse proxy'nin hazır olmasıydı
  • Uygulama sırası şöyleydi
    • Yeni sunucuda STOP SLAVE;
    • Yeni sunucuda SET GLOBAL read_only = 0;
    • Yeni sunucuda RESET SLAVE ALL;
    • Yeni sunucuda supervisorctl start all
    • Eski sunucuda nginx -t && systemctl reload nginx çalıştırılarak proxy etkinleştirildi
    • Eski sunucuda supervisorctl stop all
    • Yerel Mac üzerinde python3 do_cutover.py çalıştırılarak DNS'teki tüm A kayıtları yeni sunucu IP'siyle değiştirildi
    • Yaklaşık 5 dakika yayılım beklendi
    • Eski sunucudaki tüm crontab girdileri yorum satırına alındı
  • DNS cutover script'i, DigitalOcean API'yi çağırarak tüm A kayıtlarını yaklaşık 10 saniye içinde değiştirdi

Cutover sonrası ek işler

  • Taşıma tamamlandıktan sonra çok sayıda GitLab proje webhook'unun hâlâ eski sunucu IP'sini işaret ettiği görüldü
  • GitLab API üzerinden tüm projeleri tarayıp webhook'ları topluca güncelleyen bir script yazıldı ve uygulandı

Nihai sonuç

  • Aylık maliyet 1.432 $'dan 233 $'a düştü
  • Yıllık tasarruf 14.388 $ oldu
  • Performans tarafında da daha güçlü bir sunucu elde edildi
    • CPU, 32 vCPU'dan 96 logical CPU'ya çıktı
    • RAM, 192GB'dan 256GB DDR5'e yükseldi
    • Depolama, yaklaşık 2,6TB karma yapıdan 2TB NVMe RAID1'a geçti
    • Kesinti süresi 0 dakika oldu
  • Tüm migrasyon yaklaşık 24 saat sürdü
  • Kullanıcı tarafında hiçbir etki yaşanmadı

Temel dersler

  • MySQL replication, kesintisiz migrasyonun temel aracı
    • Erken kurulup yeterince catch-up yapması beklendikten sonra cutover yapılmalı
  • MySQL kullanıcı yetkileri taşımadan önce mutlaka gözden geçirilmeli
    • SUPER yetkisi varsa read_only bypass edilerek slave ortamının gerçekte salt okunur olmaması gibi bir sorun çıkabiliyor
  • DNS güncellemeleri, Nginx yapılandırma değişiklikleri ve webhook düzeltmeleri için script'leştirme önemli
    • 34'ten fazla siteyi elle yönetmek hem zaman kaybettirir hem hata riskini artırır
  • mydumper + myloader kombinasyonu, büyük veri setlerinde mysqldump'tan çok daha hızlı
    • 32 thread'li paralel dump/restore ile günler sürecek iş birkaç saate indirilebiliyor
  • Steady-state iş yüklerinde cloud sağlayıcıları pahalı kalabilir; dedicated server daha düşük maliyetle daha yüksek performans sunabilir

GitHub script'leri

  • Migrasyonda kullanılan tüm Python script'leri GitHub üzerinde açıklandı
  • Dahil olan script listesi
    • do_list_domains_ttl.py
      • Tüm DigitalOcean domain'lerinin A kayıtlarını, IP'lerini ve TTL değerlerini listeler
    • do_ttl_update.py
      • Tüm A/AAAA kayıtlarının TTL değerini topluca 300 saniyeye düşürür
    • do_to_hetzner_bulk_dns_records_import.py
      • Tüm DNS zone'larını DigitalOcean'dan Hetzner DNS'e taşır
    • do_cutover_to_new_ip.py
      • Tüm A kayıtlarını eski sunucu IP'sinden yeni sunucu IP'sine geçirir
    • nginx_reverse_proxy_update.py
      • Tüm nginx site ayarlarını reverse proxy yapılandırmasına dönüştürür
    • mysql_compare.py
      • İki MySQL sunucusundaki tüm tabloların row count değerlerini karşılaştırır
    • final_gitlab_webhook_update.py
      • Tüm GitLab proje webhook'larını yeni sunucu IP'sine günceller
    • mydumper
      • mydumper kütüphanesi
  • Tüm script'ler, gerçek uygulama öncesinde güvenli önizleme sağlayan DRY_RUN = True modunu destekliyor

1 yorum

 
GN⁺ 11 일 전
Hacker News yorumları
  • Birkaç ay önce iki sunucuyu Linode ve DO’dan Hetzner’e taşıdım ve maliyeti benzer ölçüde büyük oranda düşürdüm. Daha da etkileyici olan, onlarca sitenin farklı diller, eski kütüphaneler, MySQL ve Redis’le birbirine dolaştığı tam bir karmaşa yığını olmasıydı. Ama Claude Code bunların hepsini taşıdı, eksik kütüphaneler için de bazı kodları yeniden yazarak halletti. Artık bu tür karmaşık geçişler çok daha kolay, bu yüzden gelecekte sağlayıcılar arası taşınabilirliğin daha da artacağını düşünüyorum

    • Bence insanların para ödediği şey sihirli compute değil, 10 yıllık yapıştırma koduna dokunmamak içindi. Ama ajanlar bu glue kodu yemeye başlarsa, mevcut sağlayıcıların moat’u hızla incelir gibi geliyor
    • Dürüst olmak gerekirse bu, içine Hetzner reklamı yerleştirilmiş bir Claude reklamı gibi hissettiriyor. Acaba bu iç içelik nereye kadar gidiyor diye düşündürüyor
    • Her hikâyeyi ille de AI hikâyesine çevirmek gerekmiyor gibi geliyor
    • Ben de önümüzdeki birkaç ay içinde Linode’dan ayrılacağım. 10 yıldan uzun süredir kullanıyorum ve çok müşteri de yönlendirdim ama fiyatları sürekli artırdılar; artık Hetzner gibi yerlerde çok daha ucuza 8 kat bellek, dedicated NVMe ve dedicated CPU alabiliyorsun. Sanal sunucuların kolay taşınabilirliği gibi bazı avantajları kaybediyorsun ama arıza olduğunda bile Hetzner desteği her zaman hızlı ve yetkin oldu
    • Ben de Claude’u giderek daha çok DevOps için kullanıyorum. Sahip olduğum bare metal üzerinde Proxmox ile VM çalıştırıyorum ve Claude, birden fazla makineye yayılan yeni bir ağı inanılmaz hızlı optimize edip yapılandırıyor; neredeyse bir ekip arkadaşı ya da iyi maaş alan bir sysadmin gibi hissettiriyor
  • AWS’den Hetzner’e geçiş planlıyorum. Amazon’un rakiplerinden bazen 20 kat daha pahalı fiyat çekmesi, biraz makul fiyat almak için uzun vadeli taahhüt dayatması ve veri çıkışını da aşırı pahalı hâle getirmesi bana çok müşteri düşmanı geliyor. İnsanları egress ücretleriyle kilitlediklerini sanırsın ama aslında bir parçayı bile rakibe taşısan seni tümünü taşımaya zorlayan bir baskı unsuru gibi çalışıyor. Yine de platformumu Amazon’a özgü servislerin üstüne kurmadığım için geçiş biraz daha kolay olacak

    • Bu eskiden doğruydu ama Ocak 2024’te GCP egress ücreti muafiyeti politikası açıklayınca hava değişti, AWS de birkaç ay sonra benzer bir politikayla buna uydu. Kalman için ikna etmeye çalışmıyorum; sadece teknik olarak waiver talebi mümkün demek istiyorum. Pratikte kapsamı ne kadar geniş emin değilim, ayrıca AWS metnine bakınca EU Data Act etkisi de var gibi görünüyor
  • Böyle yazıları her gördüğümde, kimsenin pek yedeklilik ya da load balancer gibi şeylerden söz etmemesine şaşırıyorum. Tek bir sunucu ölürse birden çok servis birlikte düşebilir; insanların gerçekten bunu sorun etmediğini merak ediyorum. Belki paradan tasarruf etmişlerdir ama bakım süresi ve gelecekteki baş ağrıları daha pahalıya mal olabilir

    • Bunun servis türüne ve ne kadar kritik olduğuna bağlı olduğunu düşünüyorum. Bir sunucu 10 yıl çalışıp bu sürede toplam 1 hafta ila 1 ay kadar kesinti yaşatıyorsa, çoğu durumda bu gayet kabul edilebilir olabilir. Küçük işletmeler, hobi siteleri, forumlar, bloglar gibi web sitesinin çekirdek iş olmadığı yerlerde kısa kesintiler büyük sorun olmayabilir. Hatta bu düşük trafikli sitelerin uzun kuyruğu web’in çoğunluğunu oluşturuyor olabilir. Her şeyin yüksek erişilebilir olması gerekmiyor; isteyenler için bu sağlayıcılar load balancer gibi özellikler de sunuyor
    • Bence bu tür yazıların ilgi görmesinin sebebi, sık sık gereksinimlerle çözüm arasındaki uyumsuzluğu göstermeleri. Eğer hobi projesi ya da küçük bir işletme için kurumsal seviyede mimari kurup aşırı tasarladıysan, arada bir gün kapanmak sorun değilse cloud tarzı tam donanımlı kurulum şart olmayabilir. Ama bu yazıda biraz tuhaf olan, kesintisiz migration vurgulanırken varılan mimarinin aslında arızalara çok dayanıklı görünmemesiydi. Hetzner tarafına çok az ek yapı kurarak bu epey iyileştirilebilirdi gibi geliyor
    • Pek çok iş yükü için o düzeyde önleme gerekmediğini düşünüyorum. Ayrıca sadeliğin güvenilirliğini küçümsememek lazım. Uzun süre Linux sysadmin olarak çalıştım ve karmaşık sistemlerde gördüğüm kesinti, basit sistemlerden çok daha fazlaydı. Teori ile gerçek arasında bir yerde, çoğu zaman sonunda basit olanın daha iyi dayandığı izlenimini edindim
    • Adil olmak gerekirse, baştan beri DigitalOcean’da tek bir VM kullanıyorlardı; yani cloud sağlayıcısının avantajlarından çok fazla yararlanılan bir durum değildi. Genelde bu tür hikâyeler, cloud’a yanlış sebeple çıkıp fiziksel tarafa dönmesi gerekenlerle, tam tersine böyle bir taşımanın felaket olacağı durumlara ayrılıyor; bu örnek birincisine daha yakın görünüyor. Kurulum DO’da iyi çalışıyorsa, Hetzner’de de uygun bir DR politikasıyla gayet iyi olabilir
    • Muhtemelen bu karar, uzun süre gerçek anlamda bakım cehennemi ya da gelecekteki baş ağrılarını pek yaşamamış bir deneyimden çıkmış olabilir
  • Biz lithus.eu olarak müşterileri farklı cloud’lardan Hetzner’e sık sık taşıdık. Genelde çok sunuculu, bazen de çoklu AZ kurulum yapıyor ve Kubernetes ile iş yüklerini dağıtarak HA sağlıyoruz. Tek düğümde Kubernetes fazla olabilir ama birden çok düğüm varsa çok daha mantıklı. Yedeklerde Velero ile uygulama seviyesinde yedeklemeyi birlikte kullanıyoruz; örneğin Postgres için WAL yedekleriyle PITR da sağlıyoruz. State veriyi en az iki düğümde tutarak HA garanti ediyoruz. Performans açısından da bare metal çoğunlukla daha iyi oluyor; AWS’ye kıyasla yanıt süresinin yarıya indiği çok oldu. Bunun sebebinin sanallaştırmanın kendisinden çok NVMe, düşük ağ gecikmesi ve daha az cache contention gibi çevresel etkenler olduğunu düşünüyorum. Bununla ilgili daha fazlasını daha önce yazdığım HN gönderisinde de anlattım

    • Ben de birkaç yıl önce bunu kendim ölçtüm ve o günden beri sanal sunuculara bir daha dönmedim. CPU zamanı RAM gibi rezerve edilmediği için, gerçek donanıma kıyasla performans gerçekten çok kötüydü. Bu ölçüm yazısı da faydalı olabilir
    • k8s dağıtımları taşınmak için gerçekten çok iyi. Farklı cloud’lardaki managed servislere kıyasla vendor lock-in çok daha az. Benim stack’im de k8s, hosted Postgres ve s3 benzeri depolama civarında; Postgres’i her zaman kendim host edebilirim, sonuçta geriye esas olarak k8s ve s3 kalıyor. Hetzner’de de s3 benzeri bir şey var gibi ama henüz bakmadım; ayrıca 100 TB taşımak epey büyük iş olur
    • Bu arada HA, high availability anlamına geliyor
    • Yazı mantıklıydı ama sona e-posta bırakmaları biraz reklam metni gibi durmuş
  • Bu yazıyı okumak epey zordu. Sanki Claude migration’ı yapmış, sonra da Claude’un yazdığı raporu okuyormuşsun gibi. LLM sayesinde bu kadar tasarruf ettilerse harika, ama yayımlayacaksan en azından üzerinden geçip tekrarları ve LLM tarzı anlatımı temizlemek gerekirdi

    • Birçok kişinin orijinali okumadığını biliyorum ama bu yazı gerçekten acı verecek kadar zor okunuyordu
  • Hetzner konusunda dikkatli olunması gerektiğini düşünüyorum. Eskiden gerçekten seviyordum ama yakın zamanda ayrıldım. CI/CD pipeline’ımızda kullandığımız yaklaşık 30 VM’in tamamını, tek bir 36 dolarlık fatura anlaşmazlığı yüzünden kapattılar. Banka kayıtları dâhil ödemenin tamamlandığını kanıtladık ama bakmayı bile reddettiler; acil şekilde iletişime geçmeye çalışırken sonunda tüm erişimi kestiler. Şimdi Scaleway’e taşındık

    • Müşteri hizmetleri şaşırtıcı derecede hasmane gelebiliyor. Yine de kritik olmayan işler için hâlâ kullanıyorum
    • Hetzner’in faturalama işlemleri oldukça otomatikleştirilmiş, ama genelde kart ödemesi başarısız olsa bile yaklaşık bir ay ödeme süresi tanıdıklarını görmüştüm
  • Birkaç ay önce küçük bir SaaS yan projesi için AWS alternatifi ararken, maliyet azaltma ve AB bulutlarını destekleme açısından önce Hetzner’i ciddi ciddi değerlendirdim. Daha çok şeyi kendim yapmam gerekse bile razıydım ama asıl engel IP itibarı oldu. Şirketimizdeki managed AWS firewall kurallarından biri Hetzner IP’lerinin çoğunu, belki tamamını engelliyordu; iş dizüstü bilgisayarımdan da Hetzner IP’lerinde barındırılan siteler IT politikası nedeniyle açılmıyordu. Cloudflare gibi bir şey kullanmak bunu azaltabilir ama DDoS korumasının zayıf olduğuna dair yorumlar da gördüm. Sonunda AB bölgesinde DO App Platform’u seçtim; managed veritabanı seçenekleri de büyük artıydı

    • Rakipleri böyle engellemek Amazon açısından ne kadar pratik bir yöntem olurdu diye düşünmeden edemiyor insan
    • Hangi firewall kuralından söz ettiğini bilmiyorum ama DO’nun Hetzner’den daha güvenilir sayılması bana oldukça şaşırtıcı geliyor. Ben scraper ya da hacker gördüğümde DO ASN’lerini de sık görüyorum; o taraf da bir gün engellenebilir gibi geliyor
    • Benim deneyimimde DO IP’leri daha kötüydü. Ben de tam bu yüzden DO’dan taşındım
    • Daha önce Tor ile ilgili bir başlıkta bu konudan söz etmiştim. Hetzner’in Tor dostu olması nedeniyle bunun IP itibarını etkileyebileceğini tahmin etmiştim ama o zaman itibar sorunu olmadığını söyleyenler de vardı. Sonra Tor Project verilerine bakınca Hetzner’in Tor ağının yaklaşık %7’sini barındırdığı görünüyor; dolayısıyla durum o kadar basit olmayabilir
    • İşin ironik yanı, ben sadece AWS ve Azure’yu engelleyerek bot sorununun %99’unu çözdüm. Gerçek kullanıcılara zararı sıfır oldu; bu yüzden bu engelleme özelliğini başlı başına bir hizmet olarak satsam mı diye düşünüyorum
  • Böyle migration deneyimlerini paylaşmaları gerçekten faydalı, o yüzden teşekkür ederim. Ben DO ile Hetzner karşılaştırmasını, DoorDash ya da UberEats açmakla akşam yemeğini kendin yapmak arasındaki trade-off gibi görüyorum. Maliyet oranı da aşağı yukarı benzer hissettiriyor. Üç büyük cloud’u da on-prem’i de yönetiyorum ama ufak işler ya da PoC testleri için hâlâ DigitalOcean konsoluna gidiyorum. Birkaç tıklamayla sunucu ya da bucket hazırlamak, mantıklı varsayılanlar ve tek bir onay kutusuyla yedekleme eklemek gibi kolaylıkların zaman değeri düşünülünce kesinlikle bir karşılığı var

    • Tam olarak neyi kastettiğinden emin değilim ama Hetzner Console’un da benzer şekilde çalıştığını düşünüyorum
    • Bu yazıda benim için ilginç olan iki şey vardı. Biri kesintisiz geçiş prosedürünün kendisi; bu genel olarak faydalı bir referans. Diğeri ise cloud instance’larını bare metal ile değiştirme kararıydı; maliyet tasarrufunun yanında hızlı failover’dan ve yedek kayıplarından vazgeçmenin de fiyatın parçası olduğunu kabul etmek gerekir. Ben olsam 200 dolar kadar daha harcayıp bir hot spare tutar, birkaç günde bir active/standby değiştirerek ikisinin de gerçekten çalıştığını doğrulardım. Görece düşük bir maliyetle ölümcül arıza riskini ciddi biçimde azaltırsın
    • Aslında anlattığın şey, Hetzner Cloud’un yıllardır sunduğu deneyime neredeyse tamamen benziyor. Üstelik Hetzner Cloud API de var; böylece butona basmaya bile gerek kalmadan her şeyi IaC ile kurabiliyorsun
    • Benim durumumda Hetzner sunucularının üstüne Coolify kurarak neredeyse tek tıklamalı servis deneyimi elde ediyorum
    • Bu duruma bakınca aklıma gelen sadece şu xkcd oldu
  • DB yedeklerini nasıl yaptıklarını merak ettim. Replica ya da standby var mıydı, yoksa sadece saatlik yedekler mi alınıyordu öğrenmek istedim. Böyle tek sunuculu bir kurulumda SSD gibi donanım arızaları olursa uygulama doğrudan durabilir; özellikle SSD ölürse yeniden kurulum sırasında saatlerce hatta günlerce kesinti olabilir diye düşündüm

    • Hetzner donanım sunucularını genelde 2x 1TB SSD olarak tanıtıyor ve net 1 TB kapasite için SW RAID1 kurulumunu güçlü şekilde tavsiye ediyor. İmaj kurucusu da varsayılan olarak bu yöne gidiyor. Yıllar sonra ilk SSD bozulsa bile, izleme bunu yakalarsa yeni kutuya taşınabilir, geçici bir alternatif/replica kullanılabilir ya da diğer disk üzerinde devam edilip hot-swap beklenebilir. Elbette fiziksel sunucuya geçince cloud’un bazı yedekliliklerini kaybediyorsun; bunu sağlanan tasarrufla birlikte risk modeline katıp hesaplamak gerekir. Ve en azından uzak depoya günlük yedek bile yoksa, bu bence gözü karalık olur. Bu cloud’da da geçerli, sadece kurması daha kolay
    • Bu kadar uzun süre kapalı kalsa bile kimsenin çok umursamayacağı durumlar olabilir. Mesela benim HOA mobil uygulamam bir hafta kapalı kalsa pek umursamam. Her şeyin 7/24 çalışması gerekmiyor
    • Benim de aklıma gelen ilk endişe buydu. Yazı, yazarın yeterince düşünmeden sadece agresif maliyet düşürmeye odaklandığını hissettirdi. DigitalOcean VM’leri muhtemelen live migration ve snapshot destekliyordu ama Hetzner’de bunlar cloud ürünlerinde mümkün. Hetzner bare metal tarafında disk ya da parça bozulursa gerçekten bozulmuş olur; disk değişimini yapsalar bile geri yüklemeyi kullanıcı baştan yapmak zorunda kalır. Hetzner de bunu birçok yerde açıkça belirtiyor
    • Benim yaptıklarım içinde en kolayı MongoDB tarafıydı; replication, sharding ve failover çok basitti. Yakın zamanda PostgreSQL’de de pg_auto_failover ile 1 monitor, 1 primary ve 1 replica kurdum; ayarları ve tuzakları biraz öğrenince bu da oldukça kolay geldi. Benim deneyimimde kesintisiz geçiş de mümkündü
    • Eğer onların bu trade-off’u kabul etmeye değer buldukları sonucuna vardıysalar, bunun yanlış olduğunu kesin söyleyemeyiz. Her uygulama 24/7 erişilebilirlik gerektirmiyor ve çoğu web sitesi için birkaç saatlik kesinti büyük yıkım yaratmıyor. Maliyet tasarrufu riskten daha ağır basıyorsa bu tamamen mantıklı bir iş kararı olabilir. Benim asıl merak ettiğim, yedekleme ve kurtarma stratejilerinin ne olduğu ve Hetzner’e geçince bunların nasıl değiştiği
  • Başlıktaki meme görseli benim yaptığım bir şeydi. Şu yazıya koymuştum; böyle iki kez kullanıldığını görmek hoşuma gitti