Virtualization

Triển khai container trên VPS Linux với Docker Swarm và Podman

Bạn đang chạy vài container Docker trên một VPS và bắt đầu nghĩ đến chuyện mở rộng: thêm node, cân bằng tải, rolling update. Bài toán orchestration container hiện ra. Hai lựa chọn phổ biến nhất cho hạ tầng VPS Linux năm 2026 là Docker Swarm và Podman. Bài này sẽ đi thẳng vào cách triển khai cả hai trên VPS Linux, chỉ ra điểm mạnh yếu của từng loại để bạn chọn đúng công cụ cho quy mô hạ tầng của mình.

Giả định môi trường: bạn có ít nhất 2 VPS chạy Ubuntu 24.04 LTS (hoặc Debian 12), quyền sudo, và đã hiểu cơ bản về container. Mọi lệnh đều chạy được trên cả hai bản phân phối này.

Tóm tắt nhanh

  • Docker Swarm được tích hợp sẵn trong Docker Engine, cú pháp quen thuộc, phù hợp khi bạn đã dùng Docker Compose và cần cluster đơn giản.
  • Podman không có daemon trung tâm, chạy container theo mô hình rootless (không cần quyền root), an toàn hơn trên VPS Linux dùng chung.
  • Podman 6.x (ra mắt giữa 2026) hỗ trợ `podman play kube` để chạy pod theo file Kubernetes, trong khi Swarm dùng stack file riêng.
  • Cả hai đều dùng được trên VPS Linux có cấu hình thấp từ 2GB RAM, nhưng Swarm manager cần ổn định hơn về network.

Vì sao cần orchestration container trên VPS

Chạy một container đơn lẻ bằng `docker run` chỉ giải quyết được một ứng dụng. Khi hệ thống lớn lên, bạn cần nhiều thứ hơn: nhiều bản sao của cùng service để chịu tải, tự động khởi động lại khi container chết, chia sẻ cấu hình giữa các máy, và cập nhật phiên bản mà không làm gián đoạn dịch vụ. Đó là lúc bạn cần một lớp orchestration.

Với hạ tầng từ 2 đến 10 VPS, bạn có hai hướng: Docker Swarm nếu muốn tận dụng hệ sinh thái Docker sẵn có, hoặc Podman khi ưu tiên bảo mật, không muốn một daemon chạy với quyền root trên toàn hệ thống. Kubernetes (kể cả bản nhẹ k3s) là lựa chọn mạnh hơn nhưng thường quá sức cho đội ngũ nhỏ vận hành website hoặc API nội bộ trên thuê VPS Linux.

Docker Swarm: cluster tích hợp sẵn trong Docker Engine

Docker Swarm không phải sản phẩm riêng biệt, nó là chế độ hoạt động của Docker Engine. Nếu bạn đã quen với `docker compose`, việc chuyển sang Swarm gần như không có rào cản: file cấu hình tương tự, chỉ khác vài key và cách deploy.

Bước 1 - Cài đặt Docker Engine và khởi tạo Swarm

Cài Docker Engine trên cả 2 VPS bằng script chính thức (chạy với quyền root):

curl -fsSL https://get.docker.com | sh
systemctl enable --now docker

Trên node đầu tiên (sẽ là Swarm manager), chạy lệnh khởi tạo cluster:

docker swarm init --advertise-addr <IP_VPS_1>

Thay `` bằng địa chỉ IPv4 riêng của VPS. Lệnh này trả về một chuỗi `docker swarm join --token ...`, bạn copy lại để dùng ở bước sau.

Kiểm tra trạng thái cluster bằng lệnh:

docker node ls

Output mong đợi: node đầu tiên hiển thị với trạng thái `Ready` và vai trò `Leader`.

Bước 2 - Thêm worker node vào cluster

Trên VPS thứ hai, chạy lệnh join đã copy ở trên:

docker swarm join --token <TOKEN> <IP_VPS_1>:2377

Lệnh này kết nối VPS thứ hai vào cluster qua port 2377 (dành riêng cho quản lý Swarm). Lưu ý mở port này trên firewall của cả hai máy, cùng với port 7946 (giao tiếp giữa các node) và port 4789 (VXLAN cho mạng overlay). Nếu dùng ufw trên Ubuntu:

ufw allow 2377/tcp
ufw allow 7946/tcp
ufw allow 7946/udp
ufw allow 4789/udp

Bước 3 - Deploy stack bằng file Compose

Tạo file `stack.yml` mô tả service web đơn giản chạy Nginx:

version: "3.8"
services:
  web:
    image: nginx:1.27-alpine
    ports:
      - "80:80"
    deploy:
      replicas: 2
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure

Deploy stack lên Swarm bằng lệnh:

docker stack deploy -c stack.yml webserver

Stack có tên `webserver`, Swarm sẽ tự động tạo 2 bản replica của service `web` và phân bố trên các node khả dụng. Kiểm tra service và các replica:

docker service ls
docker service ps webserver_web

Podman: container không cần daemon, chạy rootless

Podman nổi bật ở điểm kiến trúc: không có daemon trung tâm. Mỗi container là một tiến trình con do systemd hoặc chính bạn quản lý, và có thể chạy hoàn toàn không cần quyền root (rootless). Điều này giảm diện tích tấn công trên VPS, đặc biệt quan trọng khi bạn chạy container từ image không rõ nguồn gốc.

Bước 1 - Cài đặt Podman 6.x trên Ubuntu 24.04

Ubuntu 24.04 có sẵn Podman trong kho lưu trữ, nhưng phiên bản có thể chưa phải mới nhất. Cài trực tiếp:

apt update
apt install podman podman-compose -y

Kiểm tra phiên bản để chắc chắn dùng đúng bản 6.x (ra mắt tháng 6/2026):

podman --version

Kết quả mong đợi có dạng `podman version 6.1.0` hoặc mới hơn.

Bước 2 - Chạy container rootless và tự động khởi động cùng systemd

Chạy container Nginx với user thường (không cần sudo):

podman run -d --name web -p 8080:80 nginx:1.27-alpine

Lệnh này ánh xạ port 8080 trên VPS vào port 80 trong container. Container rootless chỉ bind được port trên 1024, đó là lý do dùng 8080 thay vì 80.

Để container tự khởi động khi VPS reboot, dùng tính năng generate systemd unit:

systemctl --user enable --now container-web.service
loginctl enable-linger $USER

Lệnh `podman generate systemd --new --name web` tạo ra file service, sau đó bạn enable theo user. `loginctl enable-linger` giữ cho tiến trình user chạy ngay cả khi không có phiên đăng nhập nào mở.

Bước 3 - Chạy nhiều container với Podman Compose

Podman tương thích với file docker-compose qua lệnh `podman-compose`. Tạo file `docker-compose.yml` cho ứng dụng web + database:

services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - db-data:/var/lib/postgresql/data
  web:
    image: nginx:1.27-alpine
    ports:
      - "8080:80"
    depends_on:
      - db
volumes:
  db-data:

Chạy toàn bộ stack bằng lệnh:

podman-compose up -d

Podman sẽ tạo một pod (nhóm container chia sẻ network namespace) chứa cả hai container và quản lý volume `db-data`. Kiểm tra pod và container:

podman ps
podman pod ls

Bước 4 - Dùng podman play kube cho file Kubernetes

Điểm khác biệt lớn của Podman 6.x là hỗ trợ file Kubernetes gốc. Bạn có thể viết file pod YAML theo chuẩn Kubernetes rồi chạy trực tiếp bằng Podman, không cần cluster Kubernetes:

podman play kube pod.yaml

File `pod.yaml` mô tả pod với 2 container dùng chung localhost network. Đây là hướng đi được cộng đồng đánh giá cao vì tính di động: file cấu hình viết một lần, chạy được cả trên Kubernetes thật lẫn Podman đơn lẻ trên VPS WordPress hoặc VPS thường.

So sánh Docker Swarm và Podman để chọn đúng cho hạ tầng của bạn

Tiêu chíDocker SwarmPodman
Kiến trúcDaemon trung tâm chạy rootKhông daemon, rootless
Khởi tạo cluster`docker swarm init` + join tokenPodman pod đơn lẻ, không có cluster mode tích hợp
Cân bằng tải nội bộCó, tích hợp sẵn trong SwarmKhông có, cần reverse proxy riêng
Rolling updateCó qua `docker service update`Thủ công, hoặc qua systemd unit
Tương thích KubernetesKhông trực tiếp`podman play kube` chạy file K8s
Bảo mật mặc địnhContainer chạy root trong daemonRootless, user namespace riêng
Độ phức tạp vận hànhThấp, quen thuộc với devTrung bình, cần hiểu systemd user

Nhìn vào bảng trên, quyết định khá rõ ràng. Nếu bạn vận hành website hoặc API cần chịu tải, tự động scale và rolling update giữa nhiều VPS, Docker Swarm là lựa chọn gọn nhẹ, không cần học thêm công cụ mới. Nếu bạn chạy các container nhạy cảm, cần cô lập user hoặc muốn file cấu hình tương thích Kubernetes cho tương lai, Podman đáng để đầu tư thời gian.

Xử lý lỗi thường gặp khi triển khai

Bất kể chọn hướng nào, bạn sẽ gặp vài lỗi điển hình. Dưới đây là cách xử lý nhanh.

Lỗi 1: Node không join được Swarm cluster. Kiểm tra firewall đã mở port 2377, 7946 và 4789 chưa, đồng thời xác nhận token còn hạn bằng lệnh trên manager:

docker swarm join-token worker

Lệnh này in lại token mới nếu token cũ hết hạn.

Lỗi 2: Container rootless Podman không khởi động lại sau reboot. Kiểm tra linger đã bật chưa:

loginctl show-user $USER | grep Linger

Output mong đợi là `Linger=yes`. Nếu là `no`, chạy lại `loginctl enable-linger $USER`.

Lỗi 3: Volume database bị mất khi dùng podman-compose. Kiểm tra volume còn tồn tại không và đúng tên không:

podman volume ls

Nếu volume biến mất, có thể bạn đã chạy `podman-compose down -v` (flag `-v` xóa cả volume). Để an toàn, luôn backup dữ liệu database trước khi chạy lệnh down. Bạn có thể tham khảo thêm bài quản lý Docker volume và backup dữ liệu container để xây dựng quy trình backup đúng cách.

Câu hỏi thường gặp

Nên dùng Docker Swarm hay Podman cho VPS cá nhân?

Với một hoặc hai VPS chạy ứng dụng cá nhân, Podman rootless an toàn hơn và không tốn tài nguyên cho daemon Docker. Nhưng nếu bạn đã quen `docker compose` và muốn cluster đơn giản để chịu tải, Docker Swarm vẫn là đường đi nhanh nhất.

Podman có tương thích hoàn toàn với Dockerfile không?

Có. Podman dùng cùng chuẩn OCI image và có lệnh `podman build` đọc được Dockerfile thông thường. Hầu hết image trên Docker Hub chạy tốt trên Podman, chỉ khác vài chi tiết nhỏ về network và quyền user namespace.

Docker Swarm có còn được phát triển trong năm 2026 không?

Có. Docker vẫn tích hợp Swarm trong Docker Engine và dùng nó cho giải pháp nội bộ. Tuy nhiên, Docker ưu tiên phát triển cho Kubernetes và các công cụ cloud-native hơn, nên Swarm ít nhận tính năng mới nhưng vẫn ổn định cho hạ tầng vừa và nhỏ.

VPS 2GB RAM có chạy nổi Docker Swarm không?

Chạy được nếu bạn dùng image nhẹ như Alpine và giới hạn số replica. Một Swarm manager với 1-2 service nhỏ tốn khoảng 300-500MB RAM. Với 2GB, bạn nên dùng thêm swap và hạn chế chạy node worker riêng trên cùng VPS. Đọc thêm cách tối ưu container trên VPS 2GB RAM để có thêm kỹ thuật giảm tải.

Bài viết liên quan

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.