Hướng dẫn triển khai KubeSphere trên VPS để quản lý K3s trực quan (Update v4.x)

Tác giả: Trần Thảo 29 tháng 07, 2026

Bạn đang vật lộn với hàng tá cửa sổ terminal, mỏi mắt dò từng dòng log bằng lệnh kubectl mỗi khi hệ thống có biến? Ở giai đoạn đầu, quản lý K3s qua dòng lệnh có vẻ rất chuyên nghiệp và kiểm soát tốt. Nhưng khi dự án bắt đầu scale, số lượng Pod nhân lên hàng chục, việc bắt cả team developer viết cấu hình YAML thủ công hay mò mẫm debug không khác gì đi trong sương mù. Triển khai KubeSphere trên VPS chính là lối thoát hoàn hảo, mang lại một giao diện đồ họa (GUI) đỉnh cao để giám sát vi dịch vụ mà không nuốt trọn RAM của máy chủ. Nhưng làm sao để cài đặt kiến trúc LuBan v4.x mới nhất, thiết lập Cgroups chuẩn xác để tránh treo máy, và thay thế Ingress bằng Gateway API hiện đại? Hãy cùng bóc tách toàn bộ quy trình kỹ thuật ngay sau đây.

Ám ảnh dòng lệnh: Khi kubectl trở thành nút thắt vận hành

Kubernetes nói chung và K3s nói riêng là những hệ thống điều phối container tuyệt vời, nhưng công cụ CLI mặc định của chúng lại sở hữu một đường cong học tập cực kỳ dốc. Nếu tiếp tục duy trì việc quản trị 100% qua dòng lệnh, đội ngũ của bạn sẽ sớm phải đối mặt với những rào cản chí mạng:

  • Quá tải cấu hình (YAML Fatigue): Developer chuyên code backend/frontend thường không rành về hạ tầng cloud-native. Việc bắt họ phải viết đúng định dạng các tệp YAML dài dằng dặc (từ Deployment, Service, ConfigMap đến Secret) chỉ để deploy một ứng dụng đơn giản làm tăng thời gian onboarding lên gấp nhiều lần. Chỉ cần sai một dấu cách (space), toàn bộ cụm có thể từ chối thực thi.
  • Quản lý tài nguyên thiếu kiểm soát: Không có Dashboard trực quan để theo dõi mức độ tiêu thụ CPU/RAM realtime, việc thiết lập các thông số Requests và Limits trở thành một trò chơi đoán mò. Hậu quả là hệ thống liên tục rơi vào tình trạng Pod bị tắt đột ngột do cạn kiệt bộ nhớ (OOMKilled) hoặc khiến VPS bị thắt cổ chai (bottleneck), từ đó dẫn đến tình trạng VPS bị treo cứng và phải tìm cách khắc phục.
  • Debug chậm chạp và rời rạc: Việc gõ kubectl logs -f hay kubectl exec thủ công qua lại giữa hàng chục container trong một hệ thống microservices là một cực hình thực sự, nhất là khi bạn đang chịu áp lực phải xử lý sự cố trên môi trường Production.
  • Quản lý phân quyền (RBAC) rủi ro cao: Thiết lập hệ thống đa người dùng, cô lập môi trường Dev/Staging/Prod bằng YAML thuần chứa đầy rủi ro bảo mật. Một cấu hình ServiceAccount sơ hở cũng có thể mở đường cho lỗ hổng leo thang đặc quyền (privilege escalation), cho phép developer can thiệp sâu vào các node vật lý.
So sánh hiệu quả quản trị cụm K3s bằng dòng lệnh CLI và giao diện KubeSphere GUI trên VPS

KubeSphere GUI giải phóng DevOps khỏi rào cản gõ lệnh YAML thủ công và tình trạng quản lý tài nguyên thiếu kiểm soát.

Tại sao kiến trúc v4.x biến KubeSphere trên VPS thành giải pháp tối ưu cho K3s?

Nhiều kỹ sư từng thử dùng KubeSphere ở phiên bản v3.x và phải từ bỏ vì nó quá nặng nề. Ở các bản cũ, mã nguồn của tất cả các thành phần bị gắn chặt (coupled) vào lõi. Chỉ tính riêng module DevOps (dựa trên Jenkins) đã ngốn tới 8.6 GB RAM, hệ thống Logging chiếm gần 3 GB RAM. Việc cài đặt bộ máy này lên một VPS chạy K3s chẳng khác nào ép một chiếc xe máy cõng thùng container 40 feet!

Tuy nhiên, sự ra mắt của KubeSphere v4.x (tên mã LuBan) đã thay đổi hoàn toàn cuộc chơi với kiến trúc vi nhân (microkernel) siêu tối ưu:

  • Tách rời KubeSphere Core và Extensions: Kiến trúc v4.x chia hệ thống làm hai phần hoàn toàn tách biệt. Phần lõi (ks-core) được gọt giũa cực kỳ mỏng nhẹ, chỉ đảm nhiệm giao diện web console, hệ thống xác thực người dùng (IAM) và API Gateway. Toàn bộ các tính năng tiêu tốn tài nguyên khác (DevOps, Service Mesh, App Store, Logging) được tách thành các Extensions độc lập.
  • Cơ chế Plug-and-play (Cắm và chạy): Bạn có thể cài đặt, cập nhật, bật hoặc tắt nóng (hot-pluggable) các extension này ngay trên giao diện web mà không cần khởi động lại cụm hay can thiệp vào lõi hệ thống. Bạn cần tính năng nào thì bật tính năng đó, không dùng thì tắt đi để giải phóng RAM.
  • Sự cộng hưởng hoàn hảo với K3s: K3s vốn đã sinh ra để tối ưu tài nguyên (gom các tiến trình vào một file nhị phân duy nhất, dùng cơ sở dữ liệu SQLite siêu nhẹ thay cho etcd). Khi kết hợp K3s nền tảng với ks-core siêu nhẹ, bạn có ngay một hệ sinh thái quản trị hiện đại, giao diện đẹp mắt ngay trên một VPS giới hạn tài nguyên.
Sơ đồ kiến trúc vi nhân LuBan v4.x của KubeSphere tách rời Core và Extensions giúp tối ưu RAM VPS

Kiến trúc Cắm và chạy (plug-and-play) của KubeSphere v4.x giúp giải phóng tối đa RAM cho các máy chủ ảo (VPS) tài nguyên thấp.

Khảo sát tài nguyên VPS và chuẩn bị môi trường K3s tối ưu

Trước khi gõ bất kỳ dòng lệnh cài đặt nào, chúng ta cần đối mặt với bài toán cấu hình phần cứng. Đừng tin hoàn toàn vào mức Tối thiểu lý thuyết (2 vCPU, 4GB RAM) ghi trong các tài liệu marketing, vì nó chỉ đủ để Pod hệ thống khởi động chứ không gánh nổi các tác vụ điều phối thực tế.

Cấu hình VPS tối thiểu thực tế (Practical Minimum):

  • CPU: 4 vCPUs (Kiến trúc x86_64 hoặc ARM64).
  • RAM: 8 GB.
  • Storage: 40 GB SSD (Bắt buộc dùng ổ SSD NVMe hoặc SSD Enterprise vì các thành phần như SQLite, Prometheus có tần suất I/O ghi đĩa rất cao. Ổ HDD sẽ làm sập cụm ngay lập tức do nghẽn IOPS).

Cấu hình Cgroups K3s để chống Soft Lockup (Rất Quan Trọng):

Đây là kinh nghiệm thực tế thường bị bỏ qua. Nếu bạn chỉ khai báo system-reserved mà thiếu các cờ định danh Cgroups, tiến trình Kubelet của K3s sẽ hoàn toàn ngó lơ các giới hạn này. Hậu quả là khi KubeSphere cần bung RAM để xử lý log, nó sẽ hút sạch RAM của hệ điều hành, khiến VPS bị treo cứng (soft lockup) và bạn thậm chí không thể SSH vào máy chủ.

Hãy can thiệp ngay vào file /etc/rancher/k3s/config.yaml để ép Kubelet tôn trọng phân vùng tài nguyên:

kubelet-arg:
  - "enforce-node-allocatable=pods,system-reserved,kube-reserved"
  - "system-reserved-cgroup=/system.slice"
  - "kube-reserved-cgroup=/kubepods.slice"
  - "system-reserved=cpu=200m,memory=500Mi"
  - "kube-reserved=cpu=200m,memory=500Mi"
  - "eviction-hard=memory.available<200Mi,nodefs.available<10%"

Lưu ý: Thiết lập này tạo ra một ranh giới bảo mật, ép hệ thống phải luôn chừa lại 1GB RAM (500Mi cho OS + 500Mi cho K3s engine) không cho bất kỳ Pod nào chạm tới.

Đồng thời, đảm bảo cụm của bạn đang có sẵn một StorageClass. K3s mặc định đi kèm local-path-provisioner. Hãy kiểm tra bằng lệnh:

kubectl get sc

Nếu thấy dòng local-path (default), bạn đã sẵn sàng đi tiếp.

Biểu đồ phân bổ tài nguyên RAM Cgroups trên VPS chạy K3s chống lỗi Soft Lockup

Cấu hình enforce-node-allocatable tạo ranh giới bảo mật Cgroups, ngăn KubeSphere hút cạn RAM của hệ điều hành.

KubeKey vs Helm: Đâu là công cụ tối thượng cho bạn?

Trong hệ sinh thái KubeSphere, có hai công cụ triển khai phổ biến nhất. Việc chọn sai công cụ có thể khiến bạn đi đường vòng mất rất nhiều thời gian:

  • KubeKey (kk): Đây là công cụ triển khai chính thức do cộng đồng KubeSphere phát triển. KubeKey cực kỳ mạnh mẽ nếu bạn muốn dựng một cụm từ con số 0 (cài OS xong là chạy kk để nó tự động cài Kubernetes và KubeSphere cùng lúc) hoặc dùng cho môi trường ngoại tuyến (Air-gapped) không có Internet. KubeKey tự động hóa việc cấu hình HA, cài đặt etcd, và thiết lập mạng nội bộ.
  • Helm 3: Đối với trường hợp của chúng ta, khi bạn đã hoàn tất việc cài đặt cụm K3s trên VPS Linux và hệ thống đang hoạt động trơn tru, việc ứng dụng Helm vào quản lý gói Kubernetes lại là sự lựa chọn hoàn hảo và gọn nhẹ hơn. Thay vì dùng KubeKey có thể làm ghi đè các cấu hình K3s hiện tại, Helm đóng vai trò như một trình quản lý gói (package manager), nhẹ nhàng thả lõi ks-core lên trên nền K3s mà không làm gián đoạn bất kỳ workload nào đang chạy.

Trong bài viết này, do cụm K3s đã được chuẩn bị sẵn, chúng ta sẽ thực chiến bằng vũ khí Helm.

Thực chiến 4 bước setup KubeSphere trên VPS bằng Helm

Dưới đây là quy trình 4 bước cài đặt an toàn, có tính đến các rào cản mạng thường gặp đối với server đặt tại Việt Nam.

Bước 1: Khởi tạo Helm và cấu hình KUBECONFIG

Nếu VPS của bạn chưa cài Helm, hãy dùng script cài đặt chính thức:

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

Xác minh phiên bản Helm (Yêu cầu v3.x trở lên):

helm version

Tiếp theo, xuất biến môi trường để Helm và kubectl biết đường dẫn giao tiếp với K3s:

export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

Bước 2: Deploy ks-core và xử lý Rate-Limit Docker Hub

Thêm kho lưu trữ (repository) chính thức của dự án:

helm repo add kubesphere https://charts.kubesphere.io/main

Cập nhật danh sách các package từ repository:

helm repo update

Khắc phục rào cản Rate-Limit: Một khó khăn lớn khi deploy các hệ thống cloud-native là Docker Hub thường xuyên giới hạn số lượt kéo ảnh (pull image) đối với các dải IP của VPS đám mây (rate-limit). Nếu mạng chập chờn, Pod sẽ mãi kẹt ở trạng thái ImagePullBackOff.

Nếu gặp tình trạng này, bạn nên cấu hình K3s/containerd sử dụng các Mirror Registry (như của Huawei Cloud, Alibaba). Tuy nhiên, trong điều kiện mạng tiêu chuẩn, hãy chạy lệnh Helm sau để cài đặt lõi hệ thống:

helm upgrade --install ks-core kubesphere/ks-core \
  --namespace kubesphere-system \
  --create-namespace \
  --set ha.enabled=false \
  --set redisHA.enabled=false \
  --set common.core.console.enableMultiLogin=false \
  --debug --wait

Giải thích tham số:

  • ha.enabled=falseredisHA.enabled=false: Tắt chế độ High Availability (chạy nhiều bản sao dự phòng). Rất cần thiết cho VPS đơn (single-node) để tiết kiệm RAM.
  • enableMultiLogin=false: Chặn đăng nhập một tài khoản trên nhiều trình duyệt cùng lúc để siết chặt an ninh nội bộ.

Dùng lệnh theo dõi tiến trình:

kubectl get pods -n kubesphere-system -w

Bạn sẽ cần đợi khoảng 3-5 phút cho đến khi tất cả các Pod (apiserver, console, controller-manager) chuyển sang trạng thái Running.

Bước 3: Mở port 30880 và xử lý Firewall/Security Group

Theo mặc định, KubeSphere mở giao diện quản trị Web Console qua giao thức NodePort ở cổng 30880. Bạn cần tiến hành mở port tường lửa trên VPS, nhưng tuyệt đối không mở tự do ra toàn bộ Internet.

  • Nếu VPS của bạn sử dụng Ubuntu/Debian, hãy tham khảo cách cấu hình UFW để làm chủ tường lửa VPS: Hãy cấu hình danh sách trắng (white-list) chỉ cho phép IP tĩnh của văn phòng bạn (ví dụ IP là 114.114.114.114) truy cập:
    sudo ufw allow from 114.114.114.114 to any port 30880 proto tcp comment 'KubeSphere Admin Access'
  • Đối với các hệ thống CentOS/Rocky Linux, hãy tìm hiểu sự khác biệt giữa Firewalld và các công cụ khác trước khi áp dụng lệnh sau:
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="114.114.114.114" port protocol="tcp" port="30880" accept'
    sudo firewall-cmd --reload
  • Môi trường Cloud (AWS, Azure, DigitalOcean): Ngoài tường lửa hệ điều hành, bạn bắt buộc phải đăng nhập vào web quản trị của nhà cung cấp, tìm phần Security Group / Firewall Rules và thêm quy tắc Inbound cho port 30880. Nhớ cho phép cả dải port nội bộ 30000-32767 thông nhau nếu cụm có nhiều worker nodes.

Bước 4: Đăng nhập Console và kích hoạt License Community (miễn phí)

Mở trình duyệt và truy cập: http://<IP_VPS_CỦA_BẠN>:30880.

  • Tài khoản mặc định: admin
  • Mật khẩu mặc định: P@88w0rd (Hệ thống sẽ ép buộc đổi mật khẩu mạnh ngay lập tức).

Điểm mới cực kỳ quan trọng ở bản v4.x: Để tải và cài đặt các Extensions (như Monitoring, DevOps), KubeSphere yêu cầu bạn phải kích hoạt giấy phép Community Edition (hoàn toàn miễn phí trọn đời).

  1. Tại giao diện chính, click vào Component Dock (icon 9 ô vuông góc trên bên trái).
  2. Chọn Platform Settings, đi đến mục Licenses.
  3. Tại đây, hệ thống sẽ hiển thị mã Cluster ID của bạn. Hãy copy đoạn mã này.
  4. Truy cập URL đăng ký chính thức: kubesphere.co/apply-license/. Điền email và dán Cluster ID vào.
  5. Kiểm tra email (bao gồm cả thư mục Spam), copy đoạn mã License được cấp phát.
  6. Quay lại màn hình KubeSphere, chọn Add License và dán mã vào. Trạng thái chuyển sang màu xanh lá Authorized là thành công!
Sơ đồ quy trình 4 bước cài đặt KubeSphere ks-core lên cụm K3s có sẵn bằng Helm

Quy trình 4 bước chuẩn hóa deploy KubeSphere Core không làm gián đoạn workload hiện tại.

Trải nghiệm sức mạnh GUI: Bảng đối chiếu thao tác KubeSphere vs CLI

Giao diện KubeSphere giải phóng DevOps khỏi việc phải ghi nhớ cú pháp. Cùng xem khả năng của GUI thay thế dòng lệnh như thế nào:

Tác vụ quản trị Thao tác thủ công với các lệnh Linux cơ bản (kubectl) Tối ưu hóa một chạm trên GUI KubeSphere
Kiểm tra trạng thái toàn bộ Pod kubectl get pods -n <namespace> -o wide Truy cập Application Workloads, chọn Pods. Bảng dữ liệu hiển thị rõ IP, Node gánh tải, số lần restart và phần trăm CPU/RAM đang tiêu thụ thời gian thực.
Đọc Log để Debug lỗi kubectl logs -f <pod-name> -c <container-name> --tail=100 Bấm vào chi tiết Pod, chuyển sang tab Logs. Có ngay thanh tìm kiếm thông minh, lọc sự kiện theo mốc thời gian và nút Export để tải file log về máy tính cá nhân.
Truy cập Terminal bên trong Container kubectl exec -it <pod-name> -- /bin/sh Bấm nút Access Container Terminal. Một shell giả lập mở ngay trên trình duyệt. Đặc biệt: Hỗ trợ tính năng Upload/Download file kéo thả trực tiếp, không cần lệnh kubectl cp.
Scale số lượng Pod dự phòng kubectl scale deployment <name> --replicas=5 Tìm Deployment tương ứng, bấm nút (+) tăng số lượng Replicas lên 5 rồi nhấn Save. KubeSphere tự động sinh YAML ngầm định.
Tạo Secret lưu mật khẩu DB kubectl create secret generic db-pass --from-literal=password=123 Vào mục Configuration, chọn Secrets, điền form theo dạng Key-Value chuẩn bảo mật, dữ liệu tự động mã hóa Base64 ngay trên UI.

Bắt bệnh 3 lỗi phổ biến khi deploy và cách fix

Thực tế vận hành K3s không bao giờ trải đầy hoa hồng. Khi đưa hệ thống lên Production, bạn chắc chắn sẽ đụng phải 3 lỗi phổ biến này. Dưới đây là cách phân tích nguyên nhân và xử lý chuyên nghiệp:

Lỗi ImagePullBackOff (hoặc ErrImagePull)

Lỗi này cho biết Kubelet không thể kéo được image của ứng dụng về node để chạy.

  • Cách Debug: Chạy kubectl describe pod <tên-pod> -n <namespace>, cuộn xuống mục Events ở dưới cùng.
  • Phân tích nguyên nhân:
    • Sai tên/tag: Ví dụ gõ nhầm phiên bản nginx:1.141 thay vì nginx:1.14.1.
    • Lỗi 403 Forbidden: Image lưu trong Private Registry nội bộ nhưng bạn quên đính kèm imagePullSecret trong file YAML.
    • Giới hạn băng thông (Rate-limit): IP của VPS đã kéo quá nhiều lần từ Docker Hub.
  • Cách fix: Kiểm tra lại chính tả cấu hình. Khai báo Secret cho Private Registry. Nếu bị rate-limit, hãy thiết lập Registry Mirror cho containerd.

Lỗi CrashLoopBackOff (đi kèm trạng thái OOMKilled)

Container vừa báo Running được vài giây đã ngừng hoạt động, lặp đi lặp lại liên tục.

  • Cách Debug: Lệnh lấy log thông thường sẽ trả về rỗng vì container đã mất kết nối. Bạn phải dùng tham số --previous:
    kubectl logs <tên-pod> -n <namespace> --previous
  • Phân tích nguyên nhân: Đây là hệ quả của việc thiếu kiểm soát tài nguyên. Ứng dụng của bạn (ví dụ Spring Boot Java) cần 1GB RAM khởi tạo Heap, nhưng bạn lại cài đặt giới hạn bộ nhớ cứng (limits.memory) ở mức 512MB. Lập tức, kernel Linux gửi tín hiệu Exit Code 137, buộc chấm dứt tiến trình do vi phạm vượt quá giới hạn tài nguyên (Out Of Memory).
  • Cách fix: Vào giao diện KubeSphere, sửa lại cấu hình Deployment, nâng thông số Limit lên cao hơn. Đồng thời, cấu hình lại biến môi trường bên trong container (ví dụ -Xmx512m) để ứng dụng tự giới hạn nhu cầu của chính nó.

Lỗi kẹt Port mạng (“Port is in use”)

Pod kẹt mãi ở trạng thái Pending hoặc ContainerCreating.

  • Cách Debug: Đọc Events sẽ thấy thông báo: Port [X] is already in use hoặc bind: address already in use.
  • Phân tích nguyên nhân:
    • Bạn cấu hình tham số hostPort trong YAML, ép Pod phải gắn chặt vào một cổng mạng vật lý của VPS. Khi scale lên 2 Pod trên cùng 1 node, Pod thứ hai không thể lấy được port đó.
    • Một tiến trình hệ điều hành (ví dụ Nginx cài sẵn bằng apt) đang chạy ngầm và chiếm cổng 80/443.
  • Cách fix: Tuyệt đối hạn chế dùng hostPort. Mọi giao tiếp bên ngoài nên qua dịch vụ NodePort, hoặc chuẩn mực nhất là qua hệ thống định tuyến mạng Ingress/Gateway. Dùng lệnh netstat -tulpn trên VPS để tìm PID của tiến trình chạy ngầm và ngắt kết nối nó nếu cần.

Lời khuyên bảo mật và Routing cho Production (Gateway API)

Khi cụm K3s quản lý bởi KubeSphere đã sẵn sàng đón luồng traffic thật (Production), việc phơi bày các cổng mặc định ra ngoài là hành động thiếu an toàn. Dưới đây là các chuẩn mực DevOps bạn phải thiết lập:

  • Chuyển đổi từ Ingress sang Gateway API: Các tài liệu cũ thường khuyên cài Nginx Ingress Controller. Tuy nhiên, tiêu chuẩn mạng tương lai của Kubernetes đã dịch chuyển sang Gateway API (cung cấp khả năng định tuyến đa giao thức, phân quyền gắt gao theo Role, và chia sẻ hạ tầng linh hoạt hơn Ingress). KubeSphere v4.x hỗ trợ cực mạnh Gateway API thông qua các extension (như KubeSphere Gateway/Higress). Hãy triển khai Gateway API, mở duy nhất port 80/443 ra ngoài Internet, gắn chứng chỉ SSL (Let’s Encrypt), và thiết lập Proxy chuyển tiếp an toàn (Reverse Proxy) vào port 30880 nội bộ của KubeSphere.
  • Vô hiệu hóa Terminal của các Node Control Plane: Tính năng Web Terminal rất tiện lợi, nhưng nó cũng là một rủi ro an ninh nếu tài khoản quản trị viên bị lộ. Trong KubeSphere v4.x, hãy vào phần cài đặt nâng cao để tắt quyền truy cập Terminal vào các Node vật lý (Control Plane/Worker). Ngay cả khi quyền truy cập KubeSphere bị xâm phạm, hệ điều hành của VPS vẫn được đảm bảo an toàn.
  • Cô lập mạng đa người dùng (Network Policies): Tận dụng UI của KubeSphere để bật Network Isolation. Đảm bảo rằng các Pod nằm ở không gian dự án (Namespace) Development bị chặn liên lạc hoàn toàn với cơ sở dữ liệu nằm ở không gian Production.
Mô hình định tuyến mạng bảo mật KubeSphere qua Gateway API chặn truy cập trực tiếp NodePort 30880

Sử dụng Gateway API bọc SSL/TLS giúp che giấu NodePort nội bộ, chặn đứng các cuộc kiểm tra cổng trái phép.

Kết luận

Đưa KubeSphere trên VPS vào vận hành cùng K3s là một bước tiến mang tính chiến lược, biến hạ tầng phức tạp trở thành hệ sinh thái điều phối ứng dụng trực quan, an toàn và tối ưu tài nguyên.

Tài liệu tham khảo