Add the Ansible README and expand prod bootstrap coverage for StorageBox keys, DB labels, DB stack configuration, and act runner setup. Update MongoDB configuration for replica set support and refresh prod roadmap/setup documentation for Swarm labels, StorageBox-backed cert paths, and recovery guidance.
157 lines
5.4 KiB
Markdown
157 lines
5.4 KiB
Markdown
# 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 <eski-node-id>
|
||
|
||
# 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 <id>` (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 <floating-ip-id> <iklim-app-02-server-id>
|
||
```
|
||
|
||
**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 <floating-ip-id> <iklim-app-01-server-id>
|
||
```
|
||
|
||
## Ö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 |
|