Từ kiến thức mạng máy tính tới thiết kế và triển khai hệ thống
Thiết kế hệ thống

Từ kiến thức mạng máy tính tới thiết kế và triển khai hệ thống

Tư Nguyễn Khắc
Tư Nguyễn Khắc
22 tháng 5, 20259 phút đọc

Hi, xin chào tất cả các bạn, hôm nay mình xin được chia sẻ cách mình đã áp dụng kiến thức về mạng máy tính để triển khai hệ thống bán điều hoà cho anh hàng xóm như thế nào nhé. 

Tại sao lại là hệ thống bán điều hoà?

Chả là vào một đêm nọ, chuẩn bị đến giờ đi ngủ rồi, tình cờ mình lướt facebook và đọc được một bài viết nói về Vibe coding (có vẻ đang là trend coding hiện nay), với sự tò mò của một dev quèn, mình lại mở máy tính lên, theo hướng dẫn trên mạng và cũng thử Vibe coding. Tưởng không có gì mà lại cuốn không tưởng, mình hăng say với những dòng lệnh và quên mất rằng đang bỏ quên vợ nằm chờ sẵn rồi. Thế là, kết quả các bạn chắc cũng đoán được rồi đấy, mình bị vợ đuổi, không cho ngủ giường nữa, ra ngoài phòng khách ngủ sofa. 

Và thế là, nằm mãi không ngủ được, như có gì đó thôi thúc, đêm trăng thanh gió mát, mình xuống sảnh chung cư hóng tí gió cho dễ ngủ. Đang thong dong, thì chợt đâu có một giọng nói vang lên:

- Sao giờ này rồi chú vẫn còn xuống đây, chưa đi ngủ à!

Ngoái lại sau lưng thì ra là ông anh hàng xóm, thế mà mình cứ tưởng là ... :v 

Hai anh em đi dạo tâm sự, thì ra là ông anh cũng vừa làm vợ giận, cũng bị chung cảnh ngộ giống mình :v Hai anh em tâm sự linh tinh, ông anh có khoe dạo này mới vào mùa hè, cửa hàng điều hoà của ông anh cháy hàng, hàng về đến đâu là bán hết đến đó. Ông anh muốn nhân cơ hội này mở rộng kinh doanh trên internet, thế là có ngỏ ý nhờ mình viết hộ web bán điều hoà trực tuyến. Giai đoạn bắt đầu nên chức năng của web khá đơn giản, đại khái là người dùng có thể lên web, tìm kiếm sản phẩm, xem thông tin sản phẩm, đặt hàng, thanh toán, feedback về sản phẩm. Nhưng với điều kiện là chi phí triển khai rẻ thôi em nhớ, anh chị còn đang xoay vòng vốn đề lấy hàng nên không dư nhiều :v 

- À, đợt này anh thấy trên TiVi người ta nói nhiều về cái Trí Tuệ Nhân Tạo AI gì đó, chú xem có làm cho anh một em trợ lý ảo nuột nà, tư vấn người dùng, hướng dẫn họ sử dụng sản phẩm và tích hợp nó vào website được không?

- Okie anh luôn, a cứ để em.

Sau đó mình bắt đầu bước vào quá trình xây dựng web bán điều hoà cho ông anh. Bản thân mình là một dev backend Java quèn, nhưng do yêu cầu về chi phí nên mình khá đắn đo, cuối cùng mình chọn Golang và framework là Gin để làm backend cho hệ thống, vì mình có nghiên cứu và thấy rằng benchmark về memory thì Golang cho kết quả khá tốt, Java khá ngốn RAM. Kết quả mình đo được khi run Golang thì RAM chỉ tốn 17-20MB (trạng thái không tải), còn bình thường Java spring boot cũng cỡ 200MB (không tải). Rõ ràng chi phí để chạy một VPS cho Golang tối ưu hơn so với Java. Trong quá trình đó mình cũng load và stress testing sử dụng Grafana K6, với tải cao thì Golang Gin cũng đạt kết quả khá tốt. Hiện tại ở bài viết này mình không tập trung vào Performance testing nên hẹn các bạn ở bài viết khác mình sẽ viết chi tiết nhé, cụ thể từng thông số khi Performance testing.

Dev xong rồi, triển khai như thế nào?

Image
Click to zoom

Bạn có thể thấy theo sơ đồ triển khai này tôi có sử dụng:

  • 1 VPS Application: Dùng để chạy backend, front end
  • 1 VPS Database: Dùng để cài đặt và chạy MySQL
  • 1 VPS Bastion: VPS này cài các công cụ phục vụ monitoring toàn bộ hệ thống

Tất cả hệ thống được setup trên Cloud Provider, mình không sử dụng AWS vì chi phí khá cao mà traffic của hệ thống chủ yếu đến từ trong nước, nên mình lựa chọn mua VPS từ Cloud Provider. Ví dụ: Để tiết kiệm chi phí thì Bastion VPS bước đầu mình running với 1vCPU và 1GB RAM, đâu đó tốn khoảng 70K/1 tháng, khá rẻ. 

Tất cả các VPS đều có nhu cầu kết nối ra internet nên đều có IP Public. Tuy nhiên, nếu như vậy thì phát sinh vấn đề là:

MySQL rất dễ bị tấn công. Dù sao thì, phơi public IP của MySQL, mặc dù có firewall nhưng với kinh nghiệm vận hành của mình là không nhiều (vì chủ yếu mình làm dev backend), nguy cơ MySQL bị tấn công là rất có thể. Vì sao mình lại quan tâm tới việc MySQL bị tấn công, bởi vì dữ liệu là trái tim của hệ thống, dữ liệu về khách hàng, đơn hàng, lịch sử thanh toán, tất cả các mặt hàng đều được lưu trữ trong CSDL. 

Vậy thì, liệu mình có thể không cần IP Public hay không? Tức là không phơi MySQL trực tiếp ra ngoài internet. Câu trả lời chắc chắn là có, bởi vì MySQL server đang được đặt trong VPC, hiện tại nó đã có IP Internal. Tuy nhiên, nếu chỉ có IP Internal thì MySQL server không thể kết nối internet, mỗi khi cần update phiên bản của bất kì công cụ nào đó trên VPS thì mình không thể kết nối ra bên ngoài để update các package. 

Vậy thì làm cách nào VPS này có thể kết nối ra bên ngoài Internet mà không cần IP Public?

Các bạn đã và đang làm AWS có thể nói là, dễ mà, dùng NAT Gateway là xong , tuy nhiên ở đây nhà cung cấp không cung cấp cho mình tính năng này, vậy thì làm sao mình có thể tạo NAT Gateway cho hệ thống của mình? 

Quay lại với kiến thức mạng cơ bản

Khi mọi người sử dụng máy tính ở nhà và lướt web, mọi người có nhớ tại sao máy tính của chúng ta không hề có IP Public, chỉ có Internal IP (thường là 192.168.1.x) mà chúng ta vẫn kết nối được internet, lướt web, xem phim, ...

 

Câu trả lời đó chính là: Nhờ vào kĩ thuật NAT (Network Address Translation) của Router mà nhà mạng đã lắp cho nhà bạn đó. 

Giả sử bạn đang xem phim từ youtube, bản chất thì máy của bạn và server của youtube đang trao đổi gói tin qua lại với nhau. Hình dưới đây là minh hoạ cho luồng trao đổi này.

Image
Click to zoom

Mô tả ngắn gọn như sau 

  • (1) máy của bạn gửi gói tin qua router có địa chỉ local là 192.168.1.1. Tại đây router sử dụng kĩ thuật NAT, thay đổi địa chỉ IP nguồn (192.168.1.12) thành địa chỉ IP public của Router và gửi tới ISP (2).
  • (3) IPS tiếp tục chuyển tiếp gói tin này ra ngoài internet, sau khi qua các hệ thống router thì gói tin tới Youtube server. Youtube server xử lý và gửi gói tin phản hồi tới ISP (4), ISP tiếp tục gửi lại gói tin này về Router của bạn (5)
  • (6) Tiếp tục là kĩ thuật NAT, Router dựa vào lần NAT trước và biết được rằng gói tin đó cần được chuyển về 192.168.1.12 và tiến hành đổi destination IP từ IP public của router thành IP local của máy tính.

Quá trình cứ thế với các gói tin khác, vậy là máy tính của bạn không cần public IP mà vẫn truy cập được internet nhờ vào kĩ thuật NAT của Router.

Để làm rõ hơn, tại sao máy tính của bạn có địa chỉ 192.168.1.12 lại biết rằng khi gửi gói tin tới server của Youtube lại phải gửi thông qua 192.168.1.1 (Router). Đó chính là dựa vào route table. Ví dụ dưới đây là Route table của máy mình dùng Ubuntu.

Image
Click to zoom

Bạn thấy không, IP của Youtube không nằm trong danh sách của Route table nên mặc định nó sẽ được gửi qua Gateway là 192.168.1.1 thông qua địa chỉ MAC của Router. 

À, bạn cũng bắt đầu suy nghĩ giống mình rồi đúng không, cách để xây dựng NAT Gateway chính là dựa vào nguyên lý này của mạng máy tính. 

Thay sơ đồ mạng trên bằng sơ đồ VPS mà mình đang triển khai thì được như sau:

Image
Click to zoom

Ở đây, mình tận dụng luôn Bastion VPS để thực hiện kĩ thuật NAT, tức là đã biến Bastion VPS làm NAT Gateway cho hệ thống của mình.

Các VPS mình sử dụng đều dùng Ubuntu nên mình có thể mô tả cách thức triển khai như sau.

Trên VPS chạy MySQL, mình sử dụng các lệnh sau:

bash
123
sudo ip route del default sudo ip route add default via 172.17.0.3 echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

Sau khi chạy lệnh trên thì VPS chạy MySQL mặc định sử dụng Bastion VPS làm Gateway để gửi gói tin khi nó gửi các gói tin tới địa chỉ đích nằm ngoài range IP của VPC (gửi gói tin ra ngoài internet).

Tiếp theo, trên Bastion VPS mình setup NAT như sau:

bash
12
sudo iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE

Lệnh này cấu hình cho Linux làm NAT, cụ thể là dịch địa chỉ IP của máy trong mạng nội bộ (172.16.0.0/24) thành IP public của interface eth0, trước khi ra Internet.

  • iptables: Công cụ cấu hình tường lửa & NAT
  • -t nat: Chọn bảng NAT (dùng cho các thao tác dịch địa chỉ IP)
  • -A POSTROUTING: Thêm luật vào chain POSTROUTING (khi gói sắp rời máy)
  • -s 172.16.0.0/24: Áp dụng luật cho gói có IP nguồn trong mạng nội bộ
  • -o eth0: Chỉ áp dụng cho gói đi ra cổng eth0 (thường là cổng ra Internet)
  • -j MASQUERADE: Thực hiện hành động giả mạo IP (dùng IP hiện tại của eth0 làm IP nguồn)

Trước đó ta cần bật IP forwarding trên Bastion VPS:

bash
12
echo 1 > /proc/sys/net/ipv4/ip_forward sudo sysctl -w net.ipv4.ip_forward=1

Dù NAT đã được cấu hình, Linux vẫn sẽ không chuyển tiếp gói từ interface này sang interface khác nếu chưa bật ip_forward. Gói tin từ máy 172.16.0.x gửi ra Internet sẽ bị chặn lại, không đi tiếp qua eth0.

Vậy là mình đã cấu hình để Bastion VPS trở thành NAT Gateway, giúp MySQL server VPS có thể kết nối internet mà không cần public IP. Giúp giảm thiểu tối đa khả năng bị scanning và tấn công brute-force.

Cuối cùng, mình có sơ đồ triển khai tổng quát cho giai đoạn đầu như sau:

Image
Click to zoom

Tổng kết

Trên đây là chia sẻ của mình từ góc nhìn là một Backend Developer, chưa có nhiều kinh nghiệm tự tay triển khai và vân hành hạ tầng (Vì chủ yếu được support bởi System Admin và các bạn Devops). Độc giả blog, các bạn, anh/chị/em đã có nhiều kinh nghiệm, mình rất mong nhận được những ý kiến đóng góp để mình ngày càng hoàn thiện hạ tầng triển khai cho hệ thống bán điều hoà, cũng như nâng cao kiến thức, kĩ năng và kinh nghiệm. À, một thông điệp khá quan trọng từ bài viết này. Nếu các bạn còn đang là sinh viên, hãy dành thời gian để học thật vững các kiến thức nền tảng: Mạng máy tính, Cấu trúc dữ liệu & Giải thuật, Kiến trúc máy tính, Hệ điều hành. Vì công nghệ sẽ luôn thay đổi — hôm nay là Docker, Kubernetes, ngày mai có thể là một điều hoàn toàn mới. Nhưng nền tảng là thứ không bao giờ lỗi thời, là gốc rễ để bạn hiểu, thích nghi và phát triển trong mọi hoàn cảnh kỹ thuật.

Xin cảm ơn tất cả các bạn đã theo dõi bài viết của mình, hẹn gặp lại trong các bài viết tiếp theo. Rất mong nhận được những ý kiến đóng góp để mình có thể giao lưu và học hỏi nhiều hơn với các bạn, anh/chị/em nhé ạ!

Bình luận

Bình luận (0)

Vui lòng đăng nhập để tham gia bình luận.