VaultTest/vault_failover_scenarios.md
Murat ÖZDEMİR 99af68deb2 feat(vault): Add cluster health check to skip bootstrap
Integrates `vault-check-health.sh` into `vault-bootstrap.sh` to perform a network-based health check. If all Vault nodes are found initialized and unsealed, the bootstrap process is skipped, preventing unnecessary restarts or re-initialization.

Renames `failover_scenarios.md` to `vault_failover_scenarios.md` for improved clarity and consistency.
2026-06-12 09:42:10 +03:00

10 KiB
Raw Permalink Blame History

Vault HA Failover Senaryoları

Bu belge, 3 düğümlü Vault HA Raft kümesinin Docker Swarm üzerindeki çeşitli host makine hatası ve kurtarma koşulları altında nasıl davrandığını ve her durumda manuel müdahale gerekip gerekmediğini kapsamaktadır.


Mimari Özeti

Özellik Değer
Vault düğümleri 3 replika (vault-1, vault-2, vault-3)
Raft çoğunluğu (quorum) 3 düğümden 2'si gereklidir
Düğüm kimliği hostname: "vault-{{.Task.Slot}}.iklim.co" — yeniden başlatmalarda sabittir
Unseal mekanizması Shamir anahtarı, Docker Swarm secret'ı vault_unseal_key olarak saklanır
Entrypoint unseal döngüsü Başlangıçtan sonra 3 dakikaya kadar her 2 saniyede bir vault operator unseal komutunu dener
Yerleşim (Placement) max_replicas_per_node: 1, node.labels.type == service

hostname ayarı kritik parçadır: Swarm, rastgele bir konteyner kimliği yerine sabit bir slot numarası (1, 2, 3) atadığı için, Raft node_id her yeniden başlatmada aynı kalır. Raft, geri dönen bir düğümü node_id üzerinden hemen tanır ve onu yepyeni bir eş (peer) olarak değerlendirmek yerine replikasyona kaldığı yerden devam eder.


Raft Çoğunluk (Quorum) Kuralları

Hayattaki düğümler Çoğunluk Küme durumu
3 / 3 Evet Tamamen operasyonel
2 / 3 Evet Operasyonel — okuma ve yazma işlemleri devam eder
1 / 3 Hayır Donmuş — çoğunluk sağlanana kadar okuma ve yazma işlemleri engellenir
0 / 3 Hayır Kapalı

Küme, herhangi bir hizmet kesintisi olmadan aynı anda bir düğüm hatasını tolere edebilir.


Senaryo 1 — Takipçi (Follower) Host Makine Çöküyor, Volume Sağlam

Tetikleyici: vault-N (bir takipçi) çalıştıran host makine çöker veya kapatılır. Vault volume'u host makinenin diskinde hayatta kalır.

Otomatik davranış:

  1. Docker Swarm görevi (task) başarısız olarak işaretler. max_replicas_per_node: 1 ayarı uygun başka bir host makine bırakmadığı için, Swarm replikayı başka bir yerde yeniden zamanlamaz. Hizmet 2/3 görevle çalışmaya devam eder.
  2. Kalan 2 düğüm (1 lider + 1 takipçi) çoğunluğu korur. Küme, isteklere normal şekilde hizmet vermeye devam eder.
  3. Host makine geri gelip Swarm'a tekrar katıldığında, Swarm görevi hemen üzerinde zamanlar.
  4. Konteyner başlar, Raft verilerini sağlam bulur, lider ile retry_join üzerinden bağlantı kurar ve saklanan log indeksinden devam eder.
  5. Entrypoint unseal döngüsü /run/secrets/vault_unseal_key dosyasını okur ve düğümü otomatik olarak unseal eder.
  6. Düğüm saniyeler içinde standby (takipçi) durumuna geçer.

Manuel müdahale: Gerekli değildir.


Senaryo 2 — Takipçi Host Makine Çöküyor, Volume Kayıp (Host Makine Yeniden Kuruldu)

Tetikleyici: vault-N çalıştıran host makine tamamen değiştirilir veya Docker volume'ları silinir (rm -rf /var/lib/docker/volumes/iklimco_vault-data-vl/_data/*).

Bu senaryo testlerde doğrulandı: o sırada Raft lideri olan vault-3'ün volume'u silindi. Tam kurtarma yaklaşık 5 saniye sürdü.

Otomatik davranış:

  1. Swarm, görevi (şimdi temiz olan) host makine üzerinde zamanlar.
  2. Konteyner boş bir veri dizini ile başlar (security barrier not initialized).
  3. retry_join, vault.iklim.co:8200 (paylaşılan overlay takma adı) ile iletişime geçer. Başlangıçta sealed bir düğüme denk gelirse otomatik olarak tekrar dener.
  4. Başarılı bir katılımda lider, tam Raft günlüğünü yeni düğüme aktarır (previous-index=<leader> → last-index=1).
  5. Initialized: true olduğunda, entrypoint unseal döngüsü düğümü başarıyla unseal eder.
  6. Düğüm, Raft seçim sonucuna bağlı olarak standby (takipçi) veya active (lider) durumuna geçer.

Manuel müdahale: Gerekli değildir.

Yeniden kurulan host makinede ön koşul:

  • Konteyner başlamadan önce wildcard sertifika dosyaları /opt/iklimco/ssl/ dizininde mevcut olmalıdır. Bunlar konteynere salt okunur (read-only) olarak bağlanır. Eğer host makine sıfırdan kurulduysa, Swarm'ı tekrar ayağa kaldırmadan önce sertifikaları geri yükleyin.

Senaryo 3 — Lider (Leader) Host Makine Çöküyor, Volume Sağlam

Tetikleyici: Mevcut Raft liderini çalıştıran host makine çöker veya kapatılır. Volume hayatta kalır.

Otomatik davranış:

  1. Hayatta kalan iki takipçi, Raft kalp atışı zaman aşımı (~510 sn) üzerinden lider kaybını tespit eder. Bunlardan biri Raft seçimini kazanır ve yeni lider olur.
  2. Küme, yeni lider ile isteklere hizmet vermeye devam eder. Herhangi bir konfigürasyon değişikliği gerekmez — vault.iklim.co overlay takma adı, çalışan tüm konteynerlere round-robin (sırayla) dağıtım yapar.
  3. Orijinal lider host makine geri geldiğinde, konteyneri yeniden başlar, Raft verilerini bulur, bir takipçi olarak tekrar katılır ve otomatik olarak unseal edilir.

Manuel müdahale: Gerekli değildir.


Senaryo 4 — Lider Host Makine Çöküyor, Volume Kayıp (Host Makine Yeniden Kuruldu)

Senaryo 2 ile aynıdır ancak lider düğüm üzerinde tetiklenir. Davranış aynıdır: kalan 2 düğüm hemen yeni bir lider seçer ve yeniden kurulan host makine, tam log replikasyonu ile yeni bir takipçi olarak katılır.

Manuel müdahale: Gerekli değildir (Senaryo 2 ile aynı wildcard sertifika ön koşulu geçerlidir).


Senaryo 5 — İki Düğüm Aynı Anda Çöküyor

Tetikleyici: Üç host makineden ikisi aynı anda arızalanır (örneğin iki kabini etkileyen bir güç kesintisi).

Otomatik davranış:

  1. Çoğunluk kaybolur (3 düğümden sadece 1'i hayatta).
  2. Hayatta kalan düğüm bir lider seçemez ve salt okunur / donmuş duruma geçer. Tüm Vault API çağrıları hata döndürür.
  3. Çöken iki host makineden herhangi biri geri gelip Vault konteyneri başladığında, çoğunluk geri yüklenir (3 düğümden 2'si).
  4. Raft tekrar bir lider seçer. Küme normal operasyona döner.
  5. Üçüncü host makine geri döndüğünde, takipçi olarak tekrar katılır.

Manuel müdahale: Gerekli değildir — arızalanan iki düğümden en az birinin en sonunda volume'u sağlam olarak geri dönmesi (veya retry_join üzerinden taze bir düğüm olarak tekrar katılması) şartıyla.

Eğer her iki arızalı düğümün de volume'u silinmişse ve hiçbiri tekrar katılamıyorsa, hayatta kalan tek düğüm Raft günlüğünün tek kopyasını elinde tutar. Bu uç durumda küme kendi kendini iyileştirecektir: iki taze düğüm katıldığında hayatta kalan liderden tam bir Raft anlık görüntüsü (snapshot) alacaktır.


Senaryo 6 — Üç Düğümün Hepsi Çöküyor

Tetikleyici: Tam veri merkezi kesintisi, üç Swarm worker düğümünün tamamı aynı anda kapanır.

Otomatik davranış:

  1. Host makineler geri geldiğinde, Swarm üç Vault görevini de zamanlar.
  2. Setiap konteyner başlar ve Raft verilerini sağlam bulur (volume'lar yeniden başlatmalarda korunur).
  3. Raft, üç düğüm arasında bir lider seçer (en yüksek Raft CommitIndex değerine sahip olan düğüm kazanır).
  4. Üç düğümün tamamı entrypoint döngüsü üzerinden otomatik olarak unseal edilir.
  5. Küme, herhangi bir insan müdahalesi olmadan tamamen operasyonel hale gelir.

Manuel müdahale: Gerekli değildir (volume'ların host makine yeniden başlatmalarından sağ çıktığı varsayılmaktadır; bu, işletim sistemi yeniden başlatmaları / güç döngüleri için normaldir).


Senaryo 7 — Host Makine Swarm'dan Tamamen Çıkarıldı ve Tekrar Eklendi

Tetikleyici: Bir worker düğümü manuel olarak drain edilir ve Swarm'dan çıkarılır (docker node rm), ardından yeni veya yeniden imajlanmış bir host makine docker swarm join ile tekrar katılır.

Otomatik davranış:

  • Yeni Swarm düğümü, gerekli düğüm etiketine (label) sahip olmadığı için otomatik olarak bir Vault görevi almaz.

Manuel müdahale gereklidir:

# Yeni düğüm kimliğini (node ID) bulun
docker node ls

# Swarm'ın vault'u üzerinde zamanlayabilmesi için yerleşim etiketini (placement label) tekrar uygulayın
docker node update --label-add type=service <node-id>

Etiket uygulandıktan sonra Swarm, bir sonraki mutabakat döngüsü içinde (genellikle 10 sn içinde) Vault replikasını düğüm üzerinde zamanlar. Bu noktadan itibaren Senaryo 14 geçerlidir (otomatik unseal).


Özet Tablosu

Senaryo Çoğunluk kayboldu mu? Otomatik kurtarma Manuel adımlar
1 — Takipçi çöktü, volume sağlam Hayır Evet Yok
2 — Takipçi çöktü, volume silindi Hayır Evet Host makine yeniden kurulduysa /opt/iklimco/ssl sertifikalarını geri yükleyin
3 — Lider çöktü, volume sağlam Hayır (yeni seçim) Evet Yok
4 — Lider çöktü, volume silindi Hayır (yeni seçim) Evet Host makine yeniden kurulduysa /opt/iklimco/ssl sertifikalarını geri yükleyin
5 — İki düğüm aynı anda çöktü Evet (biri dönene kadar) Evet Yok — bir düğümün dönmesini bekleyin
6 — Üç düğümün hepsi çöktü Evet (ikisi dönene kadar) Evet Yok
7 — Host makine Swarm'dan çıkarıldı ve tekrar eklendi Hayır Kısmi docker node update --label-add type=service <id>

Otomatik Kurtarmayı Sağlayan Temel Tasarım Özellikleri

  1. Sabit node_id: hostname: "vault-{{.Task.Slot}}.iklim.co" ayarı, Vault'un Raft node_id değerinin konteyner yeniden başlatmalarında asla değişmemesini sağlar. Bu olmasaydı, her yeniden başlatma yeni bir eş kimliği oluştururdu ve küme asla tekrar kurulamazdı.

  2. Entrypoint unseal döngüsü: Konteyner, 3 dakikaya kadar her 2 saniyede bir vault operator unseal komutunu dener. Bu, taze bir düğümün Raft'a katılana kadar unseal edilemediği "tavuk mu yumurta mı" durumunu kapsar — döngü, Raft katılımı başarılı olana kadar denemeye devam eder.

  3. vault_unseal_key Docker secret'ı: Unseal anahtarı, konteyner içinde her zaman /run/secrets/vault_unseal_key konumunda mevcuttur. Herhangi bir yeniden başlatmadan sonra hiç kimsenin anahtarı yazması gerekmez.

  4. Paylaşılan takma ad ile retry_join: Tüm düğümler vault.iklim.co:8200 (hizmet VIP'si / overlay takma adı) adresini işaret eder. Swarm bunu çalışan herhangi bir sağlıklı konteynere yük dengeler (load-balance), böylece yeni bir düğüm, hangi eşin mevcut lider olduğunu bilmesine gerek kalmadan kümeyi her zaman bulabilir.