Bài viết này sẽ giới thiệu rõ Kubernetes (k8s) là gì và cũng đồng thời cho bức tranh tổng quan về nhiệm vụ của Kubernetes nói riêng hoặc Container Scheduler nói chung.
1. Thế nào là Container Scheduler?
Trong môn thể thao bóng đá, nếu chúng ta không có một người huấn luyện viên cho đội bóng thì khi thi đấu, đội bóng này sẽ chạy quanh sân mà không có sự phối hợp nào cả. Không có tấn công và không có phòng thủ. Họ chỉ chạy theo quả bóng 😂. Tất cả tiến về phía trước quả bóng, ai đó đá nó sang trái, và họ di chuyển theo hướng đó, chỉ để bắt đầu chạy lại vì ai đó lại đá bóng.
Nếu họ là một đội "thực sự", họ sẽ cần một huấn luyện viên. Họ cần ai đó cho họ biết chiến lược là gì, ai nên làm gì và khi nào nên thực hiện hành vi phạm tội hoặc quay trở lại để bảo vệ mục tiêu. Họ cần ai đó điều phối (orchestrate) họ 👌.
Ai đó sẽ bị thương và sẽ phải được thay thế hoặc, khi không có người thay thế, những người còn lại sẽ phải đảm nhận nhiệm vụ của anh ta (self-healing). Bóng đá có thể dễ so sánh với các mô hình Cluster. Chúng ta chỉ cần ai đó bảo chúng ta cần phải làm gì, Cluster cần cái gì đó để điều phối toàn bộ dịch vụ (service) và tài nguyên (resource). Cả hai không chỉ cần đưa ra quyết định trước, mà còn phải liên tục theo dõi trận đấu hoặc Cluster, điều chỉnh chiến lược / scheduling tùy thuộc vào các ảnh hưởng bên trong và bên ngoài. Đội bóng cần huấn luyện viên và Cluster cần scheduler. Chúng ta cần một framework mà quyết định nơi một dịch vụ sẽ được triển khai và đảm bảo rằng nó duy trì các mong muốn đặc tả khi chạy.
Cluster scheduler có khá nhiều nhiệm vụ. Nó đảm bảo rằng các tài nguyên được sử dụng hiệu quả và trong các ràng buộc. Nó đảm bảo rằng các dịch vụ luôn luôn hoạt động. Nó cung cấp khả năng chịu lỗi và tính sẵn sàng cao. Nó đảm bảo rằng số lượng bản sao(replica) được chỉ định được triển khai. Scheduler đảm bảo rằng trạng thái mong muốn của một dịch vụ hoặc node luôn luôn được đáp ứng.
Thay vì sử dụng các phương pháp mệnh lệnh (imperative) 🔪 để đạt được mục tiêu, chúng ta có thể phương pháp khai báo (declarative) 📒. Chúng ta có thể yêu cầu scheduler trạng thái mong muốn là gì và nó sẽ cố gắng hết sức để đảm bảo rằng mong muốn của chúng ta (gần như) luôn luôn được đáp ứng. Ví dụ, chúng ta thực thi tiến trình triển khai 5 lần và hy vọng chúng ta có 5 bản sao của dịch vụ mà chúng ta đang muốn triển khai. Tuy nhiên, với scheduler rằng trạng thái mong muốn của chúng tôi là có dịch vụ chạy với 5 bản sao.
Sự khác biệt giữa các phương pháp mệnh lệnh và khai báo có vẻ nhỏ nhưng trên thực tế, là rất lớn. Với phương pháp khai báo trạng thái mong muốn, scheduler có thể giám sát Cluster và thực hiện các hành động bất cứ khi nào trạng thái thực tế không khớp với mong muốn. So sánh với việc chạy 5 lần script để triển khai một dịch vụ, cả hai phương pháp đều cho một kết quả ban đầu giống nhau. Nhưng đoạn script triển khai trên sẽ không đảm bảo rằng kết quả được duy trì theo thời gian ⏳. Nếu một giờ sau, một trong những bản sao bị lỗi, hệ thống của chúng tôi sẽ gặp vấn đề. Theo cách cổ điển từ trước đến giờ, chúng ta đã giải quyết vấn đề đó bằng sự kết hợp các alert và can thiệp thủ công. Người vận hành sẽ nhận được alert từ hệ thống monitoring rằng một bản sao bị lỗi, anh ta đăng nhập vào máy chủ và khởi động lại tiến trình. Nếu toàn bộ máy chủ bị hỏng, anh ta có thể setup một máy chủ mới hoặc anh ta có thể triển khai bản sao bị lỗi cho một trong các máy chủ khác. Nhưng, trước khi làm điều đó, anh ta cần kiểm tra xem máy chủ nào có RAM và CPU. Tất cả điều đó, và nhiều hơn nữa, được thực hiện bởi scheduler mà không cần sự can thiệp của con người 😮. Hãy nghĩ về scheduler như các người vận hành liên tục theo dõi hệ thống và khắc phục sự khác biệt giữa trạng thái mong muốn và thực tế. Sự khác biệt là scheduler nhanh hơn và chính xác hơn. Scheduler không cảm thấy mệt mỏi, scheduler không cần phải đi vệ sinh và scheduler không yêu cầu tiền lương, đơn gian vì chúng là máy móc 😊.
Container scheduler dựa trên các nguyên tắc giống như khái niệm về scheduler trong khoa học máy tính. Sự khác biệt đáng kể là chúng dùng container như là một đơn vị triển khai. Container scheduler triển khai các dịch vụ như là một container image. Container scheduler cố gắng sắp xếp chúng tùy thuộc vào thông số kỹ thuật của RAM và CPU mong muốn. Nó đang đảm bảo rằng số lượng bản sao mong muốn (hầu như) luôn chạy. Container scheduler làm nhiệm vụ giống như các scheduler khác, tuy nhiên container là đơn vị đóng gói và triển khai nhỏ nhất. Và điều đó mang lại cho họ một lợi thế khác biệt. Container scheduler không quan tâm những gì bên trong container. Từ góc nhìn của Container scheduler, tất cả các container đều giống nhau.
Container mang lại khá nhiều ưu điểm và lợi ích mà các phương pháp triển khai khác không có, bạn có thể đọc thêm vấn đề này tại bài Container là gì?
2. Kubernetes là gì?
Lưu ý: Cái tên Kubernetes có nguồn gốc từ Hy Lạp, có nghĩa là thuyền trưởng, người lái xe hoặc phi công. K8s là một từ viết tắt có nguồn gốc bằng cách thay thế 8 chữ cái "ubernete" và bằng số "8", cách phát âm chính xác Kubernetes theo từ điển là
/koo-ber-nay'-tace/
✅, có thể tham khảo thêm tại đây.
Để hiểu Kubernetes, điều quan trọng là chúng ta phải nhận ra chạy container một cách trực tiếp hoặc thủ công là một ý kiến khá tệ 👎. Container là một thực thể cấp thấp, nó cần một framework trên nó. Nó cần một thứ gì đó sẽ cung cấp tất cả các tính năng bổ sung mà chúng ta mong đợi từ các dịch vụ (service) được triển khai vào cụm cluster. Nói cách khác, container rất tiện dụng nhưng không nên chạy trực tiếp trong môi trường production. Container rất dễ để chạy, các bạn dev có thể dùng container để tạo ra môi trường để dev hoàn hảo trong vài giây, tuy nhiên khi dùng container ở môi trường production thì không đơn giản như vậy. Lý do rất đơn giản. Các container, tự chúng, không cung cấp khả năng chịu lỗi (fault tolerance). Chúng không thể được triển khai dễ dàng đến mức tối ưu trong một cụm cluster. Điều đó không có nghĩa là bản thân các container không hữu ích. Nhưng nó đòi hỏi nhiều hơn nếu chúng ta khai thác sức mạnh thực sự của nó. Nếu chúng ta cần vận hành các container quy mô và nếu chúng ta cần chúng có khả năng chịu lỗi và tự phục hồi (self-healing) 🤺, và có các tính năng khác mà chúng ta mong đợi từ các cụm cluster hiện đại, thật sự chúng ta cần nhiều hơn. Chúng tôi cần ít nhất một scheduler, có thể nhiều hơn nữa.
Kubernetes lần đầu tiên được phát triển bởi một nhóm tại Google. Nó dựa trên kinh nghiệm của họ từ việc chạy container quy mô trong nhiều năm. Sau đó, nó đã được tặng cho Cloud Native Computing Foundation (CNCF). Đây là một dự án nguồn mở thực sự với tốc độ cao nhất trong lịch sử, hàng loạt các hội thảo lớn về Kubernetes lẫn Container trong các năm gần đây như KubeCon, ContainerCon, DockerCon...vv
Kubernetes là một Container scheduler và hơn thế nữa. Chúng ta có thể dùng nó để triển khai các dịch vụ của chúng ta, để roll-out các bản release mới mà không bị downtime hoặc để mở rộng (scale out) và thu hẹp (scale in) các dịch vụ này. Nó có thể chạy trên private cloud hoặc các public cloud, từ các máy chủ siêu khủng cho đến các máy chủ mini như Raspberry Pi. Nó có thể triển khai ở môi trường on-premise hoặc hybrid. Chúng ta có thể di chuyển cụm Kubernetes Cluster từ nhà cung cấp dịch vụ lưu trữ này sang nhà cung cấp dịch vụ lưu trữ khác mà không thay đổi (gần như) bất kỳ quy trình triển khai và quản lý nào. Kubernetes có thể dễ dàng mở rộng để phục vụ gần như mọi nhu cầu. Chúng ta có thể chọn module nào chúng ta sẽ sử dụng và chúng ta có thể tự phát triển các tính năng bổ sung và plug chúng vào.
Nếu chúng ta chọn sử dụng Kubernetes, chúng ta quyết định từ bỏ quyền kiểm soát thủ công/truyền thống. Kubernetes sẽ quyết định nơi để chạy một cái gì đó và làm thế nào để hoàn thành trạng thái mà chúng ta chỉ định. Kiểm soát như vậy cho phép Kubernetes đặt các bản sao (replica) của một dịch vụ trên máy chủ phù hợp nhất, để khởi động lại chúng khi cần thiết, sao chép chúng và mở rộng chúng. Chúng ta có thể nói rằng tự phục hồi (self-healing) là một tính năng có trong thiết kế của nó ngay từ đầu.
Việc triển khai không thời gian downtime hệ thống, khả năng chịu lỗi, tính sẵn sàng cao, khả năng mở rộng cao và tự phục hồi là quá đủ để thấy giá trị trong Kubernetes. Danh sách những gì Kubernetes làm được là rất nhiều và tăng nhanh. Cùng với Docker, nó đang trở thành một nền tảng bao trùm toàn bộ vòng đời phát triển, triển khai và phân phối phần mềm.
Dự án Kubernetes vừa mới bắt đầu. Nó đang ở giai trứng nước, và chúng ta có thể mong đợi những cải tiến lớn và các tính năng mới sắp ra mắt. Tuy nhiên, đừng để bị lừa với "giai đoạn trứng nước". Mặc dù dự án còn non trẻ, nhưng nó có một trong những cộng đồng lớn nhất đằng sau nó và được sử dụng trong một các công ty lớn trên thế giới, thậm chí các công ty cung cấp dịch vụ như Google (GKE), Amazon (EKS), Microsoft (AKS) hay Digital Ocean đã bắt đầu cung cấp dịch vụ Kubernetes ở thời điểm viết bài này. Đừng chờ đợi, hãy tiềm hiểu và thử nghiệm xem Kubernetes có phù hợp để triển khai hệ thống của bạn không nhé 😇.