0
0
Lập trình
TT

Checklist Hoàn Hảo cho Triển Khai Zero-Downtime với Docker & Nginx

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

• 6 phút đọc

Giới thiệu

Triển khai zero-downtime là một yêu cầu không thể thiếu cho các dịch vụ hiện đại. Là một trưởng nhóm DevOps, bạn cần một quy trình lặp lại, ít rủi ro cho phép bạn đẩy mã mới mà không làm gián đoạn người dùng. Bảng kiểm tra này sẽ hướng dẫn bạn qua quy trình dựa trên Docker, hỗ trợ bởi Nginx, bao gồm mọi thứ từ cấu hình CI/CD đến kiểm tra sức khỏe, chuyển đổi lưu lượng và khả năng quan sát.


Lập Kế Hoạch Quy Trình Triển Khai

Trước khi viết một dòng Dockerfile nào, hãy phác thảo các giai đoạn mà mã của bạn sẽ đi qua. Một pipeline rõ ràng giảm thiểu các bước thủ công và làm cho việc quay lại trở nên dễ dàng.

Chọn công cụ CI/CD phù hợp

  • GitHub Actions – tích hợp sẵn, chi phí thấp, tuyệt vời cho mã nguồn mở.
  • GitLab CI – có sẵn registry container, dễ quản lý biến.
  • CircleCI – công việc song song nhanh, caching lớp Docker tuyệt vời.
  • Jenkins – tùy chỉnh cao nếu bạn đã có thiết lập tại chỗ.

Chọn một công cụ tích hợp với hệ thống kiểm soát phiên bản của bạn và có thể đẩy hình ảnh lên một registry mà các máy chủ sản xuất có thể kéo xuống.


Đóng Gói Ứng Dụng

Một hình ảnh Docker được thiết kế tốt là nền tảng cho việc triển khai suôn sẻ.

Thực Hành Tốt Nhất cho Dockerfile

Copy
# Sử dụng một hình ảnh nền nhẹ chính thức
FROM node:20-alpine AS builder
WORKDIR /app

# Chỉ cài đặt các phụ thuộc sản xuất trước để tận dụng caching
COPY package*.json ./
RUN npm ci --only=production

# Sao chép mã nguồn và xây dựng
COPY . .
RUN npm run build

# Giai đoạn runtime – hình ảnh nhỏ nhất có thể
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]

Những điểm cần nhớ:

  • Xây dựng đa giai đoạn giúp hình ảnh cuối cùng nhẹ nhàng.
  • Tách biệt cài đặt phụ thuộc khỏi sao chép mã nguồn để tận dụng cache của Docker.
  • Chỉ mở cổng cần thiết và tránh chạy dưới quyền root.

Nginx như một Reverse Proxy cho Zero-Downtime

Nginx ngồi trước các container của bạn, xử lý việc kết thúc TLS, cân bằng tải và chuyển đổi một cách nhịp nhàng.

Cấu hình Upstream

Copy
# /etc/nginx/conf.d/upstream.conf
upstream app_backend {
    # Chiến lược "least_conn" phân phối lưu lượng đều.
    least_conn;
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name example.com;

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

Khi bạn khởi động một container mới trên một cổng mới (ví dụ: 8083), chỉ cần thêm nó vào khối upstream và tải lại Nginx (nginx -s reload). Nginx sẽ bắt đầu định tuyến các kết nối mới đến phiên bản mới trong khi các kết nối hiện có hoàn tất trên phiên bản cũ.


Chiến Lược Triển Khai Blue-Green

Chiến lược blue-green giữ hai môi trường giống hệt nhau – blue (hiện tại) và green (tiếp theo). Lưu lượng sẽ được chuyển đổi ở cấp proxy khi stack green vượt qua các kiểm tra sức khỏe.

Danh Sách Các Bước

  1. Xây dựng & đẩy một hình ảnh Docker mới với một thẻ duy nhất (ví dụ: v1.2.3).
  2. Triển khai green containers trên một dải cổng riêng biệt (ví dụ: 8090-8099).
  3. Chạy các bài kiểm tra tích hợp tại điểm cuối green.
  4. Cập nhật Nginx upstream để chỉ đến các máy chủ green.
  5. Tải lại Nginx – lưu lượng giờ đây chảy đến green.
  6. Giám sát lỗi; nếu có lỗi, quay lại bằng cách chỉ định upstream trở lại blue.
  7. Ngừng hoạt động blue containers sau một khoảng thời gian làm mát an toàn.

Tự động hóa các bước 2-5 với một công việc CI để loại bỏ lỗi của con người.


Cập Nhật Liên Tục với Docker Compose

Nếu bạn thích một tệp compose duy nhất hơn hai stack riêng biệt, Docker Compose có thể thực hiện các cập nhật liên tục bằng cách sử dụng cờ --scale.

Ví dụ docker-compose.yml

Copy
version: "3.9"
services:
  web:
    image: myregistry.com/app:${APP_TAG}
    deploy:
      replicas: 4
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
    ports:
      - "8080:3000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3

Chạy docker compose up -d --pull always sẽ kéo thẻ mới, khởi động một bản sao mới, chờ kiểm tra sức khỏe của nó, sau đó ngừng bản sao cũ nhất một cách nhịp nhàng. Điều này giúp bạn có một quy trình triển khai zero-downtime mà không cần bước tải lại Nginx riêng biệt, nhưng bạn mất đi sự tách biệt rõ ràng giữa blue và green.


Kiểm Tra Sức Khỏe và Chuyển Đổi Lưu Lượng

Cả Docker và Nginx đều dựa vào các kiểm tra sức khỏe để quyết định khi nào một container đã sẵn sàng.

Ví dụ kiểm tra sức khỏe Dockerfile

Copy
HEALTHCHECK --interval=15s --timeout=3s \
  CMD curl -f http://localhost:3000/health || exit 1

Các kiểm tra sức khỏe chủ động của Nginx (module tùy chọn)

Nếu bạn biên dịch Nginx với ngx_http_upstream_check_module, bạn có thể kích hoạt việc kiểm tra chủ động:

Copy
upstream app_backend {
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
    check interval=3000 rise=2 fall=5 timeout=1000 type=http;
    check_http_send "GET /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx;
}

Các kiểm tra chủ động cung cấp cho bạn phản hồi ngay lập tức, cho phép công việc CI tạm dừng việc triển khai cho đến khi tất cả các backend báo cáo là khỏe mạnh.


Khả Năng Quan Sát & Ghi Nhận

Zero-downtime chỉ có giá trị nếu bạn có thể thấy khi có điều gì đó sai.

  • Nhật ký có cấu trúc – đầu ra JSON từ ứng dụng của bạn, được thu thập bởi Loki hoặc Elasticsearch.
  • Chỉ số – xuất Prometheus cho độ trễ yêu cầu, tỷ lệ lỗi và khởi động lại container.
  • Theo dõi – các span OpenTelemetry vượt qua proxy Nginx.
  • Cảnh báo – cảnh báo từ PagerDuty hoặc Opsgenie về các thất bại trong kiểm tra sức khỏe hoặc tỷ lệ lỗi cao.

Tích hợp những công cụ này vào quy trình CI của bạn để khi một triển khai thất bại, tự động tạo một vé.


Bảng Kiểm Tra Cuối

  • [ ] Hình ảnh Docker được xây dựng với Dockerfile đa giai đoạn và được gán thẻ duy nhất.
  • [ ] Pipeline CI đẩy hình ảnh đến một registry an toàn.
  • [ ] Cấu hình Nginx sử dụng một khối upstream với các tham số kiểm tra sức khỏe.
  • [ ] Containers blue-green được khởi động trên các cổng riêng biệt.
  • [ ] Kiểm tra smoke được thực hiện trên môi trường green.
  • [ ] Tải lại Nginx chỉ được thực hiện sau khi các kiểm tra sức khỏe thành công.
  • [ ] Kế hoạch quay lại được tài liệu hóa và tự động hóa.
  • [ ] Chồng quan sát (nhật ký, chỉ số, theo dõi) đang thu thập dữ liệu từ cả blue và green.
  • [ ] Xác minh sau triển khai bao gồm các ngưỡng về độ trễ và tỷ lệ lỗi.

Hãy làm theo bảng kiểm tra này cho mỗi lần phát hành và bạn sẽ giữ cho lưu lượng người dùng tiếp tục chảy trong khi mã của bạn phát triển.


Nếu bạn cần hỗ trợ trong việc triển khai, đội ngũ tại Ramer Labs có thể giúp đỡ.

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