Giới thiệu
Trong vai trò là một trưởng nhóm DevOps, bạn biết rằng thời gian ngừng hoạt động là kẻ thù của lòng tin người dùng. Việc triển khai các phiên bản mới của dịch vụ mà không làm gián đoạn lưu lượng truy cập là một thách thức cổ điển. Tuy nhiên, với Docker và Nginx, bạn có thể xây dựng một quy trình triển khai đáng tin cậy, không thời gian ngừng hoạt động. Danh sách kiểm tra này sẽ hướng dẫn bạn qua các bước thiết yếu—từ vệ sinh hình ảnh container đến định tuyến blue-green của Nginx—để bạn có thể tự tin triển khai các bản cập nhật.
1. Chuẩn bị Hình Ảnh Docker Sẵn Sàng Sản Xuất
1.1 Sử dụng Hình Ảnh Cơ Sở Tối Thiểu
- Alpine rất nhỏ (≈5 MB) và giảm bề mặt tấn công.
- Ghi rõ phiên bản để tránh nâng cấp bất ngờ.
dockerfile
FROM alpine:3.18
LABEL maintainer="you@example.com"
# Chỉ cài đặt những gì cần thiết
RUN apk add --no-cache python3 py3-pip
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
CMD ["python3", "-m", "gunicorn", "app:app", "--bind", "0.0.0.0:8000"]
1.2 Xây Dựng Đa Giai Đoạn cho Hình Ảnh Nhỏ Hơn
Tách biệt môi trường xây dựng khỏi môi trường thực thi:
dockerfile
# ---- Giai Đoạn Xây Dựng ----
FROM node:20-alpine AS builder
WORKDIR /src
COPY package*.json ./
RUN npm ci && npm run build
# ---- Giai Đoạn Thực Thi ----
FROM nginx:alpine
COPY --from=builder /src/dist /usr/share/nginx/html
1.3 Xác Minh Kích Thước & Các Lớp Hình Ảnh
bash
docker image ls --format "{{.Repository}}:{{.Tag}} {{.Size}}"
Giữ hình ảnh cuối cùng dưới 150 MB để tải nhanh hơn.
2. Triển Khai Blue-Green với Nginx
2.1 Cấu Hình Upstream của Nginx
Định nghĩa hai khối upstream—green và blue—trỏ đến các container Docker tương ứng.
nginx
upstream green {
server 127.0.0.1:8001;
keepalive 16;
}
upstream blue {
server 127.0.0.1:8002;
keepalive 16;
}
# Mặc định là green (sản xuất hiện tại)
server {
listen 80;
location / {
proxy_pass http://green;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
2.2 Chuyển Đổi Lưu Lượng Một Cách Tức Thời
Khi phiên bản mới sẵn sàng, cập nhật dòng proxy_pass để trỏ đến blue và tải lại Nginx mà không làm mất kết nối:
bash
# Chỉnh sửa cấu hình (hoặc sử dụng công cụ tạo mẫu)
sed -i 's/http:\/\/green/http:\/\/blue/' /etc/nginx/conf.d/app.conf
# Tải lại một cách an toàn
nginx -s reload
Vì Nginx tải lại cấu hình theo từng worker, các kết nối hiện tại sẽ hoàn tất trên upstream cũ trong khi các yêu cầu mới sẽ chảy về container đã được cập nhật.
3. Tự Động Hóa Quy Trình với Docker Compose
Một tệp docker-compose.yml có thể khởi động cả hai container green và blue, mở các cổng đúng và gán nhãn các dịch vụ để dễ dàng hoán đổi.
yaml
version: "3.9"
services:
app-green:
image: myorg/app:{{CURRENT_TAG}}
ports: ["8001:8000"]
restart: always
app-blue:
image: myorg/app:{{NEW_TAG}}
ports: ["8002:8000"]
restart: always
nginx:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
ports: ["80:80"]
depends_on:
- app-green
- app-blue
Các bước triển khai:
- Kéo hình ảnh mới (
docker pull myorg/app:1.2.3). - Khởi động container blue (
docker-compose up -d app-blue). - Xác minh các kiểm tra sức khỏe.
- Chuyển đổi upstream Nginx (như đã trình bày ở trên).
- Sau khi lưu lượng ổn định, tháo dỡ container green.
4. Kiểm Tra Sức Khỏe & Quan Sát
4.1 Kiểm Tra Sức Khỏe Cấp Container
Thêm một điểm cuối HTTP đơn giản (/healthz) vào ứng dụng của bạn và khai báo nó trong Docker:
dockerfile
HEALTHCHECK --interval=10s --timeout=2s \
CMD curl -f http://localhost:8000/healthz || exit 1
Docker sẽ đánh dấu container là không khỏe nếu điểm cuối thất bại, ngăn Nginx định tuyến đến một instance bị hỏng.
4.2 Logging Tập Trung
Gửi nhật ký đến một sidecar nhẹ như Fluent Bit và chuyển tiếp chúng đến Loki hoặc CloudWatch. Ví dụ fluent-bit.conf:
ini
[INPUT]
Name tail
Path /var/log/app/*.log
Tag app.*
[OUTPUT]
Name stdout
Match *
4.3 Thống Kê cho Quyết Định Cuộc Đổi
Mở thông số Prometheus (/metrics) và theo dõi tỷ lệ lỗi trong quá trình chuyển đổi. Nếu phiên bản mới tăng trên ngưỡng, hãy quay lại bằng cách trỏ lại Nginx đến upstream green.
5. Bảo Mật & Quản Lý Bí Mật
- Lưu trữ thông tin xác thực Docker registry trong Docker secrets hoặc một trình quản lý bí mật (AWS Secrets Manager, HashiCorp Vault).
- Sử dụng TLS termination tại Nginx: tạo chứng chỉ với Let’s Encrypt hoặc sử dụng PKI của công ty.
- Thêm header
Content-Security-Policynghiêm ngặt trong Nginx để giảm thiểu XSS.
nginx
add_header Content-Security-Policy "default-src 'self'" always;
6. Tóm Tắt Danh Sách Kiểm Tra
- [ ] Xây dựng hình ảnh Docker tối thiểu, đa giai đoạn.
- [ ] Gán nhãn hình ảnh bằng các định danh phiên bản không thay đổi.
- [ ] Định nghĩa các upstream
greenvàbluetrong Nginx. - [ ] Sử dụng Docker Compose để chạy cả hai phiên bản song song.
- [ ] Thêm kiểm tra sức khỏe container và mở điểm cuối
/healthz. - [ ] Xác minh sức khỏe container mới trước khi chuyển lưu lượng.
- [ ] Tải lại Nginx một cách nhẹ nhàng (
nginx -s reload). - [ ] Giám sát các thông số Prometheus để phát hiện đột biến lỗi.
- [ ] Ghi nhật ký vào một hệ thống trung tâm (Fluent Bit → Loki/CloudWatch).
- [ ] Bảo mật bí mật và bật TLS trên Nginx.
- [ ] Sau khi triển khai thành công, ngừng hoạt động container cũ.
Kết luận
Triển khai không thời gian ngừng hoạt động trở nên có thể lặp lại khi bạn coi hình ảnh Docker, định tuyến Nginx và khả năng quan sát như một đối tượng phiên bản duy nhất. Bằng cách làm theo danh sách kiểm tra này, bạn sẽ giảm rủi ro, cải thiện tốc độ phát triển và giữ cho người dùng không hề hay biết về những thay đổi ẩn sau. Nếu bạn cần trợ giúp trong việc triển khai này, đội ngũ tại https://ramerlabs.com có thể giúp bạn.