Trạng thái hạ tầng khi hoàn tất toàn bộ kế hoạch trong So sánh & Kế hoạch chuyển đổi — dùng làm đích ngắm chung cho cả team: mỗi hạng mục bên dưới hoặc đã có sẵn, hoặc gắn với một bước cụ thể (0A→3C) trong kế hoạch.
Khác biệt so với hiện tại được đánh dấu MỚI. Mọi thứ không đánh dấu là giữ nguyên từ hệ thống đang chạy.
firewall-ssh — đã vá MỚI · 0A/0Bset_real_ip_from) · :22 giới hạn IP admin/VPN · port data vẫn default-denysync-nginx.sh (1C)Mỗi nhãn MỚI · x trỏ về đúng một bước trong kế hoạch chuyển đổi (0A, 0B, 1A…3C). Khi một bước hoàn thành, hạng mục tương ứng trên sơ đồ này chuyển từ "đích" thành "hiện trạng" — khi mọi nhãn đều xong, hai tài liệu hợp nhất làm một.
"Trước" là hiện trạng 04/07/2026. "Sau" là trạng thái khi hoàn tất kế hoạch.
| Chỉ số | Trước (hiện trạng) | Sau (đích) | Bước |
|---|---|---|---|
| Gateway nginx | 1 instance — SPOF trên V1 | 2 instance V1 + V4, Cloudflare LB health-check | 1A–1C |
| Firewall :80 vs danh sách trust nginx | Lệch 5/15 vs 15/15 — traffic thật có thể bị DROP | Khớp 15/15 | 0A |
| SSH :22 | Mở toàn Internet | Giới hạn IP admin/VPN (hoặc hardening thay thế có ghi nhận) | 0B |
| Double-processing giao dịch khi retry | Không có bảo vệ | Idempotency-Key trên mọi endpoint tiền | 1D |
| Connection tới Postgres | Không kiểm soát — 11 client tiềm năng vs max 100 | PgBouncer transaction mode, multiplex về ~20 conn thật | 2B, 3A |
| Redis auth | Không password — chỉ dựa firewall | requirepass/masterauth — 2 lớp độc lập | 3C |
| Failover data (V3 chết) | Thủ công, chưa văn bản hóa | Runbook promote slave (tự động hóa để sau) | 3C |
| Cấu hình nginx: keepalive / rate limit / timeout | Tắt / không có / 60s | Bật 32 / ≈20r/s / 15s-30s — gộp với DDoS Edge L0–L1 | 2C |
| OpenSearch | Vĩnh viễn yellow, không retention — index từ 04/2026 còn nguyên | replicas:0, ISM xoá theo ngày — green, disk ổn định | vệ sinh |
| Giám sát trạng thái container | Dozzle 4/4 unhealthy giả — báo động mất giá trị | Healthcheck đúng — unhealthy = sự cố thật | vệ sinh |
| Nhận diện server khi SSH | V2/V3 trùng hostname | Hostname duy nhất V1…V5 | vệ sinh |
Không thuê thêm server. Thay đổi duy nhất về bố trí: V4 nhận thêm nginx-lb #2 và PgBouncer đặt cạnh Postgres master trên V3.
| Server | Vai trò đích | Thay đổi so với hiện tại |
|---|---|---|
| V1 · CCX23 · 10.0.0.5 | Gateway #1 + App | Không đổi thành phần; bớt "duy nhất" — được phép bảo trì/deploy lỗi mà hệ vẫn sống |
| V2 · CCX13 · 10.0.0.4 | App | Số instance có thể giảm 4→2 theo kết quả đo 2A (2 vCPU); hostname đổi thành V2-Kiosk |
| V3 · CCX13 · 10.0.0.2 | Data master | + PgBouncer :6432 cạnh master; Redis thêm requirepass; hostname V3-Kiosk |
| V4 · CCX13 · 10.0.0.3 | Gateway #2 + Replica + Tools | + nginx-lb #2 (:80 — sau khi audit RAM, bước 1A); hostname V4-Kiosk |
| V5 · CCX23 · 10.0.0.6 | Gamify + Log hub | OpenSearch: replicas:0 + ISM retention; không đổi gì khác |
V3 và V4 là hai server "vừa khít" RAM 8GB: V3 = Redis 1.5GB + Postgres buffers/cache ~4GB; V4 = 7 container hiện có + nginx mới. nginx chỉ chiếm vài chục MB nên vừa, nhưng bất kỳ service nào thêm vào 2 server này sau bản đích đều phải tính lại tổng RAM trước — đó là lý do bước 1A có điều kiện tiền đề audit RAM.
Bảng "chết con nào, mất cái gì" — trước và sau chuyển đổi. Đây là thước đo trực tiếp của giá trị kế hoạch.
| Sự cố | Hệ quả TRƯỚC | Hệ quả SAU |
|---|---|---|
| V1 chết | Sập toàn hệ — mất gateway duy nhất, mọi domain chết dù V2–V5 còn sống | Hệ vẫn chạy — Cloudflare LB chuyển sang gateway #2 (V4) trong ~15–60s; mất tạm 4/8 instance API, còn 4 trên V2 gánh |
| V2 chết | Giảm nửa API — least_conn dồn về V1 | Như trước — không đổi (V2 chỉ chạy app) |
| V3 chết | Mất toàn bộ write path — promote slave thủ công, chưa có quy trình viết sẵn, thời gian phục hồi không đoán được | Vẫn mất write nhưng phục hồi theo runbook 3C có sẵn từng bước (promote PG slave :5433, đổi Redis replicaof, trỏ lại env backend) — thời gian phục hồi đo lường được |
| V4 chết | Mất replica + tools — không ảnh hưởng user | Mất gateway #2 + replica — Cloudflare LB dồn về gateway #1, user không ảnh hưởng; mất tạm khả năng failover data cho tới khi V4 hồi |
| V5 chết | Mất gamify + log tập trung — như nhau ở cả 2 trạng thái; gamify là SPOF riêng của tính năng gamification (chấp nhận ở bản đích v1, xem mục 06) | |
Chuyển đổi này xóa được kịch bản tệ nhất (V1 chết = sập toàn hệ) và biến kịch bản tệ nhì (V3 chết) từ "không đoán được" thành "có quy trình". Hai server còn lại chết chỉ gây suy giảm cục bộ — hệ vẫn phục vụ user.
Chuyển đổi được coi là hoàn tất khi tick đủ danh sách dưới — mỗi mục có lệnh/kịch bản kiểm chứng cụ thể, không nghiệm thu bằng cảm giác.
nginx-lb trên V1 (docker stop nginx-lb, giờ thấp điểm) → curl https://api.kioskservice.club vẫn trả 2xx trong vòng 60s (đi qua V4). Bật lại, lặp chiều ngược.set_real_ip_from trong default.conf.Idempotency-Key (môi trường dev) → đúng 1 giao dịch được ghi, response lần 2 trả kết quả lần 1.SHOW POOLS; trên :6432 có traffic; pg_stat_activity trên master đếm được ≤ 30 connection thật khi app đang chạy đủ tải.sync-nginx.sh với một thay đổi thử → conf trên V1 và V4 giống nhau từng byte (diff), cả hai nginx -t pass._cluster/health = green; index cũ hơn N ngày (theo policy) tự biến mất.docker ps cả 5 server không còn container unhealthy nào — mọi unhealthy từ nay là sự cố thật.Ghi rõ để không ai tưởng nhầm là bị quên — đây là các bước nâng cấp có chủ đích để lại sau, kèm điều kiện kích hoạt.
| Hạng mục | Lý do để lại | Kích hoạt khi |
|---|---|---|
| Cloudflare Full (strict) — TLS về origin | Cần cài Origin CA cert + nginx listen 443 trên cả 2 gateway; Flexible vẫn chạy ổn và firewall đã siết nguồn | Sau khi 2 gateway vận hành ổn định; hoặc yêu cầu compliance |
| Auto-failover data (Sentinel / Patroni) | Cần ≥3 node cho quorum + kỹ năng vận hành; runbook thủ công là bước đệm đúng tầm | Khi diễn tập runbook cho thấy RTO thủ công không chấp nhận được |
| HA cho V5 (gamify + log) | SPOF cục bộ của một tính năng, không phải core money-path | Khi gamification thành tính năng doanh thu chính |
| Kubernetes | Cả guideline lẫn bản so sánh đều bác — chi phí vận hành không tương xứng quy mô | Số service/team tăng gấp nhiều lần |
| OpenSearch bật security plugin | Port đã default-deny từ Internet; ưu tiên thấp hơn retention | Khi có yêu cầu audit nội bộ / thêm người truy cập Dashboards |