Nhận ra lúc 2 giờ sáng: Tại sao ảo hóa là chưa đủ
Lúc đó là 2 giờ sáng, và môi trường production của tôi đang gặp lỗi. Một lỗi race condition ở lớp lưu trữ phân tán khiến các node bị rớt, nhưng tôi không thể tái hiện nó trên máy trạm của mình. Các hệ thống ảo hóa cao cấp thường che lấp độ trễ phần cứng và những bất thường về mạng vốn là tác nhân gây ra các lỗi này. Tôi nhận ra rằng để thực sự làm chủ tính sẵn sàng cao (high availability), tôi cần phần cứng vật lý. Tôi cần một cụm máy chủ mà tôi có thể rút dây điện trực tiếp để quan sát cách phần mềm xoay sở.
Việc quản lý một cụm đa node sẽ thay đổi góc nhìn của bạn về mạng và giới hạn tài nguyên. Bạn không cần một dàn máy chủ doanh nghiệp đồ sộ để học những bài học này. Tôi đã xây dựng một cụm Raspberry Pi 4 node với giá 144 USD, và nó dạy tôi về Kubernetes nhiều hơn bất kỳ chứng chỉ đám mây nào. Đây là cách bạn có thể tự làm.
Danh sách linh kiện dưới 150 USD
Để tiết kiệm ngân sách, tôi chọn Raspberry Pi Zero 2 W. Nó tích hợp bộ vi xử lý lõi tứ trong một kích thước tí hon. Dù 512MB RAM là khá ít ỏi, nhưng nó buộc bạn phải học cách tối ưu hóa tài nguyên. Đây là bảng phân bổ chi phí:
- 4x Raspberry Pi Zero 2 W: ~$60 ($15 mỗi chiếc theo giá niêm yết)
- 4x Thẻ nhớ MicroSD 32GB (SanDisk Ultra): ~$24
- 1x Trạm sạc USB 6 cổng (60W): ~$25
- 4x Cáp Micro-USB (Loại ngắn 15cm): ~$10
- 1x USB 2.0 Hub + Ổ Flash 128GB: ~$25
- Tổng cộng: ~$144
Lưu ý: Thiết lập này sử dụng WiFi 2.4GHz để tiết kiệm chi phí cho các switch và PoE hat đắt tiền. Nó hoàn hảo để học kiến trúc K8s, dù bạn sẽ muốn đặt các node gần router để giảm thiểu mất gói tin.
Cài đặt: Từ phần cứng vật lý đến K3s
Hiệu suất là yếu tố then chốt khi làm việc với RAM hạn chế. Tôi sử dụng Raspberry Pi OS Lite (64-bit) để giữ mức chiếm dụng tài nguyên nền dưới 50MB. Hãy tránh xa các môi trường desktop bằng mọi giá.
1. Chuẩn bị hệ điều hành
Flash thẻ SD của bạn bằng Raspberry Pi Imager. Sử dụng menu cấu hình sẵn để đặt hostname duy nhất (từ node-01 đến node-04) và bật SSH. Trước khi khởi động, bạn phải bật cgroups để K3s quản lý tài nguyên chính xác. Thêm nội dung sau vào cuối file /boot/cmdline.txt:
cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1
Khởi động các node và gán IP tĩnh trong router của bạn. IP tĩnh giúp cụm không bị sụp đổ khi hợp đồng thuê DHCP hết hạn trong quá trình triển khai.
2. Cài đặt K3s trên Control Plane (node-01)
K3s là một bản phân phối Kubernetes nhẹ được thiết kế cho edge computing. Tôi tắt Traefik và metrics server để tiết kiệm khoảng 80MB RAM cho các ứng dụng của mình.
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable traefik --disable metrics-server --write-kubeconfig-mode 644" sh -s -
Sau khi script chạy xong, hãy lấy node token. Chuỗi ký tự này cho phép các worker node gia nhập cụm của bạn một cách an toàn:
sudo cat /var/lib/rancher/k3s/server/node-token
3. Kết nối các Worker Node
Chạy script cài đặt trên ba node còn lại. Trỏ chúng về IP của control plane và sử dụng token bạn vừa lưu:
curl -sfL https://get.k3s.io | K3S_URL=https://<MASTER_IP>:6443 K3S_TOKEN=<YOUR_TOKEN> sh -
Chạy kubectl get nodes từ node-01. Nếu cả bốn node đều báo trạng thái “Ready”, cụm của bạn đã chính thức hoạt động.
Cấu hình: Giải quyết bài toán lưu trữ dùng chung
Các pod trong Kubernetes có tính chất tạm thời. Nếu một pod khởi động lại trên một node khác, dữ liệu của nó sẽ biến mất trừ khi bạn có lưu trữ dùng chung. Vì chúng ta không có SAN chuyên dụng, chúng ta sẽ biến ổ USB 128GB trên node-01 thành một NFS server.
1. Thiết lập NFS Server
Cắm ổ USB vào node-01 và chia sẻ nó ra mạng:
sudo apt-get install nfs-kernel-server -y
sudo mkdir -p /mnt/cluster_storage
# Thêm vào /etc/exports
/mnt/cluster_storage *(rw,sync,no_subtree_check,no_root_squash)
Áp dụng cấu hình bằng lệnh sudo exportfs -ra.
2. Tự động hóa lưu trữ với Provisioner
Việc tạo Persistent Volumes thủ công rất tẻ nhạt. Thay vào đó, hãy sử dụng **NFS Subdir External Provisioner**. Nó sẽ tự động tạo các thư mục trên ổ USB bất khi nào ứng dụng yêu cầu lưu trữ. Cài đặt thông qua Helm:
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--set nfs.server=<MASTER_IP> \
--set nfs.path=/mnt/cluster_storage \
--set storageClass.name=nfs-client \
--set storageClass.defaultClass=true
Giờ đây, bất kỳ deployment nào yêu cầu PersistentVolumeClaim sẽ nhận được không gian lưu trữ trên ổ USB đó ngay lập tức. Điều này giúp việc chạy database hoặc các ứng dụng có trạng thái (stateful) trở nên dễ dàng hơn nhiều.
Kiểm tra: Duy trì hệ thống hoạt động
Một cụm máy chủ chỉ hữu ích nếu nó duy trì được hoạt động. Với chỉ 512MB RAM, bạn phải giám sát cực kỳ chặt chẽ. Tôi tránh các công cụ nặng nề như Prometheus và thay vào đó sử dụng k9s cho giao diện điều khiển trên terminal.
1. Triển khai workload thử nghiệm
Kiểm tra bộ điều phối (scheduler) và lưu trữ bằng cách triển khai một instance Nginx với 3 replica. Sử dụng file test-nginx.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- name: storage
mountPath: /usr/share/nginx/html
volumes:
- name: storage
persistentVolumeClaim:
claimName: nginx-pvc
Chạy kubectl apply -f test-nginx.yaml. Nếu trạng thái chuyển sang Running, logic lưu trữ của bạn đã ổn định.
2. Xử lý sự cố trong thời gian thực
Khi các node gặp lỗi—và chắc chắn chúng sẽ lỗi—hãy chạy kubectl get events -w. Trên những chiếc Pi nhỏ bé này, lỗi phổ biến nhất là OOMKilled (hết bộ nhớ). Nếu một node bắt đầu tình trạng “flapping” (chuyển đổi liên tục giữa Ready và NotReady), hãy kiểm tra tải ngay lập tức:
kubectl top nodes
Nếu node-03 đang quá tải, hãy thêm một Taint để ngăn các pod nặng chạy trên đó. Lab vật lý này mang lại trải nghiệm rất trực quan. Bạn có thể thấy đèn LED trên Pi nhấp nháy liên tục ngay trước khi kết nối SSH bị ngắt. Đó là một cách tuyệt vời để học về giới hạn thực tế của hệ thống.
Lời kết
Cụm máy chủ này không nhằm mục đích cung cấp sức mạnh xử lý thuần túy; nó là một sân chơi nơi sai lầm không tốn gì ngoài thời gian. Bạn sẽ học được cách tối ưu hóa container image và debug các vấn đề về mạng vốn không hề tồn tại trong môi trường ảo. Với chưa đầy 150 USD, bạn đã xây dựng được một phiên bản thu nhỏ của hạ tầng vận hành thế giới web hiện đại. Đừng ngần ngại thử nghiệm và làm hỏng thứ gì đó.

