# 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 — Monitoring & SWAG Failover SWAG, cert-reloader, Prometheus ve Grafana cluster-native (replicated) değildir; her zaman tek instance çalışırlar ve varsayılan olarak `iklim-app-01`'e (Floating IP node) sabitlenmişlerdir. `iklim-app-01` çöktüğünde bu servisler durur; DNS/HTTPS erişimi ve izleme (monitoring) kesilir. Swarm quorum 2 manager ile devam eder; mikroservisler ve Vault başka node'lara taşınır. Tüm bu servislerin verileri ve konfigürasyonları StorageBox'ta tutulur: - **SWAG:** `/mnt/storagebox/swag/config` - **SSL:** `/mnt/storagebox/ssl` - **Prometheus:** `/mnt/storagebox/prometheus/data` - **Grafana:** `/mnt/storagebox/grafana/data` ## Prod Senaryo: `iklim-app-01` Çöktü ### 1. Servisleri Başka Node'a Taşı SWAG ve cert-reloader birlikte taşınmalıdır. Prometheus ve Grafana da bağımsız olarak veya aynı anda taşınabilir. ```bash # iklim-app-02 veya iklim-app-03 üzerinde (aktif manager): # SWAG & Cert-Reloader taşıma 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 # Prometheus & Grafana taşıma docker service update --constraint-add "node.hostname == iklim-app-02" --constraint-rm "node.hostname == iklim-app-01" iklimco_prometheus docker service update --constraint-add "node.hostname == iklim-app-02" --constraint-rm "node.hostname == iklim-app-01" iklimco_grafana ``` ### 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. ### 3. Doğrula ```bash docker service ls | grep -E 'swag|cert-reloader|prometheus|grafana' curl -si https://api.iklim.co/health ``` ### `iklim-app-01` Geri Döndüğünde Node Swarm'a yeniden katıldıktan sonra tüm servisleri tekrar `iklim-app-01`'e taşıyıp Floating IP'yi geri aktarabilirsiniz. ```bash # Servisleri geri taşı for svc in iklimco_swag iklimco_cert-reloader iklimco_prometheus iklimco_grafana; do docker service update --constraint-add "node.hostname == iklim-app-01" --constraint-rm "node.hostname == iklim-app-02" $svc done # Floating IP'yi iklim-app-01'e geri ata 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 | | Prometheus, Grafana | Manuel — `docker service update --constraint-*` | | Veriler & Konfig | StorageBox'ta; failover node hemen erişir, veri kaybı yaşanmaz |