Zero-Downtime CI/CD với AWS AutoScaling Instance Refresh: Hướng dẫn thực chiến Chuyên mục Devops 2025-09-16 0 Lượt xem 0 Lượt thích 0 Bình luận
Bạn đã bao giờ lo lắng về việc trang web của mình bị gián đoạn mỗi khi triển khai phiên bản mới? Trong thế giới phát triển phần mềm, việc đảm bảo ứng dụng luôn chạy mượt mà ngay cả trong quá trình cập nhật là một yêu cầu then chốt. Bài viết này sẽ hướng dẫn bạn một phương pháp triển khai đơn giản, hiệu quả và không gián đoạn (zero-downtime) bằng cách sử dụng AWS Auto Scaling Instance Refresh.
Phương pháp này cực kỳ phù hợp cho các đội ngũ nhỏ, các startup, hoặc các dự án không muốn tốn thời gian và chi phí cho các hệ thống CI/CD phức tạp.
1. Hiểu về kiến trúc
Trước khi đi sâu vào chi tiết, hãy cùng nhau hình dung quy trình triển khai:
-
Developer đẩy code lên Git.
-
GitHub Actions nhận sự kiện
push
và kích hoạt pipeline. -
Pipeline ra lệnh cho AWS Auto Scaling Group thực hiện
Instance Refresh
. -
Auto Scaling Group bắt đầu tạo các instance mới.
-
Khi khởi động, các instance mới sẽ chạy User Data script.
-
User Data script tự động
git pull
phiên bản code mới nhất, cài đặt và khởi động ứng dụng. -
Khi instance mới sẵn sàng, nó sẽ tiếp nhận traffic và instance cũ sẽ được gỡ bỏ.
Tất cả quá trình này diễn ra một cách tự động, đảm bảo ứng dụng của bạn không bị gián đoạn.
2. Các thành phần chính cần thiết
Để xây dựng hệ thống này, bạn cần chuẩn bị các thành phần sau:
-
Launch Template: Đây là bản thiết kế của EC2 instance, định nghĩa hệ điều hành, cấu hình, và quan trọng nhất là script
User Data
để tự động triển khai code. -
Auto Scaling Group (ASG): ASG quản lý vòng đời của các EC2 instance. Nó sẽ tự động tạo hoặc xóa các instance để đảm bảo số lượng theo yêu cầu.
-
Instance Refresh: Đây là cơ chế của ASG, cho phép bạn thực hiện cập nhật theo kiểu "rolling update" trên toàn bộ các instance.
-
User Data: Một đoạn script (bash) được chạy tự động ngay khi EC2 instance khởi động. Script này sẽ lo việc tải code, cài đặt và khởi động ứng dụng.
-
GitHub Actions: Chúng ta sẽ sử dụng GitHub Actions để tự động kích hoạt quá trình
Instance Refresh
mỗi khi có code mới được đẩy lên.
3. Hướng dẫn thiết lập chi tiết
Bước 1: Tạo Launch Template và User Data
User Data là trái tim của hệ thống này. Nó chịu trách nhiệm lấy code mới nhất và khởi động ứng dụng. Dưới đây là một ví dụ script User Data
cho ứng dụng Node.js:
#!/bin/bash
set -euo pipefail
# Ghi lại toàn bộ log vào file
exec > /var/log/user-data.log 2>&1
export HOME=/root
echo "=== User Data Script Started at $(date) ==="
# Cài đặt AWS CLI cho Ubuntu để tải file từ S3
echo "Installing AWS CLI"
apt-get update -y
apt-get install -y awscli
# Truy cập thư mục ứng dụng
echo "Changing to /var/www/liveapp_performer_web"
cd /var/www/liveapp_performer_web
# Tải file .env từ S3 (đảm bảo an toàn)
echo "Downloading .env file from S3"
aws s3 cp s3://liveapp-configs/prod/performer-pc/.env .env --region ap-northeast-1
chmod 644 .env && chown root:root .env
# Quy trình Git
echo "Stashing local changes"
git stash
echo "Fetching all branches from remote"
git fetch origin
echo "Checking out production branch"
git checkout -B production origin/production
echo "Pulling latest code from production branch"
git pull origin production
# Build và deploy ứng dụng
echo "Installing npm dependencies"
npm install
echo "Building application"
npm run build
echo "Starting/Restarting PM2 application"
pm2 reload nextjs-app || pm2 start npm --name "nextjs-app" -- start
echo "=== SUCCESS: Deployment finished successfully ==="
Lưu ý: Script này giả định bạn đã có PM2 để quản lý tiến trình ứng dụng. Ngoài ra, bạn cũng cần một IAM Role để EC2 instance có quyền truy cập vào S3 để tải file cấu hình.
Bước 2: Thiết lập IAM Role cho EC2
Để EC2 instance có thể tải file từ S3, bạn cần cấp quyền cho nó thông qua một IAM Role.
bash
# Tạo IAM role
aws iam create-role \
--role-name liveapp-prod-performer-pc-s3-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# Attach S3 policy
aws iam put-role-policy \
--role-name liveapp-prod-performer-pc-s3-role \
--policy-name S3ConfigAccess \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::liveapp-configs",
"arn:aws:s3:::liveapp-configs/*"
]
}]
}'
# Tạo instance profile
aws iam create-instance-profile \
--instance-profile-name liveapp-prod-performer-pc-s3-profile
aws iam add-role-to-instance-profile \
--role-name liveapp-prod-performer-pc-s3-role \
--instance-profile-name liveapp-prod-performer-pc-s3-profile
Bạn sẽ gán Instance Profile này vào Launch Template của mình.
Bước 3: Cấu hình Auto Scaling Group (ASG)
Cấu hình ASG là một bước quan trọng để đảm bảo quá trình triển khai diễn ra không gián đoạn.
-
Min Size: 1
-
Max Size: 3 (Quan trọng! Giá trị này phải lớn hơn
Min Size
để ASG có thể tạo thêm instance mới trong quá trìnhInstance Refresh
). -
Desired Capacity: 1
-
Health Check Type: ELB (Application Load Balancer)
-
Health Check Grace Period: 300s (thời gian chờ để instance khởi động và vượt qua health check).
Bước 4: Xây dựng CI/CD Pipeline với GitHub Actions
Đây là nơi bạn tự động hóa quá trình. Pipeline sẽ được kích hoạt mỗi khi có code mới được đẩy lên branch production
.
Tạo file .github/workflows/deploy.yml
trong repository của bạn:
yaml
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [production]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Start Instance Refresh
run: |
aws autoscaling start-instance-refresh \
--auto-scaling-group-name liveapp-prod-performer-pc-asg \
--preferences '{
"MinHealthyPercentage": 0,
"InstanceWarmup": 300,
"CheckpointPercentages": [100],
"ScaleInProtectedInstances": "Ignore",
"StandbyInstances": "Ignore"
}' \
--region ap-northeast-1
- name: Wait for deployment completion
run: |
echo "Deployment started. Monitor progress at:"
echo "https://console.aws.amazon.com/ec2autoscaling/home?region=ap-northeast-1#/details/liveapp-prod-performer-pc-asg"
Lưu ý về MinHealthyPercentage = 0
: Với Desired Capacity = 1
, việc đặt MinHealthyPercentage
bằng 0 là chiến lược duy nhất để đạt được zero-downtime. ASG sẽ tạo ra một instance mới, đợi nó vượt qua health check của ELB, rồi mới terminate instance cũ. Điều này đảm bảo luôn có ít nhất một instance đang phục vụ traffic.
### Tại sao MinHealthyPercentage = 0?
Với Desired Capacity = 1, đây là cách duy nhất để thực hiện zero-downtime deployment:
bash
# Luồng Surge Replacement
Time 0: [i-old1] serving 100% traffic
Time 1: [i-old1, i-new1] serving traffic (surge to 2 instances)
Time 2: [i-new1] serving 100% traffic (back to desired = 1)
### So sánh với các giá trị khác:
bash
# MinHealthyPercentage: 50 hoặc 100
# Vấn đề: Không thể terminate instance cũ
# Kết quả: Deployment bị stuck
# MinHealthyPercentage: 0
# Giải pháp: Cho phép terminate instance cũ sau khi instance mới healthy
# Kết quả: Zero-downtime deployment thành công
4. Quản lý và khắc phục sự cố
-
Theo dõi quá trình triển khai: Bạn có thể theo dõi tiến độ
Instance Refresh
bằng AWS CLI hoặc trên console.-
### 1. Monitor Deployment Progress bash # Theo dõi Instance Refresh aws autoscaling describe-instance-refreshes \ --auto-scaling-group-name liveapp-prod-performer-pc-asg \ --query 'InstanceRefreshes[0].[Status,PercentageComplete,StartTime]' \ --output table # Theo dõi instances aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names liveapp-prod-performer-pc-asg \ --query 'AutoScalingGroups[0].Instances[*].[InstanceId,LifecycleState,HealthStatus]' \ --output table
-
-
Gỡ lỗi: Nếu việc triển khai thất bại, hãy SSH vào instance mới và kiểm tra file log
/var/log/user-data.log
hoặc log của ứng dụng (ví dụ:pm2 logs
).-
bash # SSH vào instance mới ssh -i key.pem ubuntu@<new-instance-ip> # Check User Data logs sudo tail -f /var/log/user-data.log # Check application status pm2 status pm2 logs nextjs-app # Check system resources df -h free -m
-
-
Rollback: Nếu cần quay lại phiên bản cũ, chỉ cần
git revert <commit-hash>
và đẩy lên branchproduction
. GitHub Actions sẽ tự động kích hoạtInstance Refresh
và triển khai phiên bản cũ.-
bash # Method 1: Git revert git revert <commit-hash> git push origin production # GitHub Actions tự động deploy version cũ # Method 2: Manual instance refresh với Launch Template version cũ aws autoscaling start-instance-refresh \ --auto-scaling-group-name liveapp-prod-performer-pc-asg \ --preferences MinHealthyPercentage=0,InstanceWarmup=300
-
5. Ưu và nhược điểm
Ưu điểm:
-
Zero Downtime: Đảm bảo ứng dụng luôn hoạt động.
-
Đơn giản và dễ hiểu: Không cần quá phức tạp như các hệ thống container.
-
Dựa trên Git: Phù hợp với quy trình làm việc của mọi developer.
-
Hiệu quả chi phí: Tận dụng cơ chế có sẵn của AWS, không cần thêm các dịch vụ đắt tiền.
Nhược điểm:
-
Thời gian build: Mỗi instance mới phải build lại từ đầu, có thể tốn thời gian.
-
Phụ thuộc vào mạng: Quá trình
git pull
vànpm install
cần kết nối internet ổn định. -
Giới hạn test: Không có giai đoạn test trước khi deploy trực tiếp vào production như các pipeline phức tạp hơn.
Kết luận
Phương pháp sử dụng AWS Auto Scaling Instance Refresh là một giải pháp CI/CD mạnh mẽ, hiệu quả và cực kỳ phù hợp cho các dự án quy mô nhỏ và vừa. Nó mang lại sự ổn định và tin cậy mà không đòi hỏi nhiều kiến thức chuyên sâu về DevOps.
Nếu bạn đang tìm kiếm một cách để triển khai ứng dụng một cách tự động và không gián đoạn, hãy thử ngay phương pháp này. Chúc bạn thành công!
Bình luận (0)