0
0
Lập trình
Thaycacac
Thaycacac thaycacac

Danh Sách Kiểm Tra Triển Khai Không Ngừng Nghỉ với Docker & Nginx

Đăng vào 1 tháng trước

• 8 phút đọc

Giới Thiệu

Triển khai không ngừng nghỉ là một yêu cầu không thể thương lượng đối với các dịch vụ hiện đại. Là một trưởng nhóm DevOps, bạn cần có một quy trình lặp lại giúp giữ cho lưu lượng truy cập không bị gián đoạn trong khi bạn đẩy mã mới, cập nhật cấu hình hoặc thực hiện di cư cơ sở dữ liệu. Danh sách kiểm tra này sẽ hướng dẫn bạn qua quy trình làm việc tập trung vào Docker, tận dụng Nginx như một proxy ngược, các bản phát hành blue-green và công cụ quan sát. Cuối cùng, bạn sẽ có một pipeline CI/CD cụ thể có thể áp dụng vào bất kỳ môi trường Linux nào.


Các Yêu Cầu Cần Thiết

  • Một máy chủ Linux (hoặc VM) với Docker Engine ≥ 20.10 được cài đặt.
  • Kiến thức cơ bản về cú pháp cấu hình Nginx.
  • Quyền truy cập vào một kho Git chứa mã nguồn ứng dụng của bạn.
  • Tùy chọn nhưng được khuyến nghị: một phiên bản PostgreSQL được quản lý cho ví dụ di cư.

Nếu bạn thiếu bất kỳ điều nào trong số này, hãy khởi động một VM đám mây giá rẻ hoặc sử dụng cài đặt Docker Desktop địa phương trước khi tiếp tục.


1️⃣ Xây Dựng Hình Ảnh Docker Có Thể Tái Tạo

Thực Hành Tốt Nhất Với Dockerfile

  • Đặt ảnh nền – sử dụng một thẻ cụ thể, không phải latest.
  • Tận dụng xây dựng đa giai đoạn để giữ cho hình ảnh cuối cùng nhẹ.
  • Khai báo người dùng không phải root để đảm bảo an ninh runtime.
  • Chỉ mở các cổng cần thiết.
dockerfile Copy
# ---- Giai đoạn xây dựng ----
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# ---- Giai đoạn chạy ----
FROM node:18-alpine
WORKDIR /app
# Tạo một người dùng không phải root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production && npm cache clean --force
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]

Xây dựng và gán thẻ cho hình ảnh với một SHA Git ngắn để theo dõi:

bash Copy
export GIT_SHA=$(git rev-parse --short HEAD)
docker build -t myapp:${GIT_SHA} .

Đẩy hình ảnh lên kho của bạn (Docker Hub, ECR, GCR, v.v.):

bash Copy
docker push myregistry.example.com/myapp:${GIT_SHA}

2️⃣ Cấu Hình Nginx Như Một Proxy Ngược

Nginx sẽ đứng trước hai nhóm upstream – greenblue – mỗi nhóm trỏ đến một phiên bản container khác nhau. Proxy sẽ định tuyến lưu lượng đến nhóm hoạt động trong khi nhóm còn lại không hoạt động.

nginx Copy
# /etc/nginx/conf.d/app.conf
upstream green {
    server 127.0.0.1:3001; # Container Docker cho phiên bản green
}

upstream blue {
    server 127.0.0.1:3002; # Container Docker cho phiên bản blue
}

# Ban đầu trỏ đến green
map $http_x_deploy_target $upstream {
    default green;
    "blue" blue;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://$upstream;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Tải lại Nginx sau bất kỳ thay đổi nào:

bash Copy
nginx -s reload

3️⃣ Triển Khai Pipeline Blue-Green

Dưới đây là một workflow GitHub Actions tối thiểu mà:

  1. Xây dựng hình ảnh Docker.
  2. Đẩy nó lên kho.
  3. Triển khai container mới vào upstream không hoạt động.
  4. Chuyển lưu lượng Nginx.
  5. Thực hiện kiểm tra sức khỏe trước khi dọn dẹp phiên bản cũ.
yaml Copy
name: CI/CD Blue-Green Deploy
on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to registry
        uses: docker/login-action@v2
        with:
          registry: myregistry.example.com
          username: ${{ secrets.REGISTRY_USER }}
          password: ${{ secrets.REGISTRY_PASS }}

      - name: Build and push image
        id: build
        run: |
          GIT_SHA=$(git rev-parse --short HEAD)
          docker build -t myregistry.example.com/myapp:${GIT_SHA} .
          docker push myregistry.example.com/myapp:${GIT_SHA}
          echo "image=${GIT_SHA}" >> $GITHUB_OUTPUT

      - name: Deploy to inactive slot
        env:
          IMAGE=${{ steps.build.outputs.image }}
        run: |
          # Xác định slot hiện tại thông qua tiêu đề Nginx (đơn giản)
          CURRENT=$(curl -s -D - http://app.example.com | grep X-Deploy-Target | cut -d: -f2 | tr -d ' ')
          if [ "$CURRENT" = "green" ]; then TARGET=blue; PORT=3002; else TARGET=green; PORT=3001; fi
          docker run -d --name ${TARGET}_app -p ${PORT}:3000 myregistry.example.com/myapp:${IMAGE}
          # Thông báo Nginx chuyển đổi
          curl -X POST -H "X-Deploy-Target: ${TARGET}" http://localhost/switch

      - name: Health check new slot
        run: |
          # Vòng lặp curl đơn giản, hủy bỏ sau 30s nếu không khỏe
          for i in {1..10}; do
            STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:${PORT})
            if [ "$STATUS" = "200" ]; then exit 0; fi
            sleep 3
          done
          exit 1

      - name: Clean up old container
        run: |
          if [ "$TARGET" = "blue" ]; then docker rm -f green_app; else docker rm -f blue_app; fi

Điểm mấu chốt:

  • Workflow không bao giờ ngừng phục vụ lưu lượng.
  • Việc chuyển đổi được thực hiện thông qua một endpoint HTTP nhỏ (/switch) cập nhật bản đồ $upstream.
  • Kiểm tra sức khỏe bảo vệ chống lại các phiên bản xấu.

4️⃣ Di Cư Cơ Sở Dữ Liệu Không Ngừng Nghỉ

Ngay cả khi việc hoán đổi container diễn ra hoàn hảo, một thay đổi schema vẫn có thể gây ra thời gian chết. Hãy làm theo các mẫu sau:

  • Di cư chỉ thêm – giới thiệu các cột mới với giá trị mặc định, tránh việc xóa bất kỳ thứ gì.
  • Điền vào nền – sử dụng một worker để điền các cột mới sau khi mã được phát trực tiếp.
  • Cờ tính năng – bảo vệ các truy vấn mới bằng một công tắc cho đến khi di cư được xác minh.

Một ví dụ CLI đơn giản sử dụng node-pg-migrate:

bash Copy
npx node-pg-migrate up --config ./migrate-config.js

migrate-config.js có thể được kiểm soát phiên bản và chạy bên trong cùng một hình ảnh Docker, đảm bảo rằng di cư diễn ra trong cùng một môi trường với ứng dụng.


5️⃣ Quan Sát & Ghi Nhận

Chiến lược không ngừng nghỉ chỉ hiệu quả khi bạn có độ hiển thị tốt trong quá trình chuyển.

  • Metrics – Prometheus thu thập /metrics từ mỗi container. Gán thẻ metrics với deployment=green|blue.
  • Logs – Chuyển tiếp stdout/stderr của Docker đến Loki qua driver ghi log Docker.
  • Tracing – Kích hoạt OpenTelemetry trong ứng dụng Node.js của bạn và gửi các spans đến Jaeger.
  • Cảnh báo – Thiết lập cảnh báo Grafana trên các đợt tăng tỷ lệ lỗi trong quá trình triển khai.

Ví dụ cấu hình thu thập Prometheus:

yaml Copy
scrape_configs:
  - job_name: 'myapp'
    static_configs:
      - targets: ['127.0.0.1:3001', '127.0.0.1:3002']

📋 Danh Sách Kiểm Tra Cuối Cùng

✅ Mục Mô tả
Dockerfile Đặt hình ảnh nền, đa giai đoạn, người dùng không phải root, mở cổng chính xác
Gán Thẻ Hình Ảnh Sử dụng SHA Git hoặc phiên bản ngữ nghĩa để theo dõi
Cấu Hình Nginx Hai block upstream, bản đồ tiêu đề đến $upstream, tải lại sau khi chuyển
Pipeline CI/CD Xây dựng → Đẩy → Triển khai vào slot không hoạt động → Kiểm tra sức khỏe → Chuyển đổi → Dọn dẹp
Di Cư Cơ Sở Dữ Liệu Chỉ thêm, điền vào, có cờ bảo vệ, chạy bên trong container
Quan Sát Metrics Prometheus, logs Loki, tracing OpenTelemetry, cảnh báo Grafana
Kế Hoạch Rollback Giữ container trước đó sống ít nhất 5 phút; docker rm -f chỉ sau khi xác nhận tính ổn định

Kiểm tra danh sách này trước mỗi lần phát hành sẽ giảm đáng kể khả năng xảy ra sự cố.


Kết Luận

Triển khai không ngừng nghỉ là sự kết hợp giữa hạ tầng có kỷ luật, pipeline tự động và giám sát nghiêm ngặt. Bằng cách coi hình ảnh Docker như các sản phẩm không thay đổi, sử dụng Nginx để định tuyến lưu lượng giữa các slot blue và green, và nhúng kiểm tra sức khỏe vào quy trình CI/CD của bạn, bạn có thể gửi thay đổi nhiều lần trong một ngày mà không bao giờ làm gián đoạn người dùng. Nếu bạn cần giúp đỡ trong việc triển khai điều này, đội ngũ tại Ramer Labs có thể hỗ trợ bạn.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào