Kubernetes (k8s) là một nền tảng mã nguồn mở mạnh mẽ, được thiết kế để tự động hóa việc triển khai, mở rộng và quản lý các ứng dụng được đóng gói trong container. Nó xem các container như các khối xây dựng cơ bản và cung cấp một cơ chế mạnh mẽ để quản lý chúng ở quy mô lớn.
Lịch Sử Phát Triển Các Mô Hình Triển Khai Ứng Dụng
Việc triển khai ứng dụng đã trải qua các giai đoạn tiến hóa đáng kể:
-
Thời kỳ Triển khai Truyền thống
Ban đầu, các ứng dụng được cài đặt trực tiếp lên phần cứng vật lý. Việc thiếu cơ chế phân bổ tài nguyên rõ ràng dẫn đến tình trạng một ứng dụng chiếm dụng phần lớn tài nguyên, ảnh hưởng đến các ứng dụng khác. Giải pháp là đặt mỗi ứng dụng lên một máy vật lý riêng biệt, nhưng điều này không hiệu quả về tài nguyên và tốn kém chi phí quản lý.
-
Thời kỳ Triển khai Ảo hóa
Ảo hóa ra đời giải quyết vấn đề trên bằng cách cho phép chạy nhiều máy ảo (VM) trên một máy vật lý. Mỗi VM hoạt động như một máy tính độc lập với hệ điều hành riêng, cung cấp sự cô lập và cải thiện hiệu suất sử dụng tài nguyên. Tuy nhiên, mỗi VM vẫn đòi hỏi tài nguyên đáng kể cho hệ điều hành.
-
Thời kỳ Triển khai Container hóa
Container hóa là một bước tiến vượt bậc, giảm bớt lớp cô lập bằng cách chia sẻ hệ điều hành của máy chủ. Điều này tạo ra các container nhẹ hơn, khởi động nhanh hơn và tiêu tốn ít tài nguyên hơn so với VM. Mỗi container có hệ thống tệp, CPU, bộ nhớ và không gian tiến trình riêng biệt, nhưng chúng chia sẻ nhân hệ điều hành.
Các lợi ích chính của container hóa bao gồm:
- Tạo và triển khai ứng dụng nhanh chóng.
- Hỗ trợ CI/CD hiệu quả với chu kỳ build, deploy và rollback nhanh.
- Phân tách rõ ràng giữa phát triển và vận hành.
- Khả năng giám sát sâu sắc cả ở cấp độ hệ điều hành và ứng dụng.
- Tính nhất quán của môi trường giữa các giai đoạn phát triển, kiểm thử và sản xuất.
- Khả năng di chuyển linh hoạt trên nhiều nhà cung cấp đám mây và hệ điều hành.
- Quản lý tập trung vào ứng dụng, thay vì tập trung vào máy ảo.
- Thúc đẩy kiến trúc microservices, với các dịch vụ nhỏ, độc lập, dễ dàng quản lý và mở rộng.
- Cô lập tài nguyên để đảm bảo hiệu suất ổn định.
- Tối ưu hóa việc sử dụng tài nguyên, cho phép mật độ triển khai cao.
Các Tính Năng Cốt Lõi Của Kubernetes
Kubernetes đóng vai trò như một hệ thống điều phối container (container orchestrator), giúp quản lý các ứng dụng container hóa ở quy mô sản xuất. Các chức năng chính bao gồm:
-
Phát hiện Dịch vụ và Cân bằng Tải
Kubernetes cung cấp các cơ chế để các container có thể tìm thấy nhau thông qua tên DNS hoặc địa chỉ IP, đồng thời phân phối lưu lượng truy cập đến các container trong một nhóm.
-
Quản lý Lưu trữ
Tự động gắn kết và quản lý các hệ thống lưu trữ khác nhau, từ lưu trữ cục bộ, NFS đến các dịch vụ lưu trữ đám mây.
-
Triển khai và Khôi phục Tự động
Khai báo trạng thái mong muốn của ứng dụng, và Kubernetes sẽ tự động điều chỉnh để đạt được trạng thái đó, bao gồm cả việc triển khai từng bước và khả năng khôi phục về trạng thái trước đó.
-
Tự phục hồi (Self-healing)
Kubernetes có khả năng tự động khởi động lại các container bị lỗi, thay thế các container không đáp ứng kiểm tra sức khỏe và đảm bảo người dùng chỉ truy cập vào các container sẵn sàng.
-
Quản lý Bí mật và Cấu hình
Lưu trữ và quản lý an toàn các thông tin nhạy cảm như mật khẩu, token và khóa. Cho phép cập nhật cấu hình và bí mật mà không cần xây dựng lại image hoặc lộ thông tin không an toàn.
Kiến Trúc Tổng Quan Của Kubernetes
Kubernetes tuân theo kiến trúc Master-Worker, trong đó:
- Master Node: Chịu trách nhiệm quản lý toàn bộ cluster, bao gồm lập lịch, theo dõi trạng thái, và điều phối các hoạt động.
- Worker Node (Node): Là các máy chủ (VM hoặc vật lý) thực thi các tác vụ của người dùng. Mỗi Worker Node có một Kubelet để giao tiếp với Master và quản lý các container trên node đó.
Các thành phần chính trên Master Node bao gồm:
- kube-apiserver: Điểm truy cập duy nhất cho mọi yêu cầu đến cluster, xử lý và định tuyến các yêu cầu tới các thành phần khác.
- Scheduler: Lập lịch và quyết định Worker Node nào sẽ chạy các Pod mới dựa trên các yêu cầu về tài nguyên và chính sách.
- Controller Manager: Quản lý các bộ điều khiển khác nhau (Node Controller, Replication Controller, v.v.) để đảm bảo trạng thái hiện tại của cluster khớp với trạng thái mong muốn.
- etcd: Một kho lưu trữ key-value nhất quán và phân tán, lưu trữ toàn bộ trạng thái và cấu hình của cluster. Chỉ có API Server mới có quyền ghi trực tiếp vào etcd.
Các thành phần chính trên Worker Node bao gồm:
- Kubelet: Đảm bảo các container đang chạy trong Pod trên node của nó. Nó giao tiếp với API Server để nhận chỉ thị và báo cáo trạng thái.
- Kube-Proxy: Quản lý các quy tắc mạng trên node, cho phép giao tiếp mạng với các Pod từ bên trong và bên ngoài cluster.
- Container Runtime: Phần mềm chịu trách nhiệm chạy các container, ví dụ như Docker Engine, containerd, hoặc CRI-O.
Thiết Lập Môi Trường Kubernetes (Ví Dụ Cơ Bản)
Việc thiết lập một cluster Kubernetes đòi hỏi một số bước chuẩn bị trên các máy chủ sẽ tham gia vào cluster.
Yêu cầu Hệ thống
- Hệ điều hành: Ví dụ như RHEL 9, Ubuntu, CentOS.
- Cấu hình phần cứng: Đảm bảo đủ tài nguyên CPU, RAM, và dung lượng lưu trữ.
Các Bước Chuẩn Bị Chung
- Vô hiệu hóa SELinux và Firewall trên tất cả các node.
- Đồng bộ hóa thời gian và cấu hình DNS trên tất cả các node.
- Cài đặt một Container Runtime (ví dụ: Docker CE, containerd).
- Vô hiệu hóa Swap và cấu hình `fstab` tương ứng.
- Cấu hình tên miền và địa chỉ IP cho từng node (Master, Worker, Registry).
- Cài đặt các công cụ cần thiết như
kubeadm,kubelet, vàkubectl. - Cấu hình Docker để sử dụng registry riêng (nếu có).
- Tải và đẩy các image cần thiết lên registry riêng.
Khởi tạo Cluster
Sử dụng kubeadm init trên Master Node để khởi tạo cluster. Lệnh này sẽ cấu hình các thành phần của control plane và tạo file cấu hình admin.conf.
kubeadm init --pod-network-cidr=10.244.0.0/16 \
--image-repository registry.example.com/k8s \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
Sau khi khởi tạo, thiết lập biến môi trường KUBECONFIG để kubectl có thể truy cập cluster.
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
Cài đặt Plugin Mạng (CNI)
Để các Pod có thể giao tiếp với nhau, cần cài đặt một plugin Mạng (CNI) như Flannel hoặc Calico. Ví dụ với Flannel:
kubectl apply -f flannel.yml
Bạn cần đảm bảo các image của Flannel đã được tải lên registry riêng và đường dẫn image trong file cấu hình flannel.yml đã được cập nhật.
Mở rộng Cluster (Thêm Worker Node)
Sử dụng lệnh kubeadm join được cung cấp sau khi chạy kubeadm init để thêm các Worker Node vào cluster.
kubeadm join :6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash> --cri-socket=unix:///var/run/cri-dockerd.sock
So Sánh Các Plugin Mạng
| Plugin | Chế độ Mạng | Hiệu suất | Trường hợp Sử dụng |
|---|---|---|---|
| Flannel | VXLAN | 8-10% | Cluster vừa và nhỏ |
| Calico | BGP | 3-5% | Môi trường sản xuất quy mô lớn |
| Cilium | eBPF | 1-3% | Cảnh quan bảo mật Cloud-native |
| Weave | Mesh | 10-15% | Môi trường Hybrid Cloud |
Khái Niệm Pod Trong Kubernetes
Pod là đơn vị trừu tượng nhỏ nhất trong Kubernetes, đại diện cho một nhóm một hoặc nhiều container cùng chia sẻ tài nguyên. Các tài nguyên chia sẻ bao gồm:
- Lưu trữ chung: Được quản lý thông qua Volumes.
- Mạng: Mỗi Pod có một địa chỉ IP duy nhất trong cluster, và các container trong Pod chia sẻ địa chỉ IP này.
- Thông tin cấu hình: Bao gồm phiên bản image, các cổng được expose, v.v.
Ví dụ, một Pod có thể chứa một container ứng dụng chính và một container phụ trợ (sidecar) để ghi log hoặc proxy.
Pod là đơn vị triển khai và quản lý cơ bản. Khi một Pod gặp sự cố hoặc node của nó bị lỗi, Kubernetes sẽ tự động tạo một Pod tương tự trên một node khác.
Mỗi Pod có một container "gốc" gọi là Pause container. Container này đóng vai trò làm nền tảng cho Pod, cung cấp địa chỉ IP và cho phép các container khác trong Pod giao tiếp với nhau.
Định Nghĩa Pod
Một định nghĩa Pod trong YAML thường bao gồm các trường sau:
apiVersion: Phiên bản API của Kubernetes (ví dụ: v1).kind: Loại tài nguyên (Pod).metadata: Siêu dữ liệu như tên, namespace, labels.spec: Định nghĩa chi tiết về các container, volumes, và các cấu hình khác.containers: Danh sách các container trong Pod.name: Tên container.image: Image container cần sử dụng.imagePullPolicy: Chính sách kéo image (Always, IfNotPresent, Never).ports: Các cổng mà container expose.env: Biến môi trường.resources: Cấu hình giới hạn (limits) và yêu cầu (requests) tài nguyên CPU/Memory.volumeMounts: Cấu hình mount volumes vào container.
volumes: Định nghĩa các volumes chia sẻ cho Pod.restartPolicy: Chính sách khởi động lại Pod (Always, Never, OnFailure).nodeSelector: Chỉ định node để chạy Pod dựa trên labels.hostNetwork: Sử dụng network của host hay không.
Ví Dụ Cấu Hình Pod Nginx
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Pod
metadata:
name: nginxpod
namespace: dev
spec:
containers:
- name: nginx-containers
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
resources:
limits:
cpu: "2"
memory: "2Gi"
requests:
cpu: "1"
memory: "10Mi"
Chính Sách Kéo Image (imagePullPolicy)
Always: Luôn luôn kéo image từ remote registry.IfNotPresent: Chỉ kéo image nếu nó chưa có sẵn trên node.Never: Chỉ sử dụng image đã có trên node, không bao giờ kéo từ remote.
Lưu ý: Mặc định là IfNotPresent cho tag phiên bản cụ thể và Always cho tag latest.
Cấu Hình Cổng (ports)
Định nghĩa các cổng mà container lắng nghe. containerPort là cổng bên trong container, hostPort là cổng trên node host (thường không được khuyến khích sử dụng).
Giới Hạn và Yêu Cầu Tài Nguyên (resources)
limits: Đặt giới hạn tối đa về CPU và Memory mà container có thể sử dụng. Nếu vượt quá, container có thể bị kill.
requests: Đặt mức tài nguyên tối thiểu mà container yêu cầu khi khởi động. Nếu không đủ tài nguyên, Pod sẽ không được lên lịch.
Ví dụ, một Pod yêu cầu 100m CPU (0.1 core) và 128Mi Memory.
Khi cấu hình tài nguyên, nếu requests quá cao so với tài nguyên sẵn có của node, Pod sẽ ở trạng thái Pending và kubectl describe pod sẽ hiển thị lý do lỗi lập lịch.