Triển khai ứng dụng Container lên VPS với Kamal 2: Zero-Downtime không còn nỗi lo phức tạp của K8s

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

Gánh nặng từ sự phức tạp của Kubernetes

Kubernetes là một công cụ cực kỳ mạnh mẽ, nhưng đối với hầu hết các ứng dụng quy mô vừa, nó thường trở thành một “hố đen” tiêu tốn thời gian. Bạn sẽ thấy mình dành nhiều giờ đồng hồ để vật lộn với các tệp manifest YAML và ingress controller hơn là viết các tính năng thực tế. Tôi đã chứng kiến nhiều đội ngũ mất tới 20% năng suất phát triển hàng tuần chỉ để duy trì một cụm cluster chạy vỏn vẹn ba hoặc bốn dịch vụ.

Kamal 2 mở ra một hướng đi khác. Được tạo ra bởi 37signals để chuyển Basecamp và HEY rời khỏi đám mây (cloud), nó mang lại sự mượt mà của một PaaS như Heroku lên bất kỳ VPS cơ bản nào. Bạn nhận được mọi lợi ích của container hóa mà không phải trả phí dịch vụ quản lý 500 USD mỗi tháng hoặc bị lệ thuộc vào nhà cung cấp (vendor lock-in). Tôi đã chuyển nhiều khối lượng công việc thực tế (production) sang mô hình này. Độ ổn định rất ấn tượng, và cuối cùng thì hạ tầng cũng thực sự đóng vai trò phụ trợ cho mã nguồn.

Về cơ chế hoạt động, Kamal 2 thực thi các lệnh thông qua SSH. Nó kéo Docker image từ registry của bạn và quản lý một proxy nhẹ để hoán đổi các phiên bản ngay lập tức. Nó không yêu cầu một agent nặng nề nào trên máy chủ của bạn. Nếu bạn có thể SSH vào một máy tính và máy đó đã cài đặt Docker, bạn đã sẵn sàng để triển khai.

Chuẩn bị môi trường

Trước khi đi sâu vào cấu hình, bạn cần một vài công cụ trên máy cục bộ của mình. Khác với các hệ thống điều phối truyền thống, Kamal chạy cục bộ hoặc trong CI/CD runner và đẩy các chỉ thị đến máy chủ từ xa.

1. Yêu cầu trên máy cục bộ

Kamal được phân phối dưới dạng một Ruby gem. Bạn không cần phải là một chuyên gia Ruby để sử dụng nó, nhưng bạn cần môi trường runtime Ruby trên máy của mình.

# Cài đặt Kamal 2
gem install kamal

# Kiểm tra phiên bản
kamal version

2. Chuẩn bị máy chủ

Bắt đầu với một VPS sạch—Ubuntu 24.04 là lựa chọn hoàn hảo. Kamal có thể tự cài đặt Docker cho bạn nếu máy chưa có, nhưng trước tiên bạn phải thiết lập truy cập bằng SSH key. Tránh sử dụng xác thực bằng mật khẩu vì nó sẽ làm gián đoạn luồng tự động hóa. Để có trải nghiệm tốt nhất, hãy đảm bảo người dùng SSH của bạn có quyền sudo không cần mật khẩu:

# Chạy lệnh này trên VPS của bạn
echo "youruser ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/youruser

3. Container Registry

Kamal xây dựng image của bạn cục bộ và đẩy nó lên một registry như Docker Hub, GitHub Packages hoặc AWS ECR. Sau đó, VPS của bạn sẽ kéo image từ đó về. Hãy đảm bảo bạn đã chuẩn bị sẵn thông tin đăng nhập registry trước khi bước sang bước tiếp theo.

Cấu hình triển khai

Mọi thứ Kamal thực hiện đều được điều khiển bởi một tệp duy nhất: config/deploy.yml. Tệp này định nghĩa các máy chủ, registry và các biến môi trường của bạn. Chạy lệnh kamal init trong thư mục gốc của dự án để tạo một mẫu khởi đầu.

Dưới đây là một cấu hình sẵn sàng cho môi trường production của một ứng dụng web tiêu chuẩn:

service: my-awesome-app
image: username/my-awesome-app

servers:
  web:
    - 123.45.67.89

registry:
  username: my-docker-user
  password:
    - KAMAL_REGISTRY_PASSWORD # Được lấy từ biến môi trường (ENV) cục bộ

env:
  secret:
    - RAILS_MASTER_KEY
    - DATABASE_URL
  clear:
    - PORT: 3000

proxy:
  ssl: true
  host: app.example.com
  # Kamal 2 sử dụng proxy tích hợp để chuyển đổi zero-downtime

asset_path: /assets

branches:
  master: main

Sức mạnh của Kamal Proxy

Kamal 2 giới thiệu kamal-proxy, thay thế cho việc tích hợp Traefik cũ. Proxy mới này được xây dựng chuyên biệt cho quy trình “khởi động và chuyển đổi” (boot-and-switch). Nó chờ đợi container mới của bạn vượt qua các bài kiểm tra sức khỏe (health check) trước khi điều hướng lưu lượng truy cập. Khi phiên bản mới được xác nhận là ổn định, nó sẽ tắt phiên bản cũ. Quy trình này đảm bảo người dùng của bạn không bao giờ gặp lỗi 502 trong quá trình phát hành.

Quản lý bí mật (Secrets) an toàn

Hãy nhìn vào phần secret trong tệp YAML ở trên. Kamal sẽ tìm kiếm tệp .env trên máy cục bộ của bạn để điền các giá trị này trong khi triển khai. Sau đó, nó sẽ chèn chúng một cách an toàn vào container từ xa. Đừng bao giờ ghi trực tiếp (hardcode) mật khẩu vào các tệp cấu hình của bạn.

Quy trình triển khai

Việc thiết lập ban đầu là một lệnh chạy một lần duy nhất. Kamal kết nối với VPS của bạn, cài đặt Docker, cấu hình registry và thiết lập proxy. Quá trình này thường mất khoảng 2 đến 3 phút, tùy thuộc vào tốc độ internet của máy chủ.

kamal setup

Lệnh duy nhất này thay thế cho cả một buổi chiều viết script bash thủ công trước đây. Khi quá trình thiết lập hoàn tất thành công, bạn đã sẵn sàng cho lần phát hành đầu tiên.

Triển khai các bản cập nhật

Đẩy mã nguồn mới lên rất đơn giản. Mọi bản cập nhật sau đó đều được xử lý bằng một lệnh:

kamal deploy

Lệnh này kích hoạt một chuỗi các bước tự động. Đầu tiên, nó xây dựng Docker image. Sau đó, nó đẩy image lên registry và kéo nó về máy chủ production. Hệ thống khởi động container mới trên một cổng (port) mới và chờ phản hồi 200 OK từ health check. Nếu kiểm tra thất bại, Kamal sẽ dừng ngay lập tức. Tấm lưới an toàn này giữ cho phiên bản cũ của bạn tiếp tục chạy, ngăn chặn một bản phát hành lỗi làm sập trang web của bạn.

Giám sát và Hoàn tác khẩn cấp (Rollback)

Phát hành mã nguồn chỉ là một nửa công việc. Bạn cần biết điều gì đang xảy ra bên trong các container của mình mà không cần phải đi tìm mã số PID. Kamal cung cấp các lệnh tiện ích thay thế cho việc kiểm tra Docker thủ công tẻ nhạt.

Kiểm tra trạng thái và nhật ký (Logs)

Để xem phiên bản nào đang hoạt động trên tất cả các máy chủ, hãy chạy:

kamal details

Nếu bạn cần chẩn đoán một sự cố đang diễn ra, bạn có thể xem luồng log từ mọi máy chủ cùng một lúc:

kamal app logs -f

Hoàn tác trong 10 giây

Lỗi là điều khó tránh khỏi. Nếu một bản phát hành lỗi bị lọt qua, bạn không muốn phải chờ đợi quy trình CI/CD xây dựng lại từ đầu. Kamal giữ lại các image cũ trên máy chủ để có thể khôi phục ngay lập tức.

kamal rollback [VERSION]

Lệnh này yêu cầu proxy trỏ ngược lại image container trước đó ngay lập tức. Đây là cách nhanh nhất để phục hồi từ một lỗi production nghiêm trọng.

Tăng tốc độ với Remote Builder

Xây dựng Docker image trên máy tính xách tay cá nhân có thể chậm, đặc biệt là khi Wi-Fi yếu. Bạn có thể chỉ định một VPS mạnh mẽ làm “Remote Builder” trong cấu hình của mình. Điều này có thể cắt giảm thời gian triển khai từ vài phút xuống còn dưới 60 giây.

builder:
  remote: ssh://builder-user@builder-ip

Loại bỏ gánh nặng phức tạp

Kamal 2 lấp đầy khoảng trống giữa việc quản lý VPS thủ công lộn xộn và sự quá tải của Kubernetes. Nó coi các máy chủ của bạn như những thứ có thể thay thế nhưng vẫn giữ cho bạn quyền kiểm soát logic. Bằng cách loại bỏ các chi phí vận hành của K8s, bạn có thể tập trung vào việc phát hành các tính năng thay vì quản lý hạ tầng. Đối với hầu hết các dự án đang phát triển, chuyển sang Kamal 2 là bước nâng cấp DevOps hiệu quả nhất mà bạn có thể thực hiện.

Share: