Bài viết này sẽ giới thiệu khái quát về kiến trúc của Kubernetes (k8s) bao gồm các thành phần cấu thành một Kubernetes Cluster và các khái niệm dùng trong Kubernetes, giúp chúng ta hiểu rõ và chính xác khi hơn mới bắt đầu tìm hiểu và làm quen Kubernetes.
1. Các tiến trình của Kubernetes
Có một tập hợp các tiền trình core của Kubernetes tạo dựng nên cụm cluster. Cluster được chia ra thành các thành phần Master (hay còn gọi là Control Plane) và các thành phần Node(gọi là Worker Node hoặc Minion trước kia).
Sơ đồ của cụm Kubernetes cluster có thể được nhìn thấy ở hình mình họa bên dưới. Lưu ý rằng tên cũ của Kubernetes Minions được sử dụng trong sơ đồ, bây giờ chúng được gọi là Kubernetes Node.
Lưu ý: Kể từ Kubernetes 1.14 thì đã có tính năng cho phép thêm nhiều Master vào Cluster ở giai đoạn alpha, góp phần làm Master (Control Plane) có độ sẵn sàng cao hơn khi khởi tạo Kubernetes Cluster sử dụng công cụ kubeadm.
1.1. Các thành phần của Master
1.1.1. kube-apiserver
kube-apiserver đóng vai trò như một API Server, cung cấp truy cập đến Kubernetes API. Nơi mà các Kubernetes Resource được publish vào.
1.1.2. kube-controller-manager
kube-controller-manager là tiến trình chạy các controller để xử lý các background task của Cluster, giúp căn chỉnh cluster vào đúng với trạng thái đã khai báo(declare) ở Resource.
1.1.3. kube-scheduler
kube-scheduler đảm trách nhiệm vụ cấp phát các Pod ở các Node dựa trên các tiêu chí nhất định, các tiêu chí có thể là độ sẵn sàng của tài nguyên, tài nguyên yêu cầu như thế nào, các chính sách về workload....vv.
1.1.4. cloud-controller-manager
cloud-controller-manager chạy các controller để giao tiếp với các nhà cung cấp dịch vụ cloud nhất định. Ví dụ như Google Cloud, Azure, AWS hoặc Digital Ocean.
1.1.5. etcd
etcd là kho lưu trữ key-value phân tán. etcd trong một Kubernetes Cluster khá quan trọng, nó được ví như trái tim của Kubernetes Cluster, toàn bộ dữ liệu Cluster đều lưu trên đây (nó giống như là database của Kubernetes Master vậy đó 😊). Vì thế để an toàn, phải luôn có một kế hoạch sao lưu cho etcd khi vận hạnh một Kubernetes Cluster 😎.
1.2. Các thành phần của Node
1.2.1. kubelet
kubelet chạy trên mỗi node và có nhiệm vụ quản lý các Pod trên node đó, bao gồm việc kết nối với container runtime (ví dụ như Docker) để tạo và quản lý các container ở trong Pod, nó giao tiếp với Master qua API.
1.2.2. kube-proxy
kube-proxy giúp định tuyến (route) các kết nối đến Pod chính xác, nó cũng thực hiện việc cân bằng tải (load balancing) trên các Pod.
2. Các khái niệm trong Kubernetes
2.1. Label và Selector trong Kubernetes
Label (nhãn) là một trong những khái niệm Kubernetes cơ bản. Label là một cặp key-value gắn vào một Kubernetes Resource. Và mỗi Kubernetes Resource có thể có một hoặc nhiều label. Label phục vụ như một phương tiện để xác định một cụ thể một Resource hoặc tập hợp các Resource.
Label Selector cũng là các cặp key-value. Chúng dùng để chọn một label nhất định hoặc một tập hợp các label. Theo cơ chế này, một loại Resource có thể chọn (select) một hoặc nhiều các Resources thuộc loại khác. Label còn được dùng với kubectl
để truy vấn các loại Resource nhất định.
Sơ đồ sau mô tả cơ chế lựa chọn này với Service chọn một nhóm Pod qua selector.
2.1. Các loại Kubernetes Resource
Resource là trừu tượng (abstraction) ở mức cao chứa trạng thái khai báo (declarative) cho một thành phần cơ sở hạ tầng (infrastructure). Resource trong Kubernetes được publish vào kube-apiserver và nó là trách nhiệm của các Kubernetes Controller để đưa Cluster vào đúng với các trạng thái đã khai báo.
Có rất nhiều loại Resource khác nhau trong Kubernetes, danh sách đầy đủ các Resource có thể xem ở tài liệu API của Kubernetes. Các phần dưới đây chỉ giới thiệu các loại Resource quan trọng.
Lưu ý: Các phần phía dưới chỉ là giới thiệu sơ lược, chi tiết hơn mỗi loại Resource sẽ được giời thiệu ở loạt bài sau.
2.1.1. Resource nhóm Workloads trong Kubernetes
2.1.1.1. Pod
Pod là một đơn vị thực thi cơ bản và nhỏ nhất trong Kubernetes. Pod có thể có một hoặc nhiều container. Hình ảnh sau minh họa 3 loại container mà một Pod có thể có:
Loại container | Mô tả |
---|---|
Application | Đây là core container của một ứng dụng, một Pod phải có loại container này, các mô hình Pod phổ biến thường chỉ có application container. |
Sidecar | Pod có thể có container loại Sidecar làm một số công việc hữu ích để hỗ trợ cho application container. Container loại này thường đảm trách các vai trò như thu thập log hay làm reverse proxy. Một Pod có thể có rất nhiều Sidecar container. |
Init | Đôi khi cần phải thực hiện một số khởi tạo trước khi khởi chạy application container, ví dụ như khởi tạo database ban đầu. Một Pod có thể có rất nhiều Init container, chúng được chạy từng cái một theo thứ tự. |
Giống như các loại Resource khác, Pod cũng có thể có Label và những Label này được sử dụng bởi các Resource khác cho phép quản lý các Pod.
2.1.1.2. Deployment và ReplicaSet
Deployment trong Kubernetes cho phép quản lý vòng đời của các Pod và một Resource liên quan gọi là ReplicaSet. Deployment chứa đặc tả (specification) cho một Pod và các thông tin thêm, như số lượng Pod để chạy. Nếu cần chạy một ứng dụng stateless mà nó sẽ chạy liên tục, ví dụ như HTTP Server, thì chắc chắn cần Deployment. Deployment trong Kubernetes cho phép cập nhật một ứng dụng đang chạy mà không có downtime. Deployment cũng chỉ định một chiến lược (strategy) để khởi động lại Pod khi chúng die hoặc crash.
ReplicaSet được tạo khi Deployment được tạo hoặc được chỉnh sửa và thật sự là ReplicaSet được dùng như định nghĩa để tạo Pod. Sơ đồ sau mô tả mối quan hệ giữa Deployment, ReplicaSet và Pod trong Kubernetes:
2.1.1.3. DaemonSet
Một DaemonSet trong Kubernetes đảm bảo một Pod chạy trên tất cả hoặc tập hợp nhỏ các Kubernetes Node đã sẵn sàng. Ngay khi Node mới được thêm vào Kubernetes Cluster, thì Pod sẽ được thêm ngay vào. Ngay khi Node được xóa khỏi Kubernetes Cluster, thì Pod liên quan cũng được garbage collector thu gom. Xóa một DaemonSet sẽ đồng nghĩa với việc xóa tất cả các Pod mà nó đã tạo ra.
💡 Ví dụ về các trường hợp sử dụng DaemonSet trong Kubernetes:
- Chạy cluster storage daemon như glusterd hoặc ceph trên mỗi node.
- Chạy log collector daemon trên mỗi node như fluentd hoặc logstash.
- Chạy monitoring daemon trên mỗi node như Prometheus Node Exporter hoặc Datadog agent.
2.1.1.4. StatefulSet
Trong Kubernetes, một StatefulSet quản lý tập hợp các Pod về triển khai (deployment) và mở rộng (scaling), StatefulSet cung cấp đảm bảo về thứ tự (ordering) và sự duy nhất (uniqueness) của các Pod mà nó quản lý. Về thứ tự, nó đảm bảo thứ tự các Pod tạo ra và xóa đi. Về sự duy nhất, nó đảm bảo duy nhất về tên của Pod và storage volume riêng kèm theo Pod.
Trường hợp sử dụng StatefulSet trong thực tế thường thấy ở các database cluster phân tán dựa vào các thành viên (member) của cluster có tên riêng và dự liệu kèm theo phải được tạo ra riêng lúc boostrap của thành viên cluster. ElasticSearch là một ví dụ điển hình.
2.1.1.5. Job
Trong Kubernetes, Job tạo nên một hoặc nhiều Pod đảm bảo rằng ít nhất một lượng nhất định trong số chúng chạy đến khi hoàn thành. Không giống với ReplicaSet, ngay khi tiến trình trong container hoàn tất thành công, container sẽ không được khởi động lại. Sử dụng Job trong Kubernetes khi muốn chạy tiến trình một lần.
Một trường hợp sử dụng Job trong Kubernetes là một tải dữ liệu hàng loạt.
2.1.1.5. CronJob
Trong Kubernetes, CronJob chỉ đơn giản là chạy Job theo lịch định sẵn, định dạng lịch định sẵn theo định dạng của Cron trên Linux.
Lưu ý: Thời gian hẹn lịch được tính theo thời gian Master nơi mà Job được khởi đầu.
Một trường hợp sử dụng CronJob trong Kubernetes là sao lưu dữ liệu theo lịch.
2.1.2. Resource nhóm Discovery và Load Balancing trong Kubernetes
2.1.2.1. Service (svc)
Trong Kubernetes, Service được dùng để nhóm lại một hoặc nhiều Pod bằng Label Selector. Service cung cấp ClusterIP và DNS Name cho các Pod.
Tiến trình Kube Proxy sử dụng thông tin có trong Service để cấu hình các rule iptables thích hợp trên mỗi Node để các traffic client cần truy cập Service được định tuyến vào đúng Pod phù hợp.
2.1.2.2. Ingress
Trong Kubernetes, Ingress được dùng để cấu hình Ingress Controller vì thế Service có thể được truy cập được từ phía bên ngoài Cluster, thông thường truy cập qua giao thức HTTP. Ingress còn cung cấp Load Balancing, SSL termination và virtual hosting theo dạng name-based.
Ingress Controller là một reverse proxy mà theo dõi Ingress Resource liên tục thông qua Kubernetes API Server và tự cấu hình rule thích hợp cho mỗi Ingress.
2.1.3. Resource nhóm Config, Storage và Cluster trong Kubernetes
2.1.3.1. ConfigMap
Trong Kubernetes, ConfigMap cho phép lưu file config độc lập và không phụ thuộc với container image. Các file lưu với ConfigMap có thể được mount vào container trong Pod lúc chạy.
2.1.3.2. Secret
Trong Kubernetes, Secret cho phép lưu các thông tin nhạy cảm như password, token, key. Gần giống với ConfigMap, tuy nhiên Secret có thể truy cập như một biến môi trường.
2.1.3.3. Volume, PersistentVolume và PersistentVolumeClaim
Trong Kubernetes, Volume là một thư mục có thể chứa dữ liệu. Volume là một thành phần của Pod và không độc lập với nó. Một Volume được tạo trong đặc tả của Pod. Một Volume không thể tự xóa. Một Volume được truy cập bởi tất cả các container trong Pod. Mỗi container mà muốn truy cập vào Volume phải mount riêng lẻ.
Một Kubernetes Volume tồn tại lâu hơn bất kỳ container nào, nhưng khi Pod kèm theo mất, Volume cũng mất theo. Tuy nhiên, các file của một số loại Volume vẫn tiếp tục tồn tại trong local hoặc cloud storage, ngay cả sau khi Volume không còn.
Kubernetes Volume có nhiều chức năng hơn Docker Volume. Volume có thể cung cấp quyền truy cập vào bộ lưu trữ đĩa local hoặc cloud storage. Một Pod có thể sử dụng kết hợp chúng cùng một lúc. Volume trong Kubernetes bao gồm thư mục trống, filesystem của Node hoặc storage đặc thù của nhà cung cấp dịch vụ cloud ví dụ như awsEleasticBlockStore hay gcePersistentDisk dùng vào mục đích long-term storage, có thể tham khảo thêm tại đây.
Để giúp trừu tượng đi các chi tiết cơ sở hạ tầng, các nhà phát triển Kubernetes đã tạo ra PersistentVolume và PersistentVolumeClaim. Thật không may, tên là một chút sai lệch, bởi vì các Volume thuần vẫn có thể có persistent storage. PersisententVolume (PV) và PersisentVolumeClaims (PVC) thêm độ phức tạp so với chỉ sử dụng Volume thuần. Tuy nhiên, PV rất hữu ích cho việc quản lý tài nguyên lưu trữ cho các dự án lớn.
Với PV, người dùng Kubernetes vẫn dủng Volume, nhưng trước tiên cần có hai bước:
Một PersistentVolume được cung cấp bởi Cluster Admin (hoặc nó được cung cấp một cách linh hoạt).
Một người dùng Cluster cá nhân cần lưu trữ cho Pod tạo ra một manifest PersistentVolumeClaim. Nó chỉ định số lượng và loại lưu trữ họ cần. Kubernetes sau đó tìm và dự trữ dung lượng cần thiết.
Sau đó, người dùng tạo một Pod có Volume sử dụng PVC. PersistentVolume có vòng đời độc lập với bất kỳ Pod nào. Trên thực tế, Pod thậm chí không biết về PV, chỉ là PVC. PVC tiêu thụ tài nguyên PV, tương tự như cách Pod tiêu thụ tài nguyên Node.
2.1.3.4. NameSpace
Trong Kubernetes, NameSpace là nơi chúng ta đặt tất cả lại với nhau. Một NameSpace có thể được coi là giống như một môi trường. Bộ sưu tập các Resource có thể được triển khai vào NameSpace để tạo thành một nhóm các thành phần liên quan.
Ví dụ về việc sử dụng NameSpace có thể là để tạo môi trường DEV hoặc chia sẻ một tập hợp các dịch vụ được sử dụng bởi các NameSpaces khác, ví dụ: Ingress Controller.
3. Lời kết
Chúng ta đã đề cập đến một lượng lớn về các thành phần, khái niệm trong Kubernetes và nó chỉ ở mức rất cơ bản 😊. Kubernetes đòi hỏi phải hiểu nhiều khái niệm trừu tượng, đừng lo lắng nếu nhưng bạn chưa nhớ và hiểu ở lần đầu tiên 😂.
Bạn đã có một Kubernetes Cluster để thực hành các loạt bài về Kubernetes tiếp theo của blogd.net chưa? Nếu chưa thì hãy tham khảo bài Cài đặt Kubernetes Cluster để biết cách tự tay thiết lập một Kubernetes Cluster cho riêng mình nhé.