# Docker Swarm — Node Recovery Test ortamında tek manager (`iklim-app-01`) ve tek worker (`iklim-db-01`) bulunur. Hangi node'un yeniden kurulduğuna göre recovery süreci farklılaşır. ## Senaryo 1: `iklim-app-01` (Manager) Yeniden Kurulur ### Sorun Yeni `iklim-app-01` üzerinde `docker swarm init` farklı cluster ID ile yeni bir küme başlatır. `iklim-db-01` hâlâ eski kümeye bağlıdır. Ansible `swarm` role'u `iklim-db-01`'de Swarm'ı `active` görür, join denemez. İki node iki ayrı kümede kalır. ### Çözüm ```bash # 1. iklim-db-01 üzerinde — eski kümeden çık docker swarm leave --force # 2. Ansible ile her iki node'u yeniden kur cd ansible/test ansible-playbook -i inventory/generated/test.yml test-bootstrap.yml --ask-vault-pass # 3. DB stack'i yeniden deploy et ansible-playbook -i inventory/generated/test.yml test-db-post-stack.yml --ask-vault-pass ``` DB verileri `iklim-db-01`'deki named volume'larda korunur, kayıp yaşanmaz. --- ## Senaryo 2: `iklim-db-01` (Worker) Yeniden Kurulur ### Durum Yeni `iklim-db-01` Swarm'dan habersiz başlar (`inactive`). Manager (`iklim-app-01`) eski dead node kaydını tutar. ### Çözüm ```bash # 1. Ansible bootstrap — yeni node otomatik join olur cd ansible/test ansible-playbook -i inventory/generated/test.yml test-bootstrap.yml --ask-vault-pass # 2. iklim-app-01 üzerinde — eski dead node kaydını temizle docker node ls # eski node ID'yi bul docker node rm # 3. DB stack'i yeniden deploy et (backup'tan restore sonrası) ansible-playbook -i inventory/generated/test.yml test-db-post-stack.yml --ask-vault-pass ``` Ansible `swarm` role'u `inactive` durumu gördüğü için token alıp join eder, `role=db` label'ını uygular. DB servisleri placement constraint sayesinde yeni node'a schedule edilir. --- ## Senaryo 3: Her İki Node Yeniden Kurulur Her şey sıfırdan kurulur, Swarm uyumsuzluğu yaşanmaz. ```bash cd ansible/test ansible-playbook -i inventory/generated/test.yml test-bootstrap.yml --ask-vault-pass ansible-playbook -i inventory/generated/test.yml test-db-post-stack.yml --ask-vault-pass ``` --- ## Özet | Senaryo | Manuel Adım | Ansible Yeterli mi? | |---|---|---| | Manager (`iklim-app-01`) ölür | `docker swarm leave --force` (worker'da) | Sonrasında evet | | Worker (`iklim-db-01`) ölür | `docker node rm ` (manager'da) | Büyük ölçüde evet | | Her ikisi ölür | Yok | Evet | ## Neden Prod'da Bu Sorun Yok Prod ortamında birden fazla manager node (en az 3) çalıştırılır. Tek manager düşse diğerleri liderliği devralır, küme sağlıklı kalmaya devam eder. --- # Prod — SWAG Failover SWAG cluster-native değildir; her zaman tek instance çalışır ve `iklim-app-01`'e (Floating IP node) sabitlenmiştir. `iklim-app-01` çöktüğünde SWAG ve cert-reloader da durur; DNS ve HTTPS erişimi kesilir. Swarm quorum 2 manager ile devam eder; mikroservisler ve Vault başka node'lara taşınır. SWAG konfigürasyonu (`/config`, letsencrypt sertifikaları dahil) StorageBox'ta tutulduğu için (`SWAG_CONFIG_DIR=/mnt/storagebox/prod/swag/config`) manuel failover hızlı yapılabilir. ## Prod Senaryo: `iklim-app-01` Çöktü ### 1. SWAG'ı Başka Node'a Taşı ```bash # iklim-app-02 veya iklim-app-03 üzerinde (aktif manager): docker service update \ --constraint-add "node.hostname == iklim-app-02" \ --constraint-rm "node.hostname == iklim-app-01" \ iklimco_swag docker service update \ --constraint-add "node.hostname == iklim-app-02" \ --constraint-rm "node.hostname == iklim-app-01" \ iklimco_cert-reloader ``` SWAG StorageBox'taki mevcut letsencrypt sertifikalarını bulur; yeni sertifika talep etmez. cert-reloader yeni node'da başlar ve `/mnt/storagebox/prod/ssl`'e yazar. ### 2. Floating IP'yi Yeni Node'a Taşı **CLI ile:** ```bash hcloud floating-ip assign ``` **Hetzner Cloud Console (web) ile:** 1. [console.hetzner.cloud](https://console.hetzner.cloud) adresine giriş yap. 2. Sol menüden ilgili projeyi seç (`iklim_prod`). 3. Sol menüden **Floating IPs** sekmesine gir. 4. `iklim-prod-app-fip` satırının sağındaki **⋮** (üç nokta) menüsünü aç → **Reassign**. 5. Açılan listeden **`iklim-app-02`**'yi seç → **Reassign** butonuna tıkla. DNS A kaydı zaten Floating IP'yi gösterdiği için ek DNS değişikliği gerekmez. ### 3. Doğrula ```bash docker service ps iklimco_swag docker service ps iklimco_cert-reloader curl -si https://api.iklim.co/health ``` ### `iklim-app-01` Geri Döndüğünde Node Swarm'a yeniden katıldıktan sonra servisleri tekrar `iklim-app-01`'e taşı ve Floating IP'yi geri aktar: ```bash docker service update \ --constraint-add "node.hostname == iklim-app-01" \ --constraint-rm "node.hostname == iklim-app-02" \ iklimco_swag docker service update \ --constraint-add "node.hostname == iklim-app-01" \ --constraint-rm "node.hostname == iklim-app-02" \ iklimco_cert-reloader hcloud floating-ip assign ``` ## Özet | Bileşen | Failover davranışı | |---------|-------------------| | Swarm quorum | Otomatik — 2 manager yeterli | | Vault, mikroservisler | Otomatik — `node.labels.type == service` constraint ile başka node'a schedule edilir | | SWAG, cert-reloader | Manuel — `docker service update --constraint-*` + Floating IP taşıma | | TLS sertifikaları | StorageBox'ta; failover node hemen erişir, yeniden istek gerekmez |