Giới thiệu
Ở bài trước chúng ta đã tìm hiểu về Batch Job và Periodic Job. Trong bài chúng ta sẽ tìm hiểu tiếp một Pattern nữa là Singleton Service.
Singleton Service
Singleton Service Pattern chắc chắn rằng chỉ có một Instance của ứng dụng được Active cho một Service tại một thời điểm. Ta có thể thực hiện công việc này bằng cách viết code bên trong ứng dụng hoặc có thể dùng K8S.
Thông thường khi ta làm việc với K8S ta sẽ sử dùng Pod để chạy ứng dụng. Và để ứng dụng của ta có độ khả dụng cao thì ta dùng ReplicaSet để chạy nhiều Pod cùng một lúc. Cách ta chạy nhiều Pod như vậy được gọi là Active-Active Topology (toàn bộ Instance của ứng dụng điều được Active).
Lúc này nếu ta cần gửi request tới những Pod đó thì ta phải tạo một thằng Service cho tụi nó.
Đây là kiến trúc phổ biến ta thường thấy, rất nhiều Pod nằm đằng sau một Service. Nhưng sẽ có một vài trường hợp mà ta không thể để nhiều Pod nằm đằng sau một Service được mà yêu cầu mỗi Pod mỗi Service. Ví dụ như là ứng dụng Websocket.
Websocket được dùng để xây dựng các ứng dụng thời gian thực (Real Time). Websocket là ứng dụng thuộc dạng Stateful, có nghĩa là nó có lưu trữ dữ liệu của riêng nó. Khi ta dùng Pod để chạy Websocket thì lúc này mỗi Pod nó có dữ liệu riêng. Nếu ta để nhiều Pod chạy Websocket ở đằng sau một Service thì ứng dụng của ta sẽ bị lỗi. Vì Service thông thường khi ta gửi request tới nó thì request đó được gửi ngẫu nhiên tới 1 trong những Pod nằm phía sau, ta không thể gọi chính xác tới Pod mà ta muốn được.
Nên ta phải có cách định danh Service cho một Pod nhất định. Để giải quyết vấn đề này, ta có hai cách thực hiện như sau: Out-of-Application và In-application Locking.
Out of Application
Như tên gọi thì ở cách này ta sẽ thực hiện công việc Singleton Service ở bên ngoài ứng dụng, nghĩa là ta dùng một thằng khác bên ngoài giúp ta kiểm soát công việc này chứ không cần phải viết code trong ứng dụng.
Trong K8S ta làm công việc này bằng cách kết hợp StatefulSet với Headless Service. Khi ta dùng Service thông thường, bên dưới K8S tạo ra một Virtual IP cho nó. Khi request được gửi tới Virtual IP này thì nó sẽ được gửi ngẫu nhiên tới một những Pod phía sau.
Còn khi ta dùng Headless Service (tạo Service với cấu hình clusterIP: None
), thì K8S không tạo ra một thằng Virtual IP cho nó mà thay vào đó K8S sẽ tạo ra một DNS chính xác cho từng thằng Pod phía sau.
Bằng cách sử dụng Headless Service thì ta có thể tạo Service định danh chính xác cho từng Pod.
Nhưng với cách Out of Application này thì ứng dụng của ta sẽ không đạt được yêu cầu về độ khả dụng. Vì nếu chỉ có 1 Pod cho một ứng dụng mà Pod đó chết thì ứng dụng của ta sẽ chết theo. Tuy StatefulSet có tạo lại Pod nhưng ứng dụng của ta cũng sẽ bị thời gian chết tầm 1 tới 2 giây.
Vì vậy ta phải có cách tạo nhiều Pod mà chỉ có một Pod được Active, những Pod còn lại thì ở trạng thái Passive. Ta thực hiện cách này bằng phương pháp In-application Locking.
In-application Locking
Như tên gọi thì để thực hiện được việc này ta phải viết code trong ứng dụng hoặc dùng những thư viện thứ ba có hỗ trợ. Những thư viện như vậy được gọi là Distributed Frameworks.
Các thư viện Distributed Frameworks thực hiện công việc như sau. Khi toàn bộ Pod của ta đang được Active nó sẽ gửi một request tới một trong những Pod đang Active và yêu cầu lock
Pod đó, nếu thành công thì Pod đó sẽ được thết lập là Active còn toàn bộ các Pod còn lại sẽ được chuyển sang Passive và chờ yêu cầu lock
.
Ví dụ ta có thể làm việc này bằng cách sử dụng Apache Camel với Kubernetes Connector để thực thi Singleton Service. Camel sẽ chắc chắn chỉ có một Pod là được Active và toàn bộ Pod khác sẽ ở trạng thái Passive và chờ cho tới khi được kích hoạt.
Đây là những tư khóa để bạn tìm kiếm thêm về Singleton Service
- Singleton Service Example
- Simple Leader Election with Kubernetes and Docker
- Leader Election in Go Client
- Configuring a Pod Disruption Budget
- Creating Clustered Singleton Services on Kubernetes
- Apache Camel Kubernetes Connector
Kết luận
Vậy là ta đã tìm hiểu xong về Singleton Service, sử dụng Out-of-Application sẽ giúp ta thực thi Singleton Service rất dễ dàng nhưng nó sẽ không đạt yêu cầu về độ khả dụng. Để đạt được độ khả dụng cao thì ta cần sử dụng thêm cách In-application Locking.
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ả?