Giới thiệu
Trong bài này chúng ta sẽ tìm hiểu về một Pattern rất quan trọng trong K8S là Service Discovery.
Service Discovery
Service Discovery là cách các ứng dụng tự động phát hiện địa chỉ của nhau thông qua Service.
Vấn đề
Ứng dụng trong K8S của ta đều được chạy bằng Pod và mỗi Pod đều có một IP riêng của nó. Nếu các ứng dụng của ta muốn giao tiếp với nhau thông qua Pod IP thì ta sẽ gặp một vấn đề rất lớn.
Vì ở trong K8S thì Pod thường được tạo ra, xóa đi và thay thế bằng một thằng khác bất cứ lúc nào. Mỗi lần Pod được tạo mới thì IP của nó sẽ thay đổi. Nên nếu các ứng dụng của ta giao tiếp với nhau thông qua Pod IP thì nó sẽ bị lỗi.
Giải pháp
K8S đã áp dụng Service Discovery để giải quyết vấn đề trên với. K8S phát triển một resource tên là Service. Khi ta tạo một Service thì nó sẽ tạo ra một Virtual IP cho toàn bộ các Pod phía sau. Service sẽ chọn các Pod mà nó quản lý thông qua thuộc tính spec.selector
.
Và khi request được gửi tới Virtual IP của Service thì nó sẽ được gửi ngẫu nhiên tới một trong những Pod ở đằng sau.
Service Discovery trong Kubernetes
Vậy làm thế nào các ứng dụng trong Pod có thể phát hiện được Virtual IP của một Service? Ta sẽ có hai cách sau:
- Phát hiện thông qua biến môi trường (ENV)
- Phát hiện thông qua DNS Lookup
Service Discovery với ENV
Cách đầu tiên để các ứng dụng có thể phát hiện được Virtual IP của một Service là thông qua ENV.
Khi một Pod bắt đầu chạy thì thông tin của các Service đang tồn tại sẽ được truyền vào bên trong Pod thông qua ENV. Thông tin Virtual IP của Service được nhúng vào các ENV này. Hai giá trị ENV chứa thông tin của Virtual IP là HOST
và PORT
, có định dạng như sau:
<SERVICE_NAME>_SERVICE_HOST
<SERVICE_NAME>_SERVICE_PORT
Ví dụ ở trên ta có Service tên là kubia
, thì giá trị ENV của nó có định dạng như sau:
KUBIA_SERVICE_HOST=172.17.0.4
KUBIA_SERVICE_PORT=80
Cách phát hiện thông qua giá trị ENV này có một khuyết điểm đó là giá trị Virtual IP chỉ được nhúng vào khi Pod bắt đầu chạy. Còn với các Pod đang chạy thì khi ta tạo Service mới nó sẽ không có thông tin của Service mới. Để Pod đang chạy lấy được thông tin Service mới thì ta cần khởi động lại Pod.
Service Discovery với DNS Lookup
Với cách này thì các ứng dụng phát hiện Virtual IP của một Service thông qua DNS. Kubernetes có cung cấp một DNS Server nội bộ, khi một Service mới được tạo ra thì bên cạnh Virtual IP được gán cho nó thì còn có thêm một DNS đi kèm.
Và ứng dụng có thể truy cập Service thông qua DNS đó. DNS của Service có định dạng FQDN (fully qualified domain name) như sau <service-name>.<namespace>.svc.cluster.local
:
<service-name>
là tên của Service ở trườngmetadata.name
<namespace>
là tên Namespace mà Service được tạo.svc
định nghĩa cho nó là service resourcecluster.local
là hậu tố cố định.
Ví dụ với Service ở trên thì DNS có định dạng như sau kubia.default.svc.cluster.local
. Khi ta sử dụng DNS trong Pod ta không cần phải chỉ định đầy đủ như dạng FQDN, mà ta chỉ cần chỉ định nó ở dạng rút gọn như sau <service-name>.<namespace>
. Ví dụ với kubia.default.svc.cluster.local
thì khi dùng ta chỉ cần chỉ định kubia.default
là đủ.
Khi ứng dụng trong Pod gọi tới DNS của Service thì nó sẽ được xử lý bởi DNS Server nội bộ. Lúc này DNS Server nội bộ sẽ trả về cho ứng dụng IP của Service.
Kết luận
Vậy là ta đã tìm hiểu xong về Service Discovery, đây là phần lý thuyết rất quan trọng khi bạn làm việc với Kubernetes.
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ả?