Cách tạo Docker image hiệu quả cho dự án Python

Docker image là công cụ mạnh mẽ trong việc phân phối các dự án Python, nhưng điều quan trọng bạn cần giữ chúng gọn gàng nhất có thể.

Docker

Docker là phần mềm chuẩn ngành công nghiệp cho việc đóng gói và triển khai ứng dụng trong container. Docker image là nền tảng mà bạn có thể xây dựng và chạy các ứng dụng.

Để mở khóa hoàn toàn tiềm năng của Docker, bạn cần tối ưu hóa các image để đạt được hiệu quả, bảo mật và năng suất. Điều này đảm bảo các ứng dụng của bạn hoạt động trơn tru trong hệ sinh thái Docker.

Dưới đây là hướng dẫn chi tiết cách làm việc đó qua một ví dụ thực tế, cho bạn biết cách container hóa ứng dụng máy tính được phát triển bằng Python.

Bắt đầu với image cơ bản nhất

Một trong số nhân tố ảnh hưởng tới hiệu quả của image Docker là lựa chọn image cơ bản. Bạn nên bắt đầu với một image tối thiểu mà chỉ bao gồm những thành phần thiết yếu cho việc chạy ứng dụng.

Image bạn dùng cũng nên xuất phát từ nguồn uy tín, cung cấp các bản cập nhật và bản vá bảo mật. Nó cũng có một cộng đồng hoạt động tích cực và tài liệu tốt. Điều này hữu ích khi khắc phục sự cố hay tìm kiếm sự trợ giúp.

Đối với ứng dụng tính toán, chọn python:3.11-slim-bookworm, là một image tối thiểu, giảm kích thước image. Ngược lại, điều này giảm tiêu thụ tài nguyên và tăng tốc download & triển khai image.

# Bắt đầu với image cơ bản nhất
FROM python:3.11-slim-bookworm AS builder

Bạn thậm chí có thể dùng image Alpine Linux nhỏ hơn, bằng cách chọn python:3.11-alpine. Tuy nhiên, image này không bao gồm trình biên dịch Python, một công cụ quản lý gói và các thư viện Python phổ biến.

Chạy ứng dụng dưới tư cách người dùng không root

Chạy container Docker bằng quyền người dùng root có thể phải đối mặt với rủi ro bảo mật đáng kể. Nếu tác nhân độc hại giành được quyền truy cập tới một container đang chạy dưới dạng root, chúng có thể khai thác lỗ hổng trong phần mềm của container để nâng cao đặc quyền của chúng. Sau đó, chúng dùng những quyền đó thực thi các lệnh với toàn quyền kiểm soát hệ thống lưu trữ.

Giải pháp là chạy app của bạn với tư cách là người dùng không root. Ví dụ ứng dụng máy tính này tạo và cấu hình máy tính người dùng.

# Đặt người dùng không root để đảm bảo an toàn
RUN adduser calculator --system

# Thêm người dùng vào nhóm máy tính
RUN addgroup calculator && adduser calculator calculator

Việc tạo người dùng chuyên dụng cho ứng dụng của bạn sẽ hạn chế quyền có sẵn cho những hacker tiềm ẩn. Điều này khiến việc khai thác lỗ hổng trở nên khó khăn hơn.

Sao chép file cần thiết và tạo môi trường ảo

Tạo môi trường ảo trong container Docker cô lập các phần phụ thuộc. Điều này ngăn chặn xung đột với gói và ứng dụng khác trên toàn hệ thống. Nó cũng đảm bảo tương thích phiên bản khi bạn có thể cài đặt chính xác phiên bản của các phần phụ thuộc cần cho ứng dụng mà không ảnh hưởng tới phần còn lại của hệ thống.

Sao chép file cần thiết vào container. Sau đó, tạo môi trường ảo cho ứng dụng máy tính bằng mô đun venv được tích hợp sẵn trong Python.

# Đặt thư mục hoạt động và sao chép file cần thiết
WORKDIR /app
COPY app.py .
COPY requirements.txt .
COPY config.json ./
# Sao chép config.json từ thư mục cục bộ

# Tạo môi trường ảo và các phần phụ thuộc
RUN python -m venv /venv
ENV PATH="/venv/bin:$PATH"
RUN /venv/bin/pip install --upgrade pip --no-cache-dir --requirement requirements.txt

Những môi trường ảo gọn nhẹ và hiệu quả vì chúng không sao chép các gói trên toàn hệ thống. Điều này giúp duy trì kích thước image của Docker nhỏ hơn và giảm tiêu hao tài nguyên khi container chạy.

Giảm thiểu các lớp nhằm tăng hiệu quả

Mỗi hướng dẫn ở Dockerfile tạo một layer mới trong image kết quả. Docker dùng cơ chế sao chép khi ghi để quản lý những layer này. Giảm số lượng image Docker cải thiện đáng kể kích thước image và hiệu quả xây dựng. Một cách giảm layer khác là hợp nhất nhiều lệnh vào một lệnh RUN duy nhất.

# Giảm thiểu layer để đạt được hiệu quả
# Kết hợp lệnh để giảm số lượng layer
RUN echo "Build process goes here" && \
   /venv/bin/python -m compileall . && \
   rm -rf __pycache__

Kết hợp các lệnh trên giảm số lượng layer trung gian được tạo trong quá trình xây dựng image.

Bảo mật xử lý cấu hình

Xử lý thông tin nhạy cảm trong image Docker có thể gặp rủi ro. Để nâng cao độ an toàn, bạn nên dùng các biến môi trường và file cấu hình bên ngoài. Ở ví dụ này, bạn có thể tạo thư mục tên /config chứa file cấu hình và đặt quyền sở hữu phù hợp.

# Bảo mật xử lý cấu hình
RUN mkdir /config && chown calculator:calculator /config

Sau đó sao chép file config.json vào thư mục này, đảm bảo nó vẫn tách biệt với code ứng dụng.

# Sao chép file config.json file vào container
RUN cp config.json /config/config.json
ENV CONFIG_PATH=/config/config.json

Việc tách biệt dữ liệu cấu hình khỏi code và áp dụng các quyền phù hợp sẽ tăng cường bảo mật tổng thể cho image Docker của bạn. Nó đảm bảo chỉ những quy trình hoặc người dùng được ủy quyền mới được phép truy cập vào dữ liệu cấu hình quan trọng.

Dùng các bản build nhiều giai đoạn

Những bản build nhiều giai đoạn cho phép bạn tách môi trường xây dựng khỏi image cuối cùng. Điều này cho kết quả trong các image sản phẩm nhỏ và tập trung hơn. Nó cũng nâng cao bảo mật bằng cách loại trừ những công cụ và file liên quan tới việc build khỏi image cuối cùng. Ngoài ra, việc này còn giảm các vụ tấn công cũng như rủi ro bảo mật tiềm ẩn liên quan đến những thành phần không cần thiết.

# Nâng cấp bản build nhiều giai đoạn
FROM python:3.11-slim-bookworm

COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
COPY --from=builder /venv /venv
COPY --from=builder /config /config
COPY --from=builder /app /app
# Sao chép code ứng dụng

Code trên chỉ sao chép những thành phần cần thiết từ giai đoạn xây dựng (builder) vào image cuối cùng. Điều này giảm kích thước ảnh bằng cách loại trừ những công cụ, file liên quan nhưng không cần cho việc ứng dụng.

Nâng cao bảo mật bằng công cụ quét image

Bạn có thể dùng những công cụ quét như Trivy hoặc Clair. Chúng được thiết kế để xác định các lỗ hổng trong layer image và các phần phụ thuộc. Dùng Trivy cho app tính toán, để tiến hành quét lỗ hổng.

# Cài đặt Trivy cho Debian/Ubuntu
RUN apt-get update && \
   apt-get install -y wget apt-transport-https gnupg lsb-release && \
   wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add - && \
   echo "deb https://aquasecurity.github.io/trivy-repo/deb bookworm main" \
   | tee -a /etc/apt/sources.list.d/trivy.list && \
   apt-get update && \
   apt-get install -y trivy

Thêm công cụ quét lỗ hổng Trivy vào image Docker rất quan trọng. Đó là do nó dùng database Common Vulnerabilities and Exposures (CVE), được update thường xuyên kèm thông tin về các lỗ hổng đã biết. Điều này giúp bạn update liên tục các image với bản vá bảo mật mới nhất, đồng thời bảo vệ ứng dụng khỏi các hành vi khai thác đã biết.

Để nhận báo cáo lỗ hổng trên image, dùng lệnh sau:

docker run --rm `
 -v /var/run/docker.sock:/var/run/docker.sock `
 -v $HOME/Library/Caches:/root/.cache/ `
 aquasec/trivy:0.18.3 `
 <your image name>

Lệnh trên sẽ cần chút thời gian để chạy. Sau khi nó hoàn tất, bạn sẽ nhận được báo cáo như hình bên dưới.

Nâng cao bảo mật ứng dụng

Mức độ nghiêm trọng càng cao thì bạn càng nên xử lý lỗ hổng đó sớm.

Chạy ứng dụng trong vai trò người dùng không root

Để nâng cao độ an toàn khi chạy ứng dụng dưới tư cách là người dùng thông thường, chạy:

# Chạy ứng dụng trong vai trò người dùng không root
WORKDIR /app
USER calculator

# Kích hoạt môi trường ảo và chạy ứng dụng này
CMD ["/bin/bash", "-c", "source /venv/bin/activate && python app.py"]

Chuyển sang chế độ người dùng không root sẽ giảm thiểu đáng kể nguy cơ bị tấn công.

Hi vọng bài viết hữu ích với các bạn!

Thứ Ba, 26/09/2023 10:52
43 👨 831
0 Bình luận
Sắp xếp theo