Phát hiện dịch vụ và kho cấu hình toàn cầu
Ý tưởng cơ bản của phát hiện dịch vụ là bất kỳ instance mới nào của một ứng dụng đều cần có khả năng tự động nhận diện các chi tiết của môi trường hiện tại. Điều này giúp instance mới có thể “kết nối” vào môi trường ứng dụng hiện có mà không cần sự can thiệp thủ công. Các công cụ phát hiện dịch vụ thường được triển khai dưới dạng một registry toàn cầu, lưu trữ thông tin về các instance hoặc dịch vụ đang hoạt động. Để cấu hình này có khả năng chịu lỗi và mở rộng, registry thường được phân phối trên các host có sẵn trong hạ tầng.
Mặc dù mục đích chính của các nền tảng phát hiện dịch vụ là cung cấp các chi tiết kết nối giúp liên kết các thành phần với nhau, nhưng chúng cũng có thể được sử dụng như một kho lưu trữ cho bất kỳ loại cấu hình nào. Nhiều triển khai tận dụng khả năng này bằng cách ghi dữ liệu cấu hình vào công cụ phát hiện dịch vụ. Nếu các container được cấu hình để tự tìm kiếm các chi tiết này, chúng có thể điều chỉnh hành vi dựa trên thông tin thu thập được.
Phát hiện dịch vụ hoạt động
Mỗi công cụ phát hiện dịch vụ đều cung cấp một API để các thành phần có thể sử dụng nhằm thiết lập hoặc truy xuất dữ liệu. Do đó, đối với mỗi thành phần, địa chỉ của công cụ phát hiện dịch vụ phải được nhúng cố định vào bên trong ứng dụng /container hoặc được cung cấp dưới dạng một tùy chọn khi chạy. Thông thường, dịch vụ phát hiện được triển khai dưới dạng một kho key-value mà có thể truy cập qua các phương thức http tiêu chuẩn.
Cách thức hoạt động của một cổng phát hiện dịch vụ là mỗi dịch vụ, khi khởi động, sẽ tự đăng ký với công cụ phát hiện. Dịch vụ đó sẽ ghi lại các thông tin cần thiết mà các thành phần liên quan có thể cần để sử dụng dịch vụ được cung cấp. Ví dụ, một cơ sở dữ liệu MySQL có thể đăng ký địa chỉ IP và cổng mà daemon đang chạy, và tùy chọn là tên người dùng cùng thông tin xác thực cần thiết để đăng nhập.
Khi một thành phần tiêu thụ dịch vụ khởi động, nó có thể truy vấn registry của công cụ phát hiện dịch vụ tại một endpoint đã được định sẵn để lấy thông tin. Từ đó, nó có thể tương tác với các thành phần cần thiết dựa trên thông tin tìm được. Một ví dụ điển hình là bộ cân bằng tải. Nó có thể tìm thấy tất cả các server backend cần chuyển lưu lượng truy cập bằng cách truy vấn cổng phát hiện dịch vụ và điều chỉnh cấu hình cho phù hợp.
Việc tách các chi tiết cấu hình ra khỏi chính container mang lại nhiều lợi ích. Một trong những lợi ích đó là giúp các container thành phần trở nên linh hoạt hơn và không bị ràng buộc vào một cấu hình cụ thể. Thêm vào đó, nó cũng tạo điều kiện cho các thành phần phản ứng nhanh với các instance mới của dịch vụ liên quan, cho phép cấu hình lại động.
Kho lưu trữ cấu hình liên quan
Một ưu điểm quan trọng của hệ thống phát hiện dịch vụ phân phối toàn cầu là nó có thể lưu trữ bất kỳ loại dữ liệu cấu hình nào mà các thành phần của bạn cần trong thời gian chạy. Điều này có nghĩa là bạn có thể tách thêm nhiều cấu hình ra khỏi container và chuyển chúng vào môi trường thực thi tổng thể.
Thông thường, để đạt hiệu quả cao nhất, các ứng dụng của bạn nên được thiết kế với các giá trị mặc định hợp lý có thể được ghi đè khi chạy bằng cách truy vấn kho cấu hình. Điều này cho phép bạn sử dụng kho cấu hình tương tự như cách sử dụng các tham số dòng lệnh (tham số). Sự khác biệt là, khi sử dụng một kho toàn cầu có thể truy cập, bạn có thể cung cấp cùng một tùy chọn cho mỗi instance của thành phần mà không cần công sức bổ sung.
Kho lưu trữ cấu hình giúp quản lý cụm
Một chức năng của kho key-value phân phối trong các triển khai Docker mà ban đầu có thể không dễ nhận ra là lưu trữ và quản lý thành viên của cluster. Các kho cấu hình chính là môi trường lý tưởng để theo dõi thành viên host nhằm phục vụ cho các công cụ quản lý.
Một số thông tin có thể được lưu trữ về từng host trong kho key-value phân phối bao gồm:
● Địa chỉ IP của host
● Thông tin kết nối của chính host
● Dữ liệu metadata và nhãn tuỳ ý, có thể được dùng để quyết định việc lập lịch
● Vai trò trong cluster
Những chi tiết này có thể không phải là điều bạn cần quan tâm khi sử dụng nền tảng phát hiện dịch vụ trong các trường hợp thông thường, nhưng chúng lại cung cấp một vị trí cho các công cụ quản lý để truy vấn hoặc thay đổi thông tin về chính cluster.
Phát hiện lỗi
Phát hiện lỗi có thể được triển khai theo nhiều cách khác nhau. Vấn đề cần quan tâm là, nếu một thành phần bị lỗi, liệu dịch vụ phát hiện có được cập nhật để phản ánh sự không khả dụng của nó hay không. Loại thông tin này rất quan trọng để giảm thiểu các lỗi của ứng dụng hoặc dịch vụ.
Nhiều nền tảng phát hiện dịch vụ cho phép thiết lập các giá trị với thời gian hết hạn (timeout) có thể cấu hình. Thành phần có thể thiết lập một giá trị kèm theo thời gian hết hạn và gửi tín hiệu ping đến dịch vụ phát hiện theo khoảng thời gian định sẵn để làm mới thời gian hết hạn. Nếu thành phần bị lỗi và thời gian hết hạn được kích hoạt, thông tin kết nối của instance đó sẽ bị loại bỏ khỏi kho. Thời gian hết hạn chủ yếu phụ thuộc vào tốc độ mà ứng dụng cần phản ứng trước sự cố của thành phần.
Cách khác để thực hiện việc này là gắn một container “helper” đơn giản với mỗi thành phần, có nhiệm vụ duy nhất là kiểm tra tình trạng sức khỏe của thành phần theo định kỳ và cập nhật registry nếu thành phần bị gián đoạn. Vấn đề của kiến trúc này là container helper cũng có thể gặp lỗi, dẫn đến thông tin không chính xác trong kho. Một số hệ thống khắc phục bằng cách cho phép định nghĩa các health check ngay trong công cụ phát hiện dịch vụ. Nhờ đó, nền tảng phát hiện tự nó có thể kiểm tra định kỳ xem các thành phần đã đăng ký có còn khả dụng hay không.
Cấu hình lại dịch vụ khi chi tiết thay đổi
Một cải tiến quan trọng của mô hình phát hiện dịch vụ cơ bản là khả năng cấu hình lại động. Trong khi phát hiện dịch vụ thông thường cho phép bạn ảnh hưởng đến cấu hình ban đầu của các thành phần bằng cách kiểm tra thông tin phát hiện khi khởi động, thì cấu hình lại động đòi hỏi bạn phải thiết lập các thành phần để phản ứng với thông tin mới trong kho cấu hình. Ví dụ, nếu bạn triển khai một bộ cân bằng tải, một health check trên các server backend có thể chỉ ra rằng một thành viên trong nhóm đã bị lỗi. Instance của bộ cân bằng tải đang chạy cần được thông báo và có khả năng điều chỉnh cấu hình cũng như tải lại (reload) để xử lý tình huống này.
Việc này có thể được triển khai theo nhiều cách. Vì ví dụ về cân bằng tải là một trong những ứng dụng chính của khả năng này, nên đã có rất nhiều dự án tập trung độc quyền vào việc cấu hình lại bộ cân bằng tải khi phát hiện thay đổi cấu hình. Việc điều chỉnh cấu hình HAProxy là phổ biến do tính phổ biến của nó trong lĩnh vực cân bằng tải.
Một số dự án có tính linh hoạt cao hơn khi có thể kích hoạt thay đổi cho bất kỳ loại phần mềm nào. Các công cụ này thường xuyên truy vấn dịch vụ phát hiện và khi phát hiện thay đổi, chúng sử dụng hệ thống templating để tạo ra các tệp cấu hình mới tích hợp các giá trị được tìm thấy tại endpoint của dịch vụ phát hiện. Sau khi tệp cấu hình mới được tạo, dịch vụ bị ảnh hưởng sẽ được tải lại .
Loại cấu hình lại động này đòi hỏi phải có sự lập kế hoạch và cấu hình kỹ càng trong quá trình build vì tất cả các cơ chế này phải tồn tại bên trong container của thành phần. Điều này khiến cho container của thành phần tự chịu trách nhiệm điều chỉnh cấu hình của chính nó. Việc xác định các giá trị cần thiết để ghi vào dịch vụ phát hiện và thiết kế cấu trúc dữ liệu phù hợp nhằm dễ dàng tiêu thụ là một thách thức khác của hệ thống này, nhưng những lợi ích và tính linh hoạt mà nó mang lại là rất đáng kể.
Bảo mật
Một mối quan tâm mà nhiều người có khi lần đầu tìm hiểu về kho lưu trữ cấu hình toàn cầu chính là vấn đề bảo mật. Liệu có an toàn khi lưu trữ thông tin kết nối vào một vị trí có thể truy cập toàn cầu hay không?
Câu trả lời phụ thuộc chủ yếu vào những gì bạn lựa chọn lưu trữ trong kho và số lớp bảo mật mà bạn cho là cần thiết để bảo vệ dữ liệu của mình. Hầu như mọi nền tảng phát hiện dịch vụ đều cho phép mã hoá kết nối bằng SSL/TLS. Đối với một số dịch vụ, tính riêng tư có thể không quá quan trọng và việc đặt dịch vụ phát hiện vào một mạng riêng có thể là đủ. Tuy nhiên, hầu hết các ứng dụng có lẽ sẽ được hưởng lợi từ việc tăng cường bảo mật.
Có nhiều cách khác nhau để giải quyết vấn đề này, và các dự án khác nhau đều đưa ra giải pháp của riêng mình. Một giải pháp là tiếp tục cho phép truy cập mở vào nền tảng phát hiện dịch vụ, nhưng mã hoá dữ liệu được ghi vào đó. Người tiêu dùng ứng dụng phải có Key tương ứng để giải mã dữ liệu mà nó tìm thấy trong kho. Các bên khác sẽ không thể truy cập được dữ liệu chưa được mã hoá.
Một cách tiếp cận khác là một số công cụ phát hiện dịch vụ triển khai danh sách kiểm soát truy cập nhằm phân chia không gian key thành các vùng riêng biệt. Từ đó, họ có thể chỉ định quyền sở hữu hoặc quyền truy cập vào từng khu vực dựa trên yêu cầu truy cập được định nghĩa cho một không gian key cụ thể. Điều này tạo ra một cách dễ dàng để cung cấp thông tin cho một số bên nhất định trong khi giữ kín thông tin đối với những bên khác. Mỗi thành phần có thể được cấu hình chỉ truy cập vào những thông tin mà nó cần sử dụng rõ ràng.
Một số công cụ phát hiện dịch vụ phổ biến bao gồm:
Sau khi đã thảo luận về một số tính năng chung của các công cụ phát hiện dịch vụ và kho key-value phân phối toàn cầu, chúng ta có thể nhắc đến một vài dự án liên quan đến những khái niệm này.
Một số công cụ phát hiện dịch vụ phổ biến nhất là:
● etcd: Công cụ này được tạo ra bởi các nhà phát triển của CoreOS nhằm cung cấp khả năng phát hiện dịch vụ và cấu hình phân phối toàn cầu cho cả container lẫn hệ thống host. Nó triển khai một API http và có sẵn một ứng dụng dòng lệnh trên mỗi máy host.
● consul: Nền tảng phát hiện dịch vụ này có nhiều tính năng tiên tiến giúp nó nổi bật, bao gồm các health check có thể cấu hình, chức năng ACL, cấu hình HAProxy, v.v.
● zookeeper: Ví dụ này có tuổi đời hơi lâu so với hai công cụ trên, mang lại một nền tảng ổn định hơn nhưng đổi lại thiếu một số tính năng mới.
Một số dự án khác mở rộng khả năng phát hiện dịch vụ cơ bản bao gồm:
● crypt: Crypt cho phép các thành phần bảo vệ thông tin chúng ghi bằng cách sử dụng mã hoá bằng public key. Các thành phần được phép đọc dữ liệu sẽ được cung cấp Key giải mã. Các bên khác sẽ không thể đọc được dữ liệu.
● confd: Confd là một dự án nhằm cho phép cấu hình lại động các ứng dụng tùy ý dựa trên sự thay đổi ở cổng phát hiện dịch vụ. Hệ thống bao gồm một công cụ để theo dõi các endpoint liên quan để phát hiện thay đổi, một hệ thống templating để tạo ra các tệp cấu hình mới dựa trên thông tin thu thập được, và khả năng tải lại các ứng dụng bị ảnh hưởng.
● DataOnline Cloud Firewalls: DataOnline Cloud Firewalls hoạt động như một bộ cân bằng tải cho các nhóm thành phần. Nó tích hợp với etcd và điều chỉnh cấu hình dựa trên những thay đổi được phát hiện trong kho.
● marathon: Mặc dù marathon chủ yếu là một trình lập lịch (sẽ được đề cập sau), nhưng nó cũng có khả năng cơ bản để tải lại HAProxy khi có thay đổi xảy ra ở các dịch vụ khả dụng cần được cân bằng tải.
● frontrunner: Dự án này tích hợp với marathon nhằm cung cấp một giải pháp mạnh mẽ hơn cho việc cập nhật HAProxy.
● synapse: Dự án này giới thiệu một instance HAProxy tích hợp có khả năng định tuyến lưu lượng đến các thành phần.
● nerve: Nerve được sử dụng cùng với synapse để cung cấp các health check cho từng instance của thành phần. Nếu thành phần bị gián đoạn, nerve sẽ cập nhật synapse để loại bỏ thành phần đó khỏi vòng xoay xử lý.
Kết luận
Phát hiện dịch vụ và kho cấu hình toàn cầu là những yếu tố quan trọng giúp các container Docker thích ứng linh hoạt với môi trường triển khai và kết nối một cách liền mạch với các thành phần khác. Những yếu tố này đóng vai trò quyết định trong việc cung cấp khả năng mở rộng và triển khai tự động, không cần sự can thiệp thủ công, bằng cách cho phép các thành phần liên tục theo dõi và phản hồi kịp thời với các thay đổi trong môi trường.
Khi quản lý kho cấu hình phân phối trong Docker, chi phí là yếu tố quan trọng. VPS giá rẻ từ DataOnline mang đến giải pháp tiết kiệm, với băng thông không giới hạn và cấu hình linh hoạt, giúp bạn triển khai dịch vụ mượt mà mà vẫn tối ưu ngân sách.
Trong bài hướng dẫn tiếp theo, chúng ta sẽ cùng khám phá cách thức mà các container Docker và các máy chủ có thể giao tiếp với nhau thông qua các cấu hình mạng tùy chỉnh, giúp tối ưu hóa quá trình triển khai và quản lý hệ thống phân tán.

