Service Mesh Proxy: Cách proxy vận hành trong service mesh
Service mesh proxy là lớp proxy nhỏ đứng cạnh từng dịch vụ trong hệ thống microservices, lo việc định tuyến, mã hóa và theo dõi mọi kết nối giữa các dịch vụ với nhau. Nhờ lớp này, đội phát triển không phải viết lại logic thử lại hay xác thực trong từng ứng dụng. Bài này ProxyVN giải thích kiến trúc, lợi ích, cấu hình mẫu và những chi phí cần cân nhắc. Xem thêm các dịch vụ proxy tại ProxyVN.
Service mesh proxy và vai trò trong microservices
Service mesh proxy ra đời để giải bài toán giao tiếp khi một ứng dụng lớn bị chia thành hàng chục, hàng trăm dịch vụ nhỏ. Mỗi dịch vụ nhỏ cần gọi tới các dịch vụ khác qua mạng, và mỗi lần gọi đều có thể chậm, lỗi hoặc bị nghe lén. Theo định nghĩa của AWS về service mesh, đây là lớp hạ tầng chuyên quản lý giao tiếp giữa các dịch vụ, tách khỏi mã nguồn của ứng dụng.
Về bản chất, mỗi service mesh proxy là một reverse proxy thu nhỏ đặt ngay cạnh dịch vụ. Nó nhận lưu lượng đi vào, chuyển tiếp lưu lượng đi ra, và áp dụng các chính sách chung cho cả hệ thống. Nếu anh em chưa quen khái niệm reverse proxy, bài reverse proxy là gì và ứng dụng như thế nào là nền tảng nên đọc trước.

Service Mesh
Vấn đề phát sinh khi số lượng service tăng
Khi chỉ có ba hay bốn dịch vụ, đội phát triển có thể tự viết code xử lý lỗi, thử lại và ghi log trong từng dịch vụ. Khi con số lên tới vài chục, cách làm này bắt đầu gãy. Mỗi đội viết theo một kiểu, mỗi ngôn ngữ dùng một thư viện khác nhau, và không ai nhìn được toàn cảnh.
Các vấn đề cụ thể hay gặp gồm:
- Một dịch vụ chậm kéo cả chuỗi chậm theo, vì các dịch vụ gọi nó cứ chờ mãi.
- Không biết lỗi phát sinh ở đâu, khi một yêu cầu của người dùng đi qua năm, sáu dịch vụ.
- Kết nối nội bộ không được mã hóa, vì nhiều đội nghĩ mạng trong là mạng an toàn.
- Triển khai phiên bản mới rủi ro cao, vì không có cách đưa một phần nhỏ lưu lượng sang bản mới để thử.
Service mesh proxy giải quyết các vấn đề này ở một chỗ duy nhất, thay vì để từng đội tự xử lý. Đây là lý do nó trở thành thành phần phổ biến trong các hệ thống chạy trên Kubernetes.
Service mesh proxy khác gì proxy thông thường
Proxy thông thường, dù là forward hay reverse, thường đứng ở rìa hệ thống. Forward proxy đại diện cho người dùng đi ra ngoài, còn reverse proxy đại diện cho máy chủ đón khách từ ngoài vào. Bài forward proxy và reverse proxy so sánh kỹ hai vai trò này.
Service mesh proxy thì đứng ở bên trong, quản lý luồng đi lại giữa các dịch vụ, người trong ngành gọi là lưu lượng đông tây. Mỗi proxy vừa là reverse proxy cho dịch vụ của nó, vừa là forward proxy khi dịch vụ đó gọi ra ngoài. Chính vị trí kép này cho phép mesh kiểm soát mọi kết nối mà ứng dụng không cần biết.
Kiến trúc của service mesh proxy
Kiến trúc của service mesh proxy chia làm hai phần rõ ràng: data plane xử lý dữ liệu thật và control plane ra lệnh cho data plane. Cách chia này giống quan hệ giữa các trạm thu phí trên đường cao tốc và trung tâm điều hành phía sau.
Data plane xử lý dữ liệu
Data plane là tập hợp tất cả các proxy đang chạy cạnh dịch vụ. Mọi gói tin đi giữa các dịch vụ đều chạy qua lớp này. Proxy phổ biến nhất cho vai trò này là Envoy, một proxy hiệu năng cao viết bằng C++ do Lyft phát triển rồi đóng góp cho cộng đồng.

Data plane xử lý dữ liệu
Mỗi proxy trong data plane làm các việc sau với từng yêu cầu: tìm địa chỉ của dịch vụ đích, chọn một phiên bản khỏe để gửi tới, mã hóa kết nối, đo thời gian phản hồi và ghi lại kết quả. Nếu dịch vụ đích không trả lời, proxy tự thử lại theo chính sách đã cấu hình. Tất cả diễn ra trong vài mili giây.
Linkerd, một service mesh khác, dùng proxy riêng viết bằng Rust thay cho Envoy. Theo giới thiệu của Linkerd về service mesh, proxy này được thiết kế nhỏ gọn để giảm tài nguyên tiêu thụ trên mỗi dịch vụ.
Control plane quản lý cấu hình
Control plane không chạm vào dữ liệu của người dùng. Nó giữ danh sách các dịch vụ, chứng chỉ bảo mật và chính sách, rồi đẩy cấu hình xuống từng proxy trong data plane. Khi quản trị viên đổi một quy tắc, control plane cập nhật tới hàng trăm proxy mà không cần khởi động lại dịch vụ nào.

Control plane quản lý cấu hình
Trong Istio, control plane là thành phần istiod. Nó gộp ba việc chính: phát hiện dịch vụ, cấp và xoay vòng chứng chỉ, và dịch các quy tắc định tuyến thành cấu hình Envoy hiểu được. Tài liệu Istio là gì mô tả kiến trúc này khá chi tiết.
Sidecar và hướng tiếp cận không sidecar
Mô hình sidecar đặt một proxy vào cùng pod với mỗi dịch vụ, giống chiếc thùng xe gắn bên hông xe máy. Ưu điểm là cô lập tốt, mỗi dịch vụ có proxy riêng. Nhược điểm là tốn tài nguyên: một nghìn pod nghĩa là một nghìn proxy, mỗi proxy chiếm thêm RAM và CPU.
Hướng không sidecar, như chế độ ambient của Istio, chuyển phần xử lý cơ bản xuống một proxy chung trên mỗi máy chủ. Chỉ những dịch vụ cần định tuyến phức tạp mới có thêm proxy riêng. Cách này giảm tài nguyên đáng kể, đổi lại kiến trúc phức tạp hơn và còn mới so với sidecar.
Bật sidecar trong Kubernetes
Với Istio, cách bật sidecar phổ biến nhất là gắn nhãn cho namespace. Từ đó mọi pod mới tạo trong namespace sẽ tự được chèn thêm proxy Envoy:
# Gan nhan de Istio tu chen sidecar vao namespace "shop"
kubectl label namespace shop istio-injection=enabled
# Khoi dong lai cac deployment de pod moi co sidecar
kubectl rollout restart deployment -n shop
# Kiem tra: moi pod se co 2/2 container (ung dung + istio-proxy)
kubectl get pods -n shop
Lợi ích chính của lớp service mesh proxy
Lợi ích chính của lớp service mesh proxy gom vào bốn nhóm: quản lý traffic, khả năng phục hồi, bảo mật và quan sát. Mỗi nhóm đều là thứ trước đây phải viết tay trong từng dịch vụ.
Quản lý traffic linh hoạt
Với service mesh, anh em có thể chia lưu lượng theo tỷ lệ phần trăm giữa các phiên bản. Đây là nền tảng của kiểu triển khai canary: đưa 5% người dùng sang bản mới, theo dõi, rồi tăng dần nếu ổn. Ví dụ cấu hình Istio dưới đây chia 90% lưu lượng cho bản v1 và 10% cho bản v2:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: thanh-toan
spec:
hosts:
- thanh-toan
http:
- route:
- destination:
host: thanh-toan
subset: v1
weight: 90
- destination:
host: thanh-toan
subset: v2
weight: 10
Ngoài chia theo tỷ lệ, mesh còn định tuyến theo header. Ví dụ chỉ nhân viên nội bộ có header riêng mới được chuyển sang bản thử nghiệm. Cách này giúp kiểm tra tính năng trên môi trường thật mà khách hàng không bị ảnh hưởng.
Tăng khả năng phục hồi
Service mesh proxy có sẵn ba cơ chế giúp hệ thống chống chịu lỗi: thời gian chờ, thử lại và ngắt mạch. Bộ ngắt mạch hoạt động như cầu dao điện: khi một dịch vụ lỗi liên tục, proxy tạm ngừng gửi yêu cầu tới nó để nó có thời gian hồi phục. Ý tưởng này tương tự cơ chế dự phòng trong bài proxy failover.
Cấu hình mẫu dưới đây giới hạn số kết nối và loại tạm thời một phiên bản ra khỏi nhóm nếu nó trả lỗi 5xx năm lần liên tiếp:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: thanh-toan
spec:
host: thanh-toan
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 50
outlierDetection:
consecutive5xxErrors: 5
interval: 10s
baseEjectionTime: 30s
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
Khi bộ ngắt mạch bật, proxy sẽ trả về lỗi 503 ngay lập tức thay vì để dịch vụ gọi chờ mãi. Lỗi nhanh tốt hơn chờ lâu, vì nó giải phóng tài nguyên cho các yêu cầu khác.
Bảo mật kết nối nội bộ
Service mesh proxy tự động mã hóa kết nối giữa các dịch vụ bằng mTLS, tức TLS hai chiều. Cả hai bên đều phải trình chứng chỉ, nên dịch vụ lạ không thể giả danh dịch vụ hợp lệ. Control plane cấp và xoay vòng chứng chỉ tự động, đội phát triển không phải quản lý thủ công.
Bật mTLS bắt buộc cho cả namespace chỉ cần vài dòng:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: mac-dinh
namespace: shop
spec:
mtls:
mode: STRICT
Kết hợp mTLS với chính sách phân quyền, anh em có thể quy định dịch vụ nào được gọi dịch vụ nào. Đây là cách triển khai mô hình không tin cậy mặc định ở tầng mạng nội bộ.
Quan sát hệ thống nhất quán
Vì mọi yêu cầu đều đi qua proxy, mesh thu được số liệu đồng nhất cho mọi dịch vụ: số yêu cầu, tỷ lệ lỗi, độ trễ. Các số liệu này đổ về Prometheus và hiển thị trên Grafana mà không cần sửa code ứng dụng.
Truy vết phân tán còn cho anh em thấy đường đi của một yêu cầu qua từng dịch vụ và thời gian ở mỗi chặng. Khi người dùng báo chậm, anh em biết ngay dịch vụ nào là điểm nghẽn thay vì đoán mò.
Giá trị lớn nhất của service mesh không nằm ở từng tính năng riêng lẻ, mà ở chỗ mọi dịch vụ được áp cùng một chuẩn mà không ai phải viết lại code.
Service mesh proxy so với các loại proxy hạ tầng khác
Service mesh proxy hay bị đặt cạnh API gateway, bộ cân bằng tải và reverse proxy truyền thống. Chúng đều là proxy, nhưng mỗi loại sinh ra cho một vị trí và một kiểu lưu lượng khác nhau.
Khác biệt giữa service mesh và API gateway
API gateway đứng ở cửa ngõ, đón yêu cầu từ khách hàng bên ngoài vào hệ thống, lưu lượng bắc nam. Nó lo xác thực người dùng, giới hạn tốc độ theo khóa API, chuyển đổi định dạng và tính phí. Service mesh thì lo lưu lượng đông tây giữa các dịch vụ bên trong. Bài Service Mesh 101 của Traefik cũng phân biệt hai lớp này theo hướng lưu lượng.

Khác nhau giữa service mesh và API gateway
Trong thực tế, hai lớp này thường đi cùng nhau. Yêu cầu của khách vào qua API gateway, sau đó di chuyển giữa các dịch vụ bên trong qua service mesh. Một số giải pháp như Istio còn có gateway riêng dùng chung Envoy, giúp quản lý cả hai đầu bằng một bộ công cụ.
So với HAProxy và Nginx làm cân bằng tải
HAProxy và Nginx là các reverse proxy và bộ cân bằng tải rất phổ biến. Chúng thường chạy thành vài máy chủ tập trung, chia tải cho một nhóm máy phía sau. Bài HAProxy là gì giải thích cách loại này hoạt động.
Service mesh proxy thì phân tán: mỗi dịch vụ có một proxy, cấu hình đổ về từ control plane. Mô hình tập trung đơn giản, dễ vận hành với hệ thống vừa và nhỏ. Mô hình phân tán linh hoạt hơn nhưng phức tạp hơn, chỉ đáng dùng khi số dịch vụ đủ lớn.
Bảng so sánh nhanh
Tiêu chí |
Service mesh proxy |
API gateway |
Bộ cân bằng tải tập trung |
|---|---|---|---|
Vị trí |
Cạnh từng dịch vụ |
Rìa hệ thống |
Trước một nhóm máy chủ |
Hướng lưu lượng |
Đông tây, nội bộ |
Bắc nam, từ ngoài vào |
Chủ yếu bắc nam |
Mã hóa nội bộ |
mTLS tự động |
Thường không |
Thường không |
Quản lý phiên bản |
Chia theo tỷ lệ, header |
Theo đường dẫn API |
Hạn chế |
Độ phức tạp vận hành |
Cao |
Trung bình |
Thấp |
Phù hợp |
Hàng chục dịch vụ trở lên |
Mọi hệ thống có API công khai |
Hệ thống vừa và nhỏ |
Ví dụ mô phỏng service mesh proxy cho hệ thống thanh toán
Ví dụ dưới đây là tình huống mô phỏng để anh em hình dung cách service mesh proxy vận hành, không phải số liệu của một doanh nghiệp cụ thể. Giả sử một sàn bán hàng có các dịch vụ đơn hàng, thanh toán, kho và thông báo.
Triển khai bản thanh toán mới
Đội thanh toán viết xong phiên bản mới hỗ trợ thêm một cổng ví điện tử. Thay vì chuyển toàn bộ người dùng sang, họ dùng VirtualService đưa 5% lưu lượng sang bản v2. Bảng theo dõi cho thấy tỷ lệ lỗi và độ trễ của v2 tương đương v1 sau hai giờ, nên họ tăng lên 25%, rồi 50%, rồi 100% trong vòng một ngày.
Nếu v2 có lỗi, chỉ cần sửa trọng số về 0 là toàn bộ người dùng quay lại v1 ngay. Không cần triển khai lại, không cần khởi động lại dịch vụ nào.
Khi cổng thanh toán bên ngoài chậm
Một buổi tối, cổng thanh toán của đối tác phản hồi chậm bất thường. Không có mesh, dịch vụ thanh toán sẽ giữ kết nối chờ, hết luồng xử lý, rồi kéo cả dịch vụ đơn hàng chậm theo. Có mesh, thời gian chờ được giới hạn và bộ ngắt mạch tạm ngừng gửi yêu cầu tới phiên bản đang quá tải.
Người dùng nhận thông báo thử lại sau thay vì treo trang vô thời hạn. Dịch vụ đơn hàng vẫn hoạt động bình thường cho các khách chọn hình thức thanh toán khác.
Truy lỗi qua truy vết phân tán
Khi khách phản ánh đặt hàng chậm, đội vận hành mở công cụ truy vết và thấy yêu cầu mất phần lớn thời gian ở dịch vụ kho. Nguyên nhân là một truy vấn cơ sở dữ liệu thiếu chỉ mục. Không có mesh, họ có thể mất cả buổi để kiểm tra từng dịch vụ theo thứ tự.
Giới hạn và chi phí của service mesh proxy
Giới hạn và chi phí của service mesh proxy là thứ anh em cần cân nhắc kỹ trước khi triển khai. Mesh giải quyết nhiều vấn đề, nhưng cũng thêm một lớp phức tạp mà đội vận hành phải gánh.
Chi phí tài nguyên và độ trễ
Mỗi sidecar tiêu thụ thêm RAM và CPU. Với vài trăm pod, tổng tài nguyên dành cho proxy có thể đáng kể. Mỗi yêu cầu cũng đi qua thêm hai proxy, một ở đầu gửi và một ở đầu nhận, cộng thêm độ trễ nhỏ.
Với phần lớn ứng dụng web, mức trễ thêm này nhỏ so với thời gian xử lý của chính ứng dụng. Nhưng với hệ thống cần độ trễ cực thấp, anh em nên đo kỹ trên môi trường thử trước khi quyết định.
Độ phức tạp vận hành
Mesh có nhiều khái niệm mới: VirtualService, DestinationRule, chính sách bảo mật, chứng chỉ. Cấu hình sai một quy tắc có thể cắt đứt giao tiếp giữa các dịch vụ. Đội vận hành cần thời gian học và cần quy trình kiểm tra cấu hình trước khi áp dụng.
Nâng cấp phiên bản mesh cũng là việc cần kế hoạch, vì nó chạm vào mọi dịch vụ trong hệ thống. Nhiều đội chọn nâng cấp theo từng namespace để giảm rủi ro.
Những lỗi cấu hình hay gặp
Phần lớn sự cố với mesh không đến từ phần mềm, mà đến từ cấu hình. Đội ProxyVN tổng hợp vài lỗi mà anh em mới làm quen thường mắc phải, kèm dấu hiệu nhận biết:
- Bật mTLS bắt buộc quá sớm: dịch vụ chưa có sidecar không gửi được chứng chỉ, kết nối bị từ chối và log chỉ báo lỗi chung chung ở tầng TLS.
- Thử lại chồng thử lại: ứng dụng tự thử lại ba lần, proxy cũng thử lại ba lần, một lỗi nhỏ biến thành chín yêu cầu dồn vào dịch vụ đang yếu.
- Thời gian chờ ở proxy ngắn hơn thời gian xử lý thật: các tác vụ dài như xuất báo cáo bị cắt giữa chừng và trả về 504.
- Đặt tên subset không khớp nhãn pod: VirtualService trỏ tới subset v2 nhưng pod lại mang nhãn khác, lưu lượng rơi vào khoảng trống và trả về 503.
- Quên cấu hình cho lưu lượng đi ra: khi mesh chặn mặc định kết nối ra ngoài, các lệnh gọi API đối tác đột ngột thất bại sau khi bật mesh.
Cách phòng tránh chung là luôn có môi trường thử nghiệm giống môi trường thật, và dùng công cụ phân tích cấu hình đi kèm mesh trước khi áp dụng. Với Istio, lệnh istioctl analyze phát hiện được nhiều lỗi trong số này trước khi chúng gây sự cố. Ghi lại mỗi lần đổi cấu hình kèm người thực hiện cũng giúp quay lui nhanh khi có vấn đề.
Khi nào chưa nên dùng service mesh
Nếu hệ thống chỉ có vài dịch vụ, một bộ cân bằng tải và thư viện xử lý lỗi trong code thường đủ dùng. Mesh chỉ thật sự đáng giá khi số dịch vụ lớn, nhiều đội cùng phát triển, và yêu cầu bảo mật nội bộ cao. Đừng dùng mesh chỉ vì nó đang thịnh hành.
Tiêu chí lựa chọn và triển khai service mesh proxy
Tiêu chí lựa chọn và triển khai service mesh proxy nên bắt đầu từ vấn đề thật mà đội đang gặp, không phải từ danh sách tính năng. Phần này gợi ý cách chọn công cụ và lộ trình triển khai an toàn.
Chọn công cụ phù hợp
- Istio: nhiều tính năng nhất, dùng Envoy, cộng đồng lớn. Phù hợp hệ thống lớn cần định tuyến và bảo mật phức tạp.
- Linkerd: nhẹ, dễ cài, tập trung vào mTLS và quan sát. Phù hợp đội muốn bắt đầu nhanh với ít cấu hình.
- Consul: mạnh về phát hiện dịch vụ, hỗ trợ cả máy ảo lẫn Kubernetes. Phù hợp hạ tầng lai.
- Cilium: dựa trên eBPF ở tầng nhân Linux, giảm phụ thuộc vào sidecar. Phù hợp đội đã dùng Cilium cho mạng.
Lộ trình triển khai từng bước
- Bước 1: chọn một namespace ít quan trọng để thử, bật sidecar và chỉ quan sát, chưa áp chính sách.
- Bước 2: kiểm tra số liệu và truy vết hiển thị đúng, đo mức tài nguyên tăng thêm.
- Bước 3: bật mTLS ở chế độ cho phép, để kết nối cũ không mã hóa vẫn chạy trong lúc chuyển đổi.
- Bước 4: khi mọi dịch vụ đã có sidecar, chuyển mTLS sang chế độ bắt buộc.
- Bước 5: thêm dần chính sách định tuyến, thời gian chờ và ngắt mạch cho từng dịch vụ.
- Bước 6: mở rộng sang các namespace khác theo thứ tự rủi ro từ thấp lên cao.
Kết nối ra ngoài từ service mesh
Mesh quản lý tốt giao tiếp bên trong, nhưng nhiều dịch vụ vẫn phải gọi API bên ngoài: cổng thanh toán, dịch vụ gửi tin nhắn, website đối tác. Một số đối tác chỉ cho phép IP đã đăng ký trong danh sách trắng. Lúc này hệ thống cần một IP đi ra cố định, thường đặt qua egress gateway của mesh kết hợp với forward proxy. Anh em xem thêm khái niệm này trong bài forward proxy là gì.
Service mesh lo phần proxy nội bộ; còn khi dịch vụ cần IP đi ra cố định, anh em có thể mua proxy datacenter hoặc dân cư tĩnh tại ProxyVN.
Câu hỏi thường gặp về service mesh proxy
Service mesh có bắt buộc phải chạy trên Kubernetes không?
Không bắt buộc, nhưng Kubernetes là môi trường phổ biến nhất. Consul và một số giải pháp khác hỗ trợ cả máy ảo và máy chủ vật lý.
Envoy và Istio khác nhau thế nào?
Envoy là proxy, thuộc data plane. Istio là cả hệ thống gồm control plane istiod và dùng Envoy làm data plane. Có thể dùng Envoy độc lập mà không cần Istio.
Service mesh có làm chậm ứng dụng không?
Có thêm độ trễ nhỏ vì mỗi yêu cầu đi qua hai proxy. Với đa số ứng dụng web, mức này không đáng kể so với thời gian xử lý nghiệp vụ, nhưng nên đo trên hệ thống của mình.
Có cần sửa code ứng dụng khi dùng service mesh không?
Thường là không. Proxy chặn lưu lượng ở tầng mạng nên ứng dụng không biết mình đang chạy trong mesh. Riêng truy vết phân tán cần ứng dụng chuyển tiếp các header truy vết để nối các chặng lại với nhau.
Service mesh có thay được API gateway không?
Không nên thay. Hai lớp phục vụ hai hướng lưu lượng khác nhau. Mesh lo bên trong, gateway lo cửa ngõ từ ngoài vào, kết hợp cả hai là cách phổ biến nhất.
Xem thêm:
Kết luận
Service mesh proxy đưa việc định tuyến, mã hóa và theo dõi kết nối ra khỏi code ứng dụng, đặt vào một lớp proxy chung có thể quản lý tập trung. Nó rất mạnh với hệ thống nhiều dịch vụ, nhưng cũng đòi hỏi đội vận hành đủ năng lực. Cần proxy cho kết nối đi ra, liên hệ Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam để được tư vấn service mesh proxy.