Đây là bài cuối của series Cloud VPS. Sau khi đi qua từng tầng balancer, minion, database cùng các lớp tự động hoá và phòng thủ, đã đến lúc nhìn lại một cách thẳng thắn: mô hình này làm tốt điều gì, thường yếu ở đâu, và khi số Cloud VPS tăng dần theo thời gian thì có nên gộp VPS hay không. Bài này tổng kết các bài học của series, liệt kê những điểm lỗi đơn điển hình của mô hình ba tầng, hướng dẫn cách lập phương án gộp VPS an toàn, và chỉ ra hướng đi tiếp theo.
1. Nhìn lại mô hình Cloud VPS qua series
Mô hình ba tầng trong bài Cloud VPS: mô hình Balancer – Minion – Database cho hàng trăm website PHP có khung rất ổn định. Thứ thay đổi theo thời gian là những lớp được đắp thêm lên nó:
| Nhóm | Việc chính | Bài liên quan |
|---|---|---|
| Nền tảng | Đặt tên máy, nginx reverse proxy, nhiều phiên bản PHP, MySQL đa tenant, certbot | DNS nội bộ, Nginx reverse proxy, MySQL đa tenant |
| Triển khai | Deploy tự động, ResponseCache và queue worker | Deploy tự động |
| Tự động hoá | Dựng lại máy bằng cloud-init, Jenkins điều khiển tác vụ, backup hằng đêm, self-healing | cloud-init, Jenkins, Backup database, Self-healing |
| Cô lập và phòng thủ | Pool FPM riêng, WAF, gom log, rate limit, Octane bằng systemd | PHP-FPM pool, Coraza WAF, Fluent Bit, Rate limit theo User-Agent, Octane bằng systemd |
Tất cả chỉ dùng công cụ quen thuộc: nginx, PHP-FPM, MySQL, supervisor, systemd. Đó vừa là điểm mạnh, vừa là nền để tính chuyện gộp VPS.
2. Những gì mô hình làm tốt
- Bề mặt tấn công nhỏ: chỉ balancer có IP public. Minion và database chỉ nghe trong mạng private.
- Cô lập theo site có tác dụng rõ: tách PHP-FPM pool riêng từng site làm lỗi
reached pm.max_childrencủa pool chung biến mất. Chuyển Octane sang systemd giúp một site bị OOM chỉ khởi động lại riêng nó trong vài giây. - Chặn sớm ở balancer: security snippet, WAF và rate limit trả 403, 429 hoặc 444 ngay tại balancer cho một phần đáng kể request rác, không tốn worker PHP nào.
- Tự động hoá đủ dùng, dễ hiểu: tạo site, deploy có rollback, backup, gia hạn SSL đều là pipeline; sự cố nào cũng đi theo đúng ba tầng là tìm ra chỗ hỏng.
3. Điểm yếu thứ nhất: không có HA, mỗi site sống trên đúng một máy
Nếu mỗi khối upstream trên balancer chỉ có một server, least_conn có khai cũng vô nghĩa. Hai kiểu sự cố điển hình, và cũng là lý do mọi phương án gộp VPS phải tính tới HA:
- Minion chết dần: một minion hỏng từ từ, error log của balancer đầy
upstream timed outtrỏ về cùng một máy, và cách duy nhất là chuyển tay site đi. - Cả nhóm upstream cùng chết: kể cả khi upstream có vài server, nếu chúng cùng bị đánh dấu down vì một nguyên nhân chung (database chậm, deploy lỗi), nginx trả
no live upstreamscho mọi request.
Bản thân balancer cũng là điểm lỗi đơn: một balancer hỏng thì mọi site đứng sau nó cùng ngừng, và nếu không có IP nổi thì không chuyển được sang máy khác. Giải pháp kinh điển là cặp balancer dùng keepalived (VRRP): một IP nổi chuyển giữa hai máy khi một máy chết.
4. Điểm yếu thứ hai: dữ liệu và dung lượng đĩa
Đây cũng là tầng khó gộp VPS nhất. Để tiết kiệm tài nguyên trên VPS nhỏ, nhiều hệ thống MySQL đa tenant tắt binlog (skip-log-bin): không binlog, không replica, không khôi phục được về thời điểm bất kỳ. An toàn dữ liệu khi đó dựa hoàn toàn vào bản mysqldump hằng đêm. Nếu máy database hỏng đĩa lúc chiều, dữ liệu từ lần dump đêm trước tới lúc đó sẽ mất.
Dung lượng đĩa là quả bom hẹn giờ thứ hai. Database bản sao để thử nghiệm, log không xoay vòng, backup để quên trên máy hay lấp đầy đĩa. Cảnh báo chỉ có ích khi có quy trình dọn đi kèm, nếu không đĩa đầy sẽ chặn đường gộp VPS.
# database nào chiếm nhiều chỗ nhất: ứng viên dọn trước khi gộp VPS
mysql -e "SELECT table_schema, ROUND(SUM(data_length+index_length)/1024/1024) AS mb
FROM information_schema.tables GROUP BY table_schema ORDER BY mb DESC LIMIT 10;"5. Điểm yếu thứ ba: cấu hình không đồng nhất giữa các máy
Mỗi cải tiến thường được làm trên một vài máy trước. Nếu không có bước rà soát, nhiều cải tiến dừng ở đó: balancer này có WAF, balancer kia chưa; máy này có fail2ban, máy kia không; một minion cũ vẫn dùng pool PHP-FPM chung. Một bảng kiểm "thành phần nào đang có trên máy nào" nên được sinh tự động định kỳ, thay vì dựa vào trí nhớ.
Một triệu chứng khác của cùng căn bệnh: pipeline và cảnh báo không được dọn theo máy. Máy đã gỡ nhưng job xoá cache vẫn SSH tới, job gia hạn SSL vẫn chạy và báo đỏ vì không phân giải được tên máy, Grafana còn rule cảnh báo cho máy không còn tồn tại. Gốc của mọi chuyện này là thiếu một nơi mô tả trạng thái mong muốn của toàn hệ thống, như Ansible hay một công cụ hạ tầng dạng code, nên mỗi máy dần trở thành một "bông tuyết". Gộp VPS mà không sửa được chuyện này thì chỉ là dồn nhiều bông tuyết vào ít máy hơn.
6. Cách lập phương án gộp VPS
Khi ứng dụng đã được tối ưu (sửa N+1 query, bật cache), giám sát thường cho thấy nhiều máy nhàn rỗi phần lớn thời gian, và nhiều site nhỏ bị xé lẻ trên quá nhiều Cloud VPS. Gộp VPS là hướng tự nhiên, nhưng phương án gộp VPS nên theo các nguyên tắc sau:
- Đo trước khi gộp VPS. Lấy CPU, RAM, đĩa của từng máy trong giờ cao điểm từ Prometheus, không lấy trung bình cả ngày.
- Không đụng các cụm khách thuê hạ tầng riêng. Mỗi cụm giữ nguyên balancer, minion và database của mình.
- Dọn trước, gộp sau. Rà các website đã hết hợp đồng, domain test cũ, site đã chuyển đi. Backup lên object storage rồi gỡ.
- Cô lập trước, gộp VPS sau. Mỗi site có pool FPM riêng, mỗi site Octane một unit systemd có
MemoryMax, trước khi dồn về chung máy. - Dùng phần tiết kiệm từ gộp VPS để mua an toàn: HA cho balancer và replica cho database.
| Tầng | Câu hỏi khi gộp VPS | Điều kiện trước khi gộp |
|---|---|---|
| Balancer | Một balancer chết thì bao nhiêu site ngừng? | Cặp balancer với keepalived, cấu hình đồng nhất |
| Minion | Tổng worker và MemoryMax có nằm dưới RAM thật? | Pool FPM riêng, Octane cô lập, ngân sách bộ nhớ |
| Database | Đĩa còn đủ chỗ? Mất máy thì mất bao nhiêu dữ liệu? | Dọn database thử nghiệm, bật binlog hoặc replica |
7. Ba điều cần biết khi thực hiện gộp VPS
- Gộp VPS làm tăng phạm vi ảnh hưởng. Mười site trên một máy thì một site lỗi có thể kéo chín site kia. Vì vậy cô lập phải đi trước: đó là lý do bài về PHP-FPM pool và bài về Octane bằng systemd là điều kiện tiên quyết.
- Đĩa và RAM giới hạn tốc độ gộp VPS. Máy database đĩa gần đầy không thể nhận thêm database. Minion Octane vẫn có thể hết RAM cả máy dù từng site đều có giới hạn riêng, nếu tổng giới hạn vượt RAM thật.
- Gỡ máy phải gỡ cả "bóng" của nó. Mỗi máy gỡ đi trong đợt gộp VPS để lại pipeline, rule cảnh báo, bản ghi DNS nội bộ trỏ vào nó. Trước khi gỡ,
greptên máy trong cấu hình nginx, DNS, Prometheus và Jenkins.
8. Bài học sau series Cloud VPS
- Đơn giản là lợi thế thật. Một đội nhỏ vận hành được hàng trăm site trên nhiều Cloud VPS cấu hình nhỏ vì mọi thứ đều nhìn thấy và sửa được bằng SSH.
- Đo trước, sửa sau. Những cải tiến hiệu quả nhất (pool riêng, rate limit theo User-Agent) đều bắt đầu từ việc đếm dòng log, không phải từ cảm giác.
- Cô lập rẻ hơn mở rộng. Tách pool, tách service tốn ít tiền hơn thêm máy, giải quyết đúng vấn đề "một site kéo cả máy", và là điều kiện để gộp VPS an toàn.
- Thiếu HA và thiếu binlog là hai món nợ lớn nhất. Mọi lớp phòng thủ khác đều không bù được việc một máy chết là site chết, hay một ổ đĩa hỏng là mất dữ liệu trong ngày. Bước tối thiểu cho database là bật binlog và dựng replica theo tài liệu replication của MySQL cho các máy quan trọng.
- Cấu hình phải có một nguồn sự thật. Script shell trong Jenkins giúp làm nhanh, nhưng không ngăn được việc các máy dần khác nhau.
9. Hướng đi tiếp: Kubernetes
Song song với mô hình Cloud VPS, một phần website của chúng tôi chạy trên Kubernetes. Kubernetes giải quyết đúng điểm yếu ở mục 3 và 5: mỗi site nhiều pod, pod chết được thay tự động, deploy rolling, giới hạn tài nguyên khai báo trong chart và áp đồng nhất. Đổi lại là độ phức tạp cao hơn, và nó không chữa được code rò bộ nhớ: pod vượt giới hạn vẫn bị OOMKilled.
Đây không phải chuyện chọn một bỏ một. Gộp VPS và chuyển dần lên Kubernetes có thể chạy song song. Cloud VPS vẫn hợp với site nhỏ, site cũ khó đóng gói container, và khách cần một cụm máy riêng. Kubernetes hợp với các sản phẩm cần mở rộng và triển khai thường xuyên. Câu chuyện đó, từ Docker hoá Laravel, Helm chart dùng chung đến CI/CD và các sự cố trên cụm, nằm trong series Kubernetes & CI/CD tại Sudo ở chuyên mục blog kỹ thuật của Sudo.
Kết series
Cảm ơn bạn đã theo dõi series Cloud VPS. Mô hình Balancer – Minion – Database không hoàn hảo, nhưng nó chạy được hàng trăm website với chi phí thấp, và mỗi sự cố đều để lại một bài học cụ thể. Nếu bạn đang vận hành một hệ thống tương tự và tính chuyện gộp VPS, hãy nhớ thứ tự: đo, dọn, cô lập, rồi mới gộp.
Câu chuyện tiếp theo, khi chúng tôi đưa Website AI lên container và Kubernetes, nằm ở series Kubernetes & CI/CD; các sự cố và bài học vận hành được gom trong series Vận hành thực chiến.
