Bài viết thuộc series “Service Mesh on Kubernetes”
Giới thiệu
Việc triển khai hệ thống microservices lên trên máy chủ luôn luôn là một thử thách lớn, và khi Kubernetes được sinh ra thì nó đã giúp ta dễ dàng hơn phần nào trong việc triển khai hệ thống microservices lên trên máy chủ. Nhưng ta sẽ đối mặc với thách thức tiếp theo là cách giao tiếp giữa các services bên trong Kubernetes, vì Kubernetes không được sinh ra như một giải pháp về networking, do đó Istio đã được ra đời, Istio được phát triển dựa trên Service Mesh.
Với K8S thì ta sẽ dùng Pod để triển khai services, trước khi tìm hiểu về Service Mesh thì ta sẽ xem cách giao tiếp mặc định giữa các Pod bên trong K8S như thế nào và nó bị hạn chế gì?
Internal Pod Communication
Trong K8S để các Pod nằm ở các worker node khác nhau có thể giao tiếp được với nhau thì K8S sử dụng Container Network Interface (CNI), và ở bên trong một worker node để các Pod có thể giao tiếp được với nhau thì K8S sử dụng kube-proxy.
Khi ta tạo một Pod hay Service thì kube-proxy sẽ thực hiện cập nhật iptables rules để các Pod có thể giao tiếp được với nhau, ví dụ như sau.
Image from Kubernetes in Action
Khi ta tạo Service tên là B thì Kubernetes API Server sẽ thông báo cho kube-proxy ở worker node cập nhật lại iptables rules thêm vào rule cho Service B, sau đó nếu có một Pod nào đó gọi tới Service B thì request của nó đầu tiên sẽ đi qua iptables, lúc này iptables sẽ xem thằng Service B này IP thật sự của nó sẽ bao gồm những thằng nào, tiếp theo iptables sẽ gửi request tới một trong những IP nó kiếm được theo cách random.
Đây là cách kube-proxy làm việc, nhưng nó sẽ có những hạn chế như sau:
- Request nó gửi đi tới các Pod là random.
- Không thể chia traffic theo kiểu phần trăm.
- Không thể thực hiện canary releases hoặc blue-green releases.
- Khó để giám sát và bắt lỗi.
Đặt biệt là trong hệ thống microservices thì việc giao tiếp giữa các services cần phải có bảo mật, có thể giám sát và truy lỗi, đo được thời gian của từng request, và để thực hiện được những chức năng này thì ta phải tự cài thư viện bên trong ứng dụng của ta, ví dụ như sau.
Việc này tuy không có gì sai, nhưng những tiến trình này rõ ràng đang chiếm tài nguyên của ứng dụng chính, và khi một developer viết code thì cũng cần viết thêm code cho phần này, trong khi thường thì ta chỉ muốn developer tập trung vào logic của ứng dụng.
Do đó service mesh đã được sinh ra.
Service Mesh
Service Mesh là một công cụ sẽ thêm một lớp mạng riêng biệt (dedicated network layer) đứng trước ứng dụng, phần network layer này sẽ cung cấp thêm các tính năng như bảo mật, giám sát tầng network cho ứng dụng thay vì ta phải thực hiện nó ở trong ứng dụng, hình minh họa.
Service Mesh gồm có hai thành phần chính là control plane và data plane:
- Control plane sẽ thực hiện vài trò là quản lý toàn bộ các services.
- Data plane sẽ đóng vai trò xử lý giao tiếp giữa các services.
Khi ta triển khai service mesh lên trên K8S thì lúc này data plane sẽ là phần sidecar container proxy được triển chung với application container, còn control plane sẽ được triển khai như một Pod riêng biệt.
Lúc này thay vì quản lý việc giao tiếp với nhau thông qua kube-proxy, thì ứng dụng của ta sẽ giao tiếp với container proxy, và container proxy sẽ thực hiện việc giao tiếp giữa các Pod với nhau. Tất cả các chức năng như bảo mật, giám sát, đo lường thì container proxy sẽ thực hiện hết, còn ứng dụng của ta chỉ cần tập trung vào phần application logic.
Thì hai công cụ service mesh phổ biến nhất ở thời điểm mình viết bài là Istio và Consul, và chúng ta sẽ nói về Istio.
Istio là gì?
Istio là một công cụ service mesh được xây dựng để chạy trên Kubernetes, Istio cũng gồm hai phần chính là control plane và data plane. Với control plane sử dụng Istiod container và data plane sẽ được triển khai tới Pod như một sidecar proxy dùng Envoy container.
Istiod sẽ quản lý và cấu hình sidecar container proxy, đóng vai trò như một service discovery cho toàn bộ proxy. Istiod sẽ chuyển toàn bộ cấu hình routing rules sang dạng cấu hình của Envoy và chuyển nó tới toàn bộ Envoy container.
Envoy container sẽ thực hiện việc giao tiếp giữa các Pod với nhau, các tính năng nổi bật của Envoy:
- Dynamic service discovery
- Load balancing
- TLS termination
- HTTP/2 and gRPC proxies
- Circuit breakers
- Health checks
- Staged rollouts with %-based traffic split
- Fault injection
- Rich metrics
Khi ta cài Istio lên trên Kubernetes thì lúc ta tạo Pod thì Envoy container sẽ tự động được thêm vào Pod của ta, nên ta không cần phải tự khai báo thêm Envoy container khi viết file manifest cho Pod.
Hiện tại thì Istio đã được chấp nhận như là một dự án của Cloud Native Computing Foundation (CNCF), đây là tổ chức phát triển Kubernetes nên Istio sẽ còn phát triển nhiều trong tương lai và sẽ không bị bỏ ngang nên các bạn cứ thoải mái sử dụng 😁.
Kết luận
Vậy là ta đã tìm hiểu tại sao ta lại nên sử dụng Service Mesh trong hệ thống microservices và Istio là gì. Bài tiếp theo ta sẽ tìm hiểu về cách cài đặt Istio và cách làm một số thứ cơ bản.
Tác giả @Quân Huỳnh
Nếu bài viết có gì sai hoặc cần cập nhật thì liên hệ Admin.
Tham gia nhóm chat của DevOps VN tại Telegram.
Kém tiếng Anh và cần nâng cao trình độ giao tiếp: Tại sao bạn học không hiệu quả?