Kubernetes Cluster Architecture

“The whole is greater than the sum of its parts.” – Aristotle

10 min
Nội dung bài viết
Bài viết này cũng có bản English.
banner

Hi các bạn 👋. Mình là Hùng Anh.

Đây là bài thứ năm trong series Kubernetes Fundamentals. Ở bài trước, mình và bạn đã tìm hiểu về chủ đề container. Cuối bài, mình có đặt ra 1 câu hỏi: liệu có công nghệ nào giúp tự động điều phối và quản lý các container khi phải triển khai chúng trên nhiều server khác nhau để đảm bảo tính HA không?

Trên thế giới đã có rất nhiều công cụ khác nhau để giải quyết bài toán này như Kubernetes, OpenShift, Docker Swarm, Nomad, ... Trong số đó nổi bật nhất và được dùng phổ biến nhất có lẽ vẫn là Kubernetes.

Trong bài này hãy cùng mình tìm hiểu kỹ hơn Kubernetes là gì và kiến trúc của nó như nào nhé.

Bắt đầu thôi.

1. Kubernetes là gì?

Kubernetes (K8s) là 1 container orchestrator được Google open source vào năm 2014, và hiện do CNCF (Cloud Native Computing Foundation) duy trì.

Với Kubernetes, chúng ta chỉ cần cấu hình trạng thái mong muốn của hệ thống (ví dụ như bao nhiêu instance, lượng tài nguyên sử dụng, ...), sau đó Kubernetes sẽ triển khai đúng như khai báo, và luôn duy trì trạng thái đó:

  • Nếu container chết, K8s restart lại.
  • Nếu node sập, K8s chuyển container sang node khác.
  • Nếu traffic tăng, K8s scale thêm instance.

Cơ chế đằng sau khá đơn giản: Kubernetes liên tục so sánh trạng thái thực tế với trạng thái đã được cấu hình, và tự điều chỉnh mỗi khi 2 trạng thái này lệch nhau.

Phần tiếp theo mình sẽ cùng tìm hiểu sâu hơn về kiến trúc cluster trong Kubernetes nhé.

2. K8s Cluster Overview

cluster-overview

1 cluster Kubernetes gồm 2 thành phần chính phối hợp với nhau:

  • Control Plane: Thành phần ra các quyết định như cái nào cần chạy, chạy ở đâu, và trạng thái hiện tại của cluster đã khớp với cấu hình hay chưa.
  • Node: Là một server vật lý (hoặc VM). Đây sẽ là nơi chạy các container của application.

1 cluster cần ít nhất 1 node để có thể chạy được. Trong môi trường production, kiến trúc cluster thường có nhiều node để đảm bảo tính HA — nếu 1 máy gặp sự cố thì cluster vẫn sẽ hoạt động bình thường.

Thông thường khi tự triển khai 1 K8s cluster, ta sẽ sử dụng nhiều server vật lý hoặc nhiều VM có kết nối mạng với nhau, rồi SSH vào từng server, sau đó cài các thành phần cần thiết (như container runtime, kubelet, ...) và dùng công cụ như kubeadm để join chúng thành 1 K8s cluster.

3. Các thành phần của Control Plane

control-plane-mindmap

Control Plane gồm 5 thành phần chính. Chúng phối hợp với nhau để quản lý cả cụm cluster, chứ không trực tiếp chạy container nào cả.

3.1. Kube-apiserver

Kube-apiserver là điểm truy cập trung tâm của cluster, chịu trách nhiệm expose Kubernetes API. Gần như mọi thành phần khác (kubectl, các thành phần còn lại trong Control Plane, các node) đều chỉ giao tiếp với cluster thông qua kube-apiserver, chứ không bao giờ call trực tiếp với nhau.

Nó cũng được thiết kế để scale ngang thay vì chạy 1 instance duy nhất. Chúng ta hoàn toàn có thể chạy nhiều instance kube-apiserver song song và thực hiện load balancing cho các instance của nó.

3.2. Etcd

Etcd là 1 key-value store nhất quán, có tính sẵn sàng cao, và là nơi lưu toàn bộ trạng thái của cluster (số replica mong muốn, trạng thái hiện tại, ...). Mất etcd mà không có backup nghĩa là mất toàn bộ thông tin về những gì cluster phải chạy, dù mọi node vẫn còn nguyên.

3.3. Kube-scheduler

Kube-scheduler theo dõi các Pod mới tạo mà chưa được gán node, rồi chọn ra node nào sẽ chạy chúng. Lựa chọn đó không ngẫu nhiên, nó cân nhắc các yếu tố như:

  • Pod cần bao nhiêu tài nguyên (CPU/RAM), có nhỏ hơn lượng tài nguyên còn thừa của các node còn trống không?
  • Các ràng buộc về phần cứng, phần mềm, hoặc policy (1 Pod cần GPU chỉ có thể chạy trên node có GPU)
  • Quy tắc affinity/anti-affinity: affinity là ràng buộc yêu cầu đặt các Pod gần nhau (ví dụ 2 Pod thường xuyên giao tiếp với nhau nên chạy chung 1 node để giảm độ trễ), còn anti-affinity thì ngược lại — yêu cầu tách các Pod ra xa nhau (ví dụ 2 replica của cùng 1 app nên nằm trên 2 node khác nhau, để 1 node chết không làm mất cả 2).
  • Dữ liệu mà Pod cần đang nằm trên node nào — đặt Pod gần dữ liệu sẽ giúp đọc/ghi nhanh hơn, thay vì phải kéo dữ liệu qua mạng.
  • Deadline của workload, và mức độ các workload trên cùng 1 node tranh chấp tài nguyên của nhau — 2 workload nặng nằm chung 1 node có thể làm chậm lẫn nhau.

3.4. Kube-controller-manager

Kube-controller-manager có nhiệm vụ quản lý và chạy các controller trong K8s. Dưới đây là các controller tiêu biểu:

  • Node controller: Phát hiện có node bị go down, đánh dấu node đó là NotReady, và sau 1 khoảng thời gian sẽ loại bỏ các Pod trên node đó để chúng được tạo lại trên các node khác.
  • Job controller: Quản lý các K8s Job và theo dõi, tạo các Pod để chạy các task cho tới khi xong.
  • EndpointSlice controller: Theo dõi Pod nào thực sự đang đứng sau mỗi Service.
  • ServiceAccount controller: Tạo 1 ServiceAccount mặc định cho mỗi namespace mới trong Kubernetes.

Còn nhiều controller khác nữa, và tất cả các controller này đều được biên dịch chung vào cùng 1 binary.

3.5. Cloud-controller-manager

Cloud-controller-manager chỉ xuất hiện khi cluster chạy trên 1 cloud provider (AWS, GCP, Azure...) — 1 cluster chạy on-prem hoặc trên chính máy của bạn sẽ không có thành phần này. Nó tồn tại để tách phần logic đặc thù của cloud ra khỏi phần còn lại của Kubernetes, và chạy các controller như:

  • Node controller: Hỏi lại cloud provider xem 1 node đã ngừng phản hồi có thực sự bị xóa hay chưa.
  • Route controller: Thiết lập các route mạng trong hạ tầng cloud bên dưới.
  • Service controller: Tạo, cập nhật, xóa load balancer của chính cloud provider đó.

4. Các thành phần trên Node

node-mindmap

Node là nơi thực thi các quyết định của Control Plane. Mỗi node có nhiều thành phần và chúng có các nhiệm vụ riêng biệt nhé.

4.1. Kubelet

Kubelet là agent chạy trên mỗi node. Nó được giao cho một tập các mô tả cần chạy những gì (PodSpec), và đảm bảo các container đó thực sự đang chạy và khỏe mạnh. Kubelet chỉ quản lý container do chính Kubernetes tạo ra và không quản lý các container mà bạn tự tay khởi động.

4.2. Kube-proxy (Tuỳ chọn)

Kube-proxy duy trì các network rule trên mỗi node, cho phép traffic đi đúng tới Pod thông qua 1 Kubernetes Service. Đây là thành phần tuỳ chọn. Nếu network plugin bạn dùng đã tự đảm nhiệm việc forward traffic này thì bạn không cần chạy kube-proxy nữa.

4.3. Container Runtime

Đây chính là container runtime đã nói ở bài trước. Nó có thể là containerd, CRI-O, hay bất kỳ implementation nào khác của chuẩn CRI. Nó là phần thực sự tạo và chạy các container mà kubelet yêu cầu.

5. Addons

addons-mindmap

Addons không phải là phần lõi của Kubernetes. Chúng được triển khai như những resource Kubernetes bình thường (giống như 1 Deployment, 1 DaemonSet, ...), và sẽ thường được nằm trong namespace kube-system. DNS gần như là bắt buộc; số còn lại là tuỳ chọn, nhưng phần lớn cluster thực tế rồi cũng có lúc cần đến chúng.

  • DNS: Cấp cho mỗi Service 1 domain nội bộ, nhờ đó các Pod có thể gọi tới Service qua tên domain thay vì phải hardcode địa chỉ IP. Các container do Kubernetes khởi động sẽ tự động dùng DNS server này.
  • Dashboard: 1 web UI để bạn xem và quản lý cluster.
  • Monitoring & Logging: Monitoring ghi lại metric dạng time-series của container vào 1 database trung tâm để truy vấn; logging lưu log container vào 1 nơi tập trung để bạn tìm kiếm thay vì phải SSH vào từng node.
  • Network Plugins (CNI): Kubernetes giao phần mạng cho network plugin (Calico, Flannel, Cilium...) và bạn phải tự cài. Plugin đảm nhiệm 2 việc:
    • Cấp IP cho từng Pod và giúp các Pod nằm trên những node khác nhau giao tiếp được với nhau.
    • Network policy (nhiều plugin hỗ trợ): quy tắc kiểm soát Pod nào được phép gọi tới Pod nào.

6. Cách 1 cluster thực sự được triển khai

deployment-mindmap

Những gì vừa nói ở trên đều là về vai trò của từng thành phần, chưa phải cách chúng được cài đặt lên các server thật. Trên thực tế, 1 cluster thường được triển khai theo 1 trong vài kiểu sau:

  • 1 server duy nhất: Mọi thành phần Control Plane và mọi node trên cùng 1 server. Phù hợp để học, nhưng không dùng được cho production vì 1 server chết sẽ làm dừng toàn bộ cluster.
  • Nhiều server: Control Plane được triển khai trên vài server, cộng thêm nhiều node tách riêng (mỗi node là 1 server độc lập).
  • Managed: 1 cloud provider (EKS, GKE, AKS...) tự chạy và vận hành Control Plane cho bạn. Bạn vẫn phải tự tạo và trả tiền cho các worker node (thường qua tính năng node group của cloud), rồi deploy ứng dụng lên đó. 1 số dịch vụ như GKE Autopilot còn quản lý luôn cả node — bạn chỉ việc deploy container.

Các công cụ như kubeadm và kops giúp tự động hóa việc cài đặt các thành phần này. Và vì các thành phần giao tiếp với nhau qua interface chuẩn (như CRI cho container runtime, CNI cho networking) nên ta hoàn toàn có thể thay thế từng thành phần mà không ảnh hưởng tới phần còn lại của hệ thống.

Kubernetes cũng cho phép mở rộng thêm:

  • 1 scheduler tự viết chạy song song với scheduler mặc định.
  • 1 CRD (Custom Resource Definition) để thêm loại object mới vào API.
  • 1 admission webhook để can thiệp vào request trước khi request đó được lưu.

7. Tổng kết

Tới đây bạn đã có cái nhìn tổng quan về kiến trúc cluster của K8s và các thành phần bên trong nó.

Một K8s cluster sẽ bao gồm 2 thành phần chính:

  • Control Plane: Quản lý cả cụm cluster. Các thành phần bao gồm kube-apiserver, etcd, kube-scheduler, kube-controller-manager, cloud-controller-manager.
  • Node: Nơi chạy các container của application. Các thành phần bao gồm kubelet, kube-proxy, container runtime.

Ngoài ra còn có các addon (DNS, dashboard, monitoring, network plugin) bổ sung các chức năng còn lại, và các công cụ như kubeadm giúp triển khai cluster lên các server thật.

Ở bài sau, mình và bạn sẽ tiếp tục tìm hiểu cách sử dụng các object của K8s như Pod, Deployment, Service, StatefulSet, ... thông qua usecase thực tế và ví dụ cụ thể nhé.

Giờ thì tạm biệt và hẹn gặp lại.

Happy reading! 🍵

Tài liệu tham khảo

  1. Kubernetes Components - Kubernetes documentation
  2. Kubernetes Cluster Architecture - Kubernetes documentation

Bài viết liên quan

Đừng bỏ lỡ bài mới nhé!