Bài 2. Docker Image: cách xây Dựng và tối Ưu

Docker không chỉ là chạy container – nó bắt đầu từ Docker Image, “bản thiết kế” để tạo ra container. Trong DevOps, việc xây dựng image nhẹ, nhanh, và đáng tin cậy là yếu tố sống còn để tối ưu pipeline CI/CD. Trong bài thứ hai của series, chúng ta sẽ đi sâu vào Docker Image trong DevOps, đặc biệt tập trung vào Dockerfile chuyên sâu, cách build container hiệu quả, và kỹ thuật tối ưu image để giảm kích thước, tăng tốc độ. Hãy chuẩn bị để làm chủ nghệ thuật tạo image!

Docker Image Là Gì?

Định Nghĩa và Cấu Trúc

Docker Image là tập hợp các layer (lớp) chỉ đọc, chứa mã nguồn, thư viện, và cấu hình cần thiết để chạy ứng dụng trong container.

  • Layer: Mỗi lệnh trong Dockerfile tạo một layer, được cache để tái sử dụng.
  • Ví dụ: Image nginx:alpine gồm layer cơ bản (Alpine Linux) và layer Nginx.

DevOps: Image là “gói hàng” bạn build trong CI, push lên registry, và deploy trong CD.

Image vs Container

  • Image: Template tĩnh, không chạy.
  • Container: Instance động của image, chạy trên Docker Engine.

Thực tế: Một image Python có thể sinh ra hàng trăm container test trong pipeline.

Dockerfile Chuyên Sâu: Xây Dựng Image Từ Đầu

Cấu Trúc Dockerfile

Dockerfile là file script định nghĩa cách build image. Các lệnh chính:

  1. FROM: Base image khởi đầu.
    FROM ubuntu:20.04
  2. RUN: Chạy lệnh trong image (cài package, update).
    RUN apt update && apt install -y python3
  3. COPY: Sao chép file từ host vào image.
    COPY app.py /app/
  4. WORKDIR: Đặt thư mục làm việc.
    WORKDIR /app
  5. CMD: Lệnh mặc định khi container chạy.
    CMD ["python3", "app.py"]
  6. EXPOSE: Công khai port (thông tin, không bind).
    EXPOSE 8080
  7. ENV: Đặt biến môi trường.
    ENV APP_ENV=production

DevOps: Dockerfile là “công thức” để đảm bảo môi trường nhất quán từ dev đến prod.

Layer Caching: Bí Mật Tăng Tốc Build

Docker cache layer để tránh chạy lại lệnh không thay đổi.

  • Nguyên tắc: Thứ tự lệnh ảnh hưởng cache.
  • Ví dụ sai:
    FROM python:3.9
    COPY . /app
    RUN pip install -r requirements.txt
    • COPY . thay đổi → cache RUN bị phá, build chậm.
  • Ví dụ đúng:
    FROM python:3.9
    RUN pip install -r requirements.txt
    COPY . /app
    • RUN được cache nếu requirements.txt không đổi.

DevOps: Tối ưu cache giảm thời gian build trong pipeline từ phút xuống giây.

Multi-Stage Build: Giảm Kích Thước Image

Multi-stage build dùng nhiều FROM để tách build và runtime.

  • Ví dụ:

    # Stage 1: Build
    FROM python:3.9 AS builder
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install --user -r requirements.txt
    
    # Stage 2: Runtime
    FROM python:3.9-slim
    WORKDIR /app
    COPY --from=builder /root/.local /root/.local
    COPY app.py .
    CMD ["python3", "app.py"]
  • Kết quả: Image chỉ chứa runtime, loại bỏ tool build (VD: giảm từ 900MB xuống 150MB).

DevOps: Image nhỏ hơn → push/pull nhanh hơn trong CI/CD.

Tối Ưu Image: Kỹ Thuật Nâng Cao

Chọn Base Image Nhẹ

  • Alpine: ~5MB, nhỏ nhất.
  • Slim: Cân bằng giữa nhỏ và đầy đủ (VD: python:3.9-slim ~80MB).
  • Ví dụ:
    FROM alpine:3.14
    RUN apk add --no-cache python3

Gộp Lệnh RUN

  • Giảm layer, giảm kích thước metadata:
    RUN apt update && apt install -y python3 && apt clean

Xóa File Thừa

  • Xóa cache package sau cài đặt:
    RUN apt update && apt install -y python3 && rm -rf /var/lib/apt/lists/*

Dùng .dockerignore

  • Loại file không cần (VD: .git, node_modules):
    # .dockerignore
    .git
    *.md

DevOps: Image tối ưu giảm tải registry, tăng tốc deploy.

Thực Hành: Build Image Chuyên Sâu

Tạo Ứng Dụng Python

  1. File app.py:

    from flask import Flask
    app = Flask(__name__)
    
    @app.route('/')
    def hello():
       return "Hello DevOps!"
    
    if __name__ == "__main__":
       app.run(host="0.0.0.0", port=8080)
  2. File requirements.txt:
    flask==2.0.1

Dockerfile Tối Ưu

# Stage 1: Build
FROM python:3.9-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt

# Stage 2: Runtime
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY app.py .
ENV PATH=/root/.local/bin:$PATH
EXPOSE 8080
CMD ["python3", "app.py"]

Build và Test

  1. Build:
    docker build -t myapp:latest .
  2. Chạy:
    docker run -d -p 8080:8080 myapp:latest
  3. Test:
    curl localhost:8080
    • Kết quả: “Hello DevOps!”.

Kiểm Tra Kích Thước

docker images myapp:latest
  • So sánh: python:3.9 (~900MB) vs myapp (~150MB).

Debug tip:

  • Build lỗi: Xem log docker build -t myapp . --no-cache.
  • Container không chạy: Check docker logs <container-id>.

Ứng Dụng trong DevOps

Microservices

  • Mỗi service có Dockerfile riêng, tối ưu riêng (VD: web dùng nginx:alpine, API dùng python:slim).

Case study: Một team giảm kích thước image từ 1.2GB xuống 200MB với multi-stage, tăng tốc pipeline 3 lần.

Kết Luận

Docker Image trong DevOps là bước quan trọng để tạo container hiệu quả. Với Dockerfile chuyên sâu, từ layer caching, multi-stage build, đến kỹ thuật tối ưu image, bạn có thể xây dựng image nhẹ, nhanh cho CI/CD. Bài tiếp theo, chúng ta sẽ khám phá Docker Networking – cách kết nối container trong DevOps.

Điều hướng chuỗi bài viết<< Bài 1. Cơ Bản Docker: Hiểu Container và Vai Trò trong DevOps
>> Bài 3. Docker Networking: Kết Nối Container Hiệu Quả
Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận