Hãy tưởng tượng bạn đang quản lý một hệ thống với hàng trăm dịch vụ nhỏ (microservices), mỗi dịch vụ hoạt động độc lập và cần liên tục trao đổi dữ liệu. Khi có một vấn đề như lỗi mạng, yêu cầu thất bại, hoặc quá tải dịch vụ, DevOps phải can thiệp để xử lý thủ công từng chi tiết: từ bảo mật, cân bằng tải đến giám sát hiệu suất. Công việc này không chỉ mất thời gian mà còn làm tăng rủi ro lỗi hệ thống.
Sau khi Service Mesh ra đời, DevOps không còn phải lo lắng về việc điều phối và bảo vệ từng dịch vụ nữa, đảm bảo các dịch vụ luôn giao tiếp an toàn và hiệu quả một cách tự động. Vậy Service Mesh là gì? Hãy cùng mình tìm hiểu trong bài viết này nhé.
1. Service Mesh là gì?
Service Mesh là một "infrastructure layer" giúp quản lý và kiểm soát cách các dịch vụ trong hệ thống Microservices. Nó cung cấp các tính năng quan trọng như bảo mật, giám sát, và quản lý lưu lượng (traffic management) mà không cần thay đổi mã nguồn của ứng dụng.
Về cơ bản các tính năng này của Service Mesh hoàn toàn có thể được phát triển ngay trong ứng dụng, nhưng nó sẽ làm tăng tính phức tạp của mã nguồn. Đội ngũ phát triển sẽ phải tự viết code để cung cấp các chức năng này, rất dễ gây lỗi và khiến các lập trình viên mất nhiều thời gian hơn vào các tác vụ “ẩn” thay vì tập trung vào những chức năng chính của ứng dụng.
2. Chức năng của Service Mesh
2.1 Tăng cường bảo mật (Security)
- Hệ thống Monolithic: Là ứng dụng lớn chạy dưới dạng một tiến trình (process) trong hệ điều hành. Nhờ vậy, hệ điều hành có thể bảo vệ ứng dụng bằng cách không cho phép các tiến trình khác "nhìn" hoặc chỉnh sửa nội dung bên trong ứng dụng. Các phần của ứng dụng giao tiếp với nhau qua các lời gọi hàm (function calls) trong cùng một không gian bộ nhớ. Điều này giúp bảo mật tốt hơn và tránh được nhiều mối đe dọa từ bên ngoài.
- Hệ thống Microservices: Với microservices, mọi thứ lại khác, mỗi microservice là một tiến trình độc lập và chỉ giao tiếp với nhau qua mạng. Các cơ chế bảo vệ của hệ điều hành chỉ có tác dụng bên trong từng tiến trình, mạng lại không đảm bảo tính bảo mật như các cơ chế của hệ điều hành, do đó microservices dễ bị tấn công hơn khi trao đổi dữ liệu qua mạng.
Vậy các vấn đề có qua mạng có thể xảy ra với microservices là gì?
- Eavesdropping (Nghe trộm): Kẻ xấu có thể chặn các thông tin trao đổi giữa các microservices, dẫn đến nguy cơ lộ thông tin quan trọng.
Biện pháp bảo vệ: Sử dụng mã hóa (encryption) để mã hóa dữ liệu, chỉ người nhận mới có thể giải mã được dữ liệu. - Tampering (Giả mạo dữ liệu): Kẻ xấu có thể chỉnh sửa dữ liệu khi dữ liệu đang truyền qua mạng, có thể gây ra hậu quả nghiêm trọng.
Biện pháp bảo vệ: Ngoài mã hóa, cần thêm các cơ chế kiểm tra tính toàn vẹn dữ liệu, như checksum hoặc các giao thức có tính năng kiểm tra tính toàn vẹn. - Identity Theft (Đánh cắp danh tính): Nếu microservice giả danh một microservice khác, ví dụ như giả danh microservice thanh toán, thì có thể đánh cắp hoặc làm sai lệch các thông tin nhạy cảm.
Biện pháp bảo vệ: Xác thực mạnh (strong authentication) để đảm bảo microservice giao tiếp là microservice thật sự, không phải là giả mạo. - Overreach (Lạm quyền): Kẻ xấu có thể khai thác một microservice để thực hiện các chức năng không được phép, ví dụ microservice thanh toán bị yêu cầu từ một dịch vụ chỉ có quyền liệt kê sản phẩm.
Biện pháp bảo vệ: Thực hiện ủy quyền chính xác cho từng microservice để đảm bảo mỗi dịch vụ chỉ có thể làm những gì nó cần và không nhiều hơn (nguyên tắc least privilege - quyền tối thiểu).
2.2 Tăng độ tin cậy (Reliability)
- Trong hệ thống monolithic: Các phần trong ứng dụng giao tiếp qua các lời gọi hàm trong cùng một tiến trình. Điều này đảm bảo rằng các lời gọi không bị thất lạc, và ít khi có sự cố xảy ra với các hàm.
- Trong hệ thống microservices: Giao tiếp diễn ra qua mạng, do đó dễ gặp các vấn đề làm giảm độ tin cậy. Các sự cố này có thể làm cho dịch vụ bị gián đoạn hoặc phản hồi chậm.
Vậy các vấn đề về độ tin câỵ xảy ra với microservices là gì?
- Request Failures (Yêu cầu bị lỗi): Một số yêu cầu có thể thất bại do dịch vụ bị lỗi, mạng quá tải, hoặc ngắt kết nối.
Cách xử lý: Service mesh có thể tự động gửi lại yêu cầu nếu dịch vụ không phản hồi. Tuy nhiên, không phải mọi yêu cầu đều có thể gửi lại được, nên việc này chỉ áp dụng trong một số trường hợp. - Service Failure (Dịch vụ bị lỗi hoàn toàn): Không chỉ một yêu cầu mà toàn bộ dịch vụ có thể gặp sự cố, ví dụ như khi có bản cập nhật lỗi hoặc cả một cụm máy chủ bị sập.
Cách xử lý: Service mesh có thể chuyển sang cụm dự phòng hoặc phiên bản ổn định khác của dịch vụ đó. Đặc biệt hữu ích với các dịch vụ không lưu trữ trạng thái (stateless services), vì chuyển đổi trạng thái phức tạp hơn nhiều. - Service Overload (Dịch vụ quá tải): Khi có quá nhiều yêu cầu đổ dồn vào một dịch vụ, có thể gây ra hiệu ứng domino, service này quá tải dẫn đến service khác quá tải.
Cách xử lý: Service mesh có thể dùng kỹ thuật "circuit breaking" để ngắt một số yêu cầu trước khi chúng tạo áp lực lên các dịch vụ khác, nhằm giảm thiểu thiệt hại và tăng độ ổn định của ứng dụng.
2.3 Tăng khả năng giám sát (Observability)
- Trong hệ thống Monolithic: Khả năng giám sát thường được xử lý bằng cách ghi log, thu thập các chỉ số từ các phần khác nhau trong ứng dụng. Điều này khá đơn giản vì tất cả các phần của ứng dụng nằm trong cùng một nơi.
- Trong hệ thống Microservices: Việc giám sát sẽ phức tạp hơn vì các dịch vụ hoạt động độc lập và giao tiếp qua mạng. Để có cái nhìn tổng thể, cần thu thập thông tin từ các dịch vụ và mối liên hệ giữa chúng.
Bên dưới là các biểu đồ và chỉ số mà chúng ta thường giám sát:
- Call Graph: Đây là biểu đồ cho biết dịch vụ nào gọi đến dịch vụ nào. Service mesh cung cấp số liệu về lượng "traffic" giữa các dịch vụ, tỷ lệ thành công và thất bại của các cuộc gọi này. Biểu đồ này giúp developer nhanh chóng tìm ra nguyên nhân gây lỗi.
- Metrics: Bốn chỉ số quan trọng thường được thu thập từ mỗi microservice để đánh giá hiệu suất:
Latency (Độ trễ): Thời gian để hoàn thành một yêu cầu.
Traffic (Lưu lượng): Số lượng yêu cầu mà dịch vụ đang xử lý.
Errors (Lỗi): Số lượng yêu cầu thất bại, hoặc tỷ lệ thành công.
Saturation (Độ bão hòa): Khả năng mà dịch vụ đang sử dụng so với công suất tối đa.
3. Service Mesh hoạt động như thế nào?
Phần lớn các service mesh sử dụng mô hình sidecar. Trong mô hình này, một container proxy (sidecar) được triển khai bên cạnh mỗi container của ứng dụng.
Proxy này thay đổi các quy tắc định tuyến mạng (network routing rules) để tất cả lưu lượng vào và ra khỏi container phải đi qua sidecar, giúp sidecar kiểm soát mọi thứ cần thiết để thực hiện chức năng của service mesh.
Vì sidecar chạy dưới dạng một tiến trình riêng bên cạnh dịch vụ trong cùng một pod, nó thừa hưởng mọi cơ chế bảo mật của hệ điều hành đối với dịch vụ.
Mình sẽ đưa ra ví dụ cho bạn dễ hiểu nhé, giả sử bạn có 2 service như sau:
- Dịch vụ Thanh Toán (Payment Service): Xử lý thanh toán
- Dịch vụ Đặt Hàng (Order Service): Xử lý đơn hàng
Khi service mesh và sidecar proxy được triển khai, mỗi dịch vụ sẽ có một sidecar chạy song song để quản lý traffic và bảo mật:
- Hệ điều hành giới hạn quyền truy cập của mỗi tiến trình, bảo vệ dữ liệu của dịch vụ thanh toán và dịch vụ đặt hàng khỏi các tiến trình khác ngoài pod.
- Khi dịch vụ thanh toán cần liên lạc với dịch vụ đặt hàng, tất cả traffic đi ra ngoài mạng chung sẽ được chuyển qua sidecar proxy, proxy này sẽ mã hóa dữ liệu trước khi truyền đi, sidecar proxy ở đầu nhận sẽ chịu trách nhiệm giải mã và chuyển đến service đích.
- Các sidecar proxy thường sử dụng chứng chỉ TLS để xác thực danh tính của nhau, đảm bảo rằng Order Service trên máy chủ A thực sự đang giao tiếp với Payment Service trên máy chủ B, ngăn chặn các cuộc tấn công giả mạo.
- Nếu yêu cầu từ Order Service đến Payment Service gặp lỗi do mạng hoặc dịch vụ tạm thời không phản hồi, sidecar proxy sẽ tự động thử lại mà không cần thay đổi trong mã nguồn của Order Service.
- Nếu Payment Service bị quá tải hoặc gặp lỗi liên tục, sidecar proxy của Order Service có thể áp dụng kỹ thuật circuit breaking để ngăn chặn việc gửi yêu cầu thêm, giúp giảm tải cho Payment Service và ngăn ngừa lỗi lan rộng.
- Sidecar proxy cũng ghi nhận các thông số như độ trễ, tỷ lệ thành công, và lưu lượng giữa các dịch vụ.
4. Kết luận
Service Mesh là một giải pháp hiệu quả để quản lý giao tiếp giữa các dịch vụ trong hệ thống microservices. Với mô hình sidecar proxy, service mesh giúp các dịch vụ kết nối an toàn và hiệu quả mà không cần phải thay đổi mã nguồn của ứng dụng.
Các bài viết liên quan: