Quay lại

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    comment-3 Created with Sketch Beta. 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ình Instance 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 branch production. GitHub Actions sẽ tự động kích hoạt Instance 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 pullnpm 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)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Bài viết liên quan

Learning English Everyday