Updates README.md with the new Shamir-based auto-unseal process using Docker secrets, eliminating the need for a separate transit vault. Adds `failover_scenarios.md` to detail the Vault cluster's resilience under various failure conditions. Translates `vault-bootstrap.sh` messages and step titles from Turkish to English, and aligns its execution flow with the updated documentation.
10 KiB
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ış:
- Docker Swarm görevi (task) başarısız olarak işaretler.
max_replicas_per_node: 1ayarı 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. - Kalan 2 düğüm (1 lider + 1 takipçi) çoğunluğu korur. Küme, isteklere normal şekilde hizmet vermeye devam eder.
- Host makine geri gelip Swarm'a tekrar katıldığında, Swarm görevi hemen üzerinde zamanlar.
- Konteyner başlar, Raft verilerini sağlam bulur, lider ile
retry_joinüzerinden bağlantı kurar ve saklanan log indeksinden devam eder. - Entrypoint unseal döngüsü
/run/secrets/vault_unseal_keydosyasını okur ve düğümü otomatik olarak unseal eder. - 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ış:
- Swarm, görevi (şimdi temiz olan) host makine üzerinde zamanlar.
- Konteyner boş bir veri dizini ile başlar (
security barrier not initialized). 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.- Başarılı bir katılımda lider, tam Raft günlüğünü yeni düğüme aktarır (
previous-index=<leader> → last-index=1). Initialized: trueolduğunda, entrypoint unseal döngüsü düğümü başarıyla unseal eder.- Düğüm, Raft seçim sonucuna bağlı olarak
standby(takipçi) veyaactive(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ış:
- Hayatta kalan iki takipçi, Raft kalp atışı zaman aşımı (~5–10 sn) üzerinden lider kaybını tespit eder. Bunlardan biri Raft seçimini kazanır ve yeni lider olur.
- Küme, yeni lider ile isteklere hizmet vermeye devam eder. Herhangi bir konfigürasyon değişikliği gerekmez —
vault.iklim.cooverlay takma adı, çalışan tüm konteynerlere round-robin (sırayla) dağıtım yapar. - 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ış:
- Çoğunluk kaybolur (3 düğümden sadece 1'i hayatta).
- 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.
- Çöken iki host makineden herhangi biri geri gelip Vault konteyneri başladığında, çoğunluk geri yüklenir (3 düğümden 2'si).
- Raft tekrar bir lider seçer. Küme normal operasyona döner.
- Üçü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ış:
- Host makineler geri geldiğinde, Swarm üç Vault görevini de zamanlar.
- Setiap konteyner başlar ve Raft verilerini sağlam bulur (volume'lar yeniden başlatmalarda korunur).
- Raft, üç düğüm arasında bir lider seçer (en yüksek Raft
CommitIndexdeğerine sahip olan düğüm kazanır). - Üç düğümün tamamı entrypoint döngüsü üzerinden otomatik olarak unseal edilir.
- 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 1–4 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
-
Sabit
node_id:hostname: "vault-{{.Task.Slot}}.iklim.co"ayarı, Vault'un Raftnode_iddeğ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ı. -
Entrypoint unseal döngüsü: Konteyner, 3 dakikaya kadar her 2 saniyede bir
vault operator unsealkomutunu 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. -
vault_unseal_keyDocker secret'ı: Unseal anahtarı, konteyner içinde her zaman/run/secrets/vault_unseal_keykonumunda mevcuttur. Herhangi bir yeniden başlatmadan sonra hiç kimsenin anahtarı yazması gerekmez. -
Paylaşılan takma ad ile
retry_join: Tüm düğümlervault.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.