Loạt bài viết sổ tay Kubernetes:
Trong hướng dẫn trước bạn đã tìm hiểu về Kubernetes, cách cài đặt Kubernetes và chạy ứng dụng đầu tiên sử dụng Kubernetes.
Trong hướng dẫn này, bạn sẽ tìm hiểu về kiến trúc Kubernetes và cá khái niệm cơ bản trong Kubernetes như: cluster, node, control plane, pod, service, load balancer, ... Chúng ta bắt đầu thôi!
Trong thế giới của Kubernetes, một nút (node) có thể là một máy vật lý hoặc một máy ảo với một vai trò nhất định. Một tập hợp các máy hoặc máy chủ như vậy sử dụng mạng chia sẻ để giao tiếp với nhau được gọi là một cụm (cluster).
Trong thiết lập trên máy cục bộ của bạn, minikube
là một cụm Kubernetes với một nút duy nhất. Vì vậy, thay vì có nhiều máy chủ như trong sơ đồ trên, minikube
chỉ có một máy chủ đóng vai trò vừa là máy chủ chính, vừa là nút.
Mỗi máy chủ trong một cụm Kubernetes có một vai trò. Có thể có hai vai trò:
Mỗi máy chủ trong cụm của bạn sẽ có một tập hợp các thành phần được thiết lập. Số lượng và loại các thành phần đó có thể khác nhau tùy thuộc vào vai trò của máy chủ trong cụm của bạn. Điều đó có nghĩa là các nút không có tất cả các thành phần mà Control Plane có.
Trong các phần sắp tới, bạn sẽ có cái nhìn chi tiết hơn về các thành phần riêng lẻ tạo nên một cụm Kubernetes.
Control Plane trong một cụm Kubernetes bao gồm 5 thành phần sau:
kubectl
.kube-controller-manager
nhóm tất cả các tiến trình bộ điều khiển thành một tiến trình duy nhất.kube-scheduler
thực hiện nhiệm vụ lập lịch trong Kubernetes đảm bảo không có máy chủ nào trong cụm bị quá tải.minikube
, thành phần này không tồn tại.So với Control Plane, các nút (node) có số lượng thành phần rất nhỏ. Các thành phần này như sau:
etcd
để cập nhật thông tin trạng thái.Theo tài liệu Kubernetes -
"Object (đối tượng) là các thực thể lâu dài trong hệ thống Kubernetes. Kubernetes sử dụng các thực thể này để đại diện cho trạng thái của cụm của bạn. Cụ thể, chúng có thể mô tả những ứng dụng trong container đang chạy, các tài nguyên có sẵn cho chúng và các chính sách xung quanh hành vi của chúng."
Khi bạn tạo một đối tượng Kubernetes, bạn đang nói với hệ thống Kubernetes rằng bạn muốn đối tượng này tồn tại bất kể điều gì và hệ thống Kubernetes sẽ liên tục hoạt động để giữ cho đối tượng hoạt động.
Theo tài liệu Kubernetes -
"Pod là đơn vị máy tính có thể triển khai nhỏ nhất mà bạn có thể tạo và quản lý trong Kubernetes".
Một Pod thường bao gồm một hoặc nhiều container có liên quan chặt chẽ với nhau, chia sẻ vòng đời và các tài nguyên.
Mặc dù một Pod có thể chứa nhiều hơn một container, nhưng bạn không nên chỉ đặt các container bất kỳ vào một Pod. Các container trong một Pod phải có liên quan chặt chẽ đến mức chúng có thể được coi như một ứng dụng duy nhất.
Ví dụ: back-end API của bạn có thể phụ thuộc vào cơ sở dữ liệu nhưng điều đó không có nghĩa là bạn sẽ đặt cả hai trong cùng một Pod. Trong toàn bộ bài viết này, bạn sẽ không thấy bất kỳ Pod nào có nhiều hơn một container đang chạy.
Thông thường, bạn không nên quản lý một Pod trực tiếp. Thay vào đó, bạn nên làm việc với các đối tượng (object) cấp cao hơn có thể cung cấp cho bạn khả năng quản lý tốt hơn nhiều. Bạn sẽ tìm hiểu về các đối tượng cấp cao hơn này trong phần sau.
Theo tài liệu Kubernetes -
"Một dịch vụ (service) trong Kubernetes là một cách trừu tượng để hiển thị một ứng dụng đang chạy trên một nhóm các Pod như một dịch vụ mạng".
Pod của Kubernetes có bản chất là không bền vững. Chúng được tạo ra và sau một thời gian khi chúng bị hủy, chúng sẽ không được tái sử dụng.
Thay vào đó, các Pod mới giống hệt nhau sẽ thay thế các Pod cũ. Một số đối tượng Kubernetes cấp cao hơn thậm chí còn có khả năng tạo và hủy các Pod động.
Một địa chỉ IP mới được chỉ định cho mỗi Pod tại thời điểm tạo. Nhưng trong trường hợp một đối tượng cấp cao có thể tạo, hủy và nhóm một số Pod lại với nhau, nhóm Pod đang chạy trong một thời điểm này có thể khác với nhóm Pod chạy ứng dụng đó tại một thời điểm khác.
Điều này dẫn đến một vấn đề: nếu một số nhóm Pod phụ thuộc vào nhóm Pod khác trong cụm của bạn, làm cách nào để chúng tìm ra và theo dõi địa chỉ IP của nhau?
Theo tài liệu Kubernetes -
"Một Service (dịch vụ) là một phần trừu tượng định nghĩa một tập hợp các Pod và một chính sách để truy cập chúng".
Về cơ bản, điều này có nghĩa là một Service sẽ nhóm một số Pod thực hiện cùng một chức năng và mô tả chúng dưới dạng một thực thể duy nhất.
Bằng cách này, sự nhầm lẫn trong việc theo dõi nhiều Pod sẽ không xuất hiện trong cửa sổ vì Service hoạt động như một loại thiết bị giao tiếp cho tất cả chúng.
Trong ví dụ hello-kube
ở hướng dẫn trước, bạn đã tạo một loại dịch vụ là LoadBalancer
cho phép các yêu cầu từ bên ngoài cụm kết nối với các Pod đang chạy bên trong cụm.
Bất kỳ lúc nào bạn cần cấp quyền truy cập vào một hoặc nhiều Pod cho một ứng dụng khác hoặc một cái gì đó bên ngoài cụm, bạn nên tạo một Service.
Ví dụ: nếu bạn có một tập hợp các Pod đang chạy các máy chủ web có thể truy cập được từ internet, một Service sẽ cung cấp thông tin tóm tắt cần thiết.
Bây giờ bạn đã hiểu về các thành phần của Kubernetes, đây là phần trình bày trực quan về cách chúng hoạt động cùng nhau ở phía sau:
Trước khi tôi giải thích chi tiết, hãy xem tài liệu Kubernetes nói gì -
"Để làm việc với các đối tượng Kubernetes - cho dù tạo, sửa đổi hay xóa chúng - bạn sẽ cần sử dụng Kubernetes API. Khi bạn sử dụng giao diện dòng lệnh kubectl
, CLI thực hiện các lệnh gọi Kubernetes API cần thiết cho bạn."
Lệnh đầu tiên mà bạn chạy là lệnh run
. Nó như sau:
kubectl run hello-kube --image=fhsinchy/hello-kube --port=80
Lệnh run
có trách nhiệm tạo một pod mới để chạy một image nhất định. Khi bạn thực thi lệnh này, các sự kiện sau sẽ xảy ra bên trong cụm Kubernetes:
kube-api-server
nhận yêu cầu, xác nhận nó và xử lý nó.kube-api-server
giao tiếp với thành phần kubelet
trên nút và cung cấp các chỉ dẫn cần thiết để tạo pod.kubelet
bắt đầu làm việc để thiết lập và chạy pod và cũng lưu giữ thông tin trạng thái được cập nhật trong kho lưu trữ etcd
.Cú pháp chung cho lệnh run
như sau:
kubectl run <pod name> --image=<image name> --port=<port to expose>
Bạn có thể chạy bất kỳ image hợp lệ nào bên trong một pod. Docker Image fhsinchy/hello-kube chứa một ứng dụng JavaScript rất đơn giản chạy trên cổng 80 bên trong container. Tùy chọn --port=80
cho phép pod để lộ cổng 80 từ bên trong container.
Pod mới được tạo chạy bên trong cụm minikube
và không thể truy cập từ bên ngoài. Để hiển thị pod và làm cho nó có thể truy cập được, lệnh thứ hai mà bạn đã thực hiện như sau:
kubectl expose pod hello-kube --type=LoadBalancer --port=80
Lệnh expose
có nhiệm vụ tạo ra một dịch vụ LoadBalancer
trong Kubernetes cho phép người dùng truy cập vào các ứng dụng đang chạy bên trong pod.
Cũng giống như lệnh run
, lệnh expose
thực thi lệnh trải qua các bước tương tự bên trong cụm. Nhưng thay vì một pod, kube-api-server
cung cấp các chỉ dẫn cần thiết để tạo một dịch vụ cho thành phần kubelet
trong trường hợp này.
Cú pháp chung cho lệnh expose
như sau:
kubectl expose <resource kind to expose> <resource name> --type=<type of service to create> --port=<port to expose>
Loại đối tượng có thể là bất kỳ loại đối tượng Kubernetes hợp lệ nào. Tên phải khớp với tên đối tượng mà bạn đang cố gắng hiển thị.
Tùy chọn --type
cho biết loại dịch vụ bạn muốn. Có bốn loại dịch vụ khác nhau có sẵn cho mạng nội bộ hoặc bên ngoài.
Cuối cùng, tùy chọn --port
là cổng bạn muốn hiển thị từ container đang chạy.
Khi dịch vụ đã được tạo, phần cuối cùng là truy cập vào ứng dụng đang chạy bên trong nhóm. Để làm điều đó, lệnh bạn đã thực hiện như sau:
minikube service hello-kube
Không giống như những lệnh trước, lệnh cuối cùng này không đi đến kube-api-server
. Thay vào đó, nó giao tiếp với cụm cục bộ bằng cách sử dụng chương trình minikube
. Lệnh service
cho minikube
trả về một URL đầy đủ cho một dịch vụ nhất định.
Khi bạn tạo pod hello-kube
với tùy chọn --port=80
, bạn đã hướng dẫn Kubernetes để pod hiển thị cổng 80 từ bên trong container nhưng nó không thể truy cập được từ bên ngoài cụm.
Sau đó, khi bạn tạo dịch vụ LoadBalancer
với tùy chọn --port=80
, nó đã ánh xạ cổng 80 từ container đó đến một cổng tùy ý trong hệ thống cục bộ để có thể truy cập từ bên ngoài cụm.
Trên hệ thống của tôi, lệnh service
trả về URL 192.168.99.101:30848
cho pod. IP trong URL này thực sự là IP của máy ảo minikube
. Bạn có thể xác minh điều này bằng cách thực hiện lệnh sau:
minikube ip
# 192.168.99.101
Để xác minh rằng cổng 30848
trỏ đến cổng 80 bên trong pod, bạn có thể thực hiện lệnh sau:
kubectl get service hello-kube
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# hello-kube LoadBalancer 10.109.60.75 <pending> 80:30848/TCP 119s
Trên cột PORT(S)
, bạn có thể thấy cổng đó 80
thực sự ánh xạ tới cổng 30484
trên hệ thống cục bộ. Vì vậy, thay vì chạy lệnh service
, bạn có thể chỉ cần kiểm tra IP và cổng, sau đó đưa nó vào trình duyệt của bạn theo cách thủ công để truy cập ứng dụng hello-kube
.
Bây giờ, trạng thái cuối cùng của cụm có thể được hình dung như sau:
Nếu bạn quen thuộc với Docker, thì tầm quan trọng của việc sử dụng một dịch vụ để hiển thị một pod có vẻ hơi quá dài dòng đối với bạn vào lúc này.
Nhưng khi bạn đi vào các ví dụ xử lý nhiều hơn một pod, bạn sẽ bắt đầu đánh giá cao mọi thứ mà Kubernetes cung cấp.
Bây giờ bạn đã biết cách tạo các tài nguyên của Kubernetes như Pod và Service, bạn cũng cần biết cách xóa chúng.
Bạn có thể làm điều đó bằng cách sử dụng lệnh delete
cho kubectl
. Cú pháp chung của lệnh như sau:
kubectl delete <resource type> <resource name>
Để xóa một pod có tên hello-kube
, lệnh sẽ như sau:
kubectl delete pod hello-kube
# pod "hello-kube" deleted
Và để xóa một service có tên hello-kube
, lệnh sẽ như sau:
kubectl delete service hello-kube
# service "hello-kube" deleted
Hoặc nếu bạn đang có tâm trạng phá hoại, bạn có thể xóa tất cả các đối tượng cùng loại trong một lần sử dụng tùy chọn --all
cho lệnh delete
. Cú pháp chung cho tùy chọn như sau:
kubectl delete <object type> --all
Vì vậy, để xóa tất cả các pod và service bạn phải thực thi lệnh kubectl delete pod --all
và kubectl delete service --all
tương ứng.
Trong phần tiếp theo, bạn sẽ tìm hiểu về phương pháp triển khai bằng khai báo trong Kubernetes.
Hướng dẫn này được dịch từ sách Kubernetes Handbook của Farhan Hasin Chowdhury:
Bạn có thể vui lòng tắt trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi duy trì hoạt động của trang web.
Trong phần này, bạn sẽ tìm hiểu cách sử dụng Secret, ConfigMap để lưu trữ thông tin cấu hình, phát hành các bản cập nhật và xử lý sự cố trong Kubernetes.
Trong hướng dẫn này, bạn sẽ tìm hiểu về Ingress Controller và cách sử dụng NGINX Ingress Controller để cấu hình định tuyến trong Kubernetes.
Ở phần 3 này, chúng ta sẽ tìm hiểu cách cung cấp động Persistent Volume, kết nối volume với pod và kết nối các thành phần trong cụm với nhau.
Ở phần 2 này, chúng ta sẽ tìm cách khắc phục những lỗi xảy ra khi triển khai. Chúng ta cũng tìm hiểu thêm về Persistent Volume, Persistent Volume Claim.