Chuyển đến nội dung chính

Cách container hóa một ứng dụng bằng Docker

Tìm hiểu cách container hóa ứng dụng học máy với Docker và Kubernetes. Hướng dẫn thân thiện cho người mới bắt đầu về xây dựng, triển khai và mở rộng mô hình ML dạng container trong môi trường sản xuất.
· 15 phút đọc

Khám phá cùng AI

Khi các ứng dụng machine learning ngày càng phức tạp, việc đưa mô hình từ giai đoạn phát triển lên sản xuất không chỉ là viết mã tốt. Điều quan trọng là đảm bảo ứng dụng chạy ổn định trên nhiều môi trường khác nhau. Đó là lúc container hóa phát huy tác dụng. Nhưng chính xác thì container hóa là gì, và vì sao nó lại là bước ngoặt cho quy trình làm việc của machine learning?

Container hóa là một cách nhẹ, linh động để đóng gói ứng dụng cùng toàn bộ phụ thuộc, thư viện và cấu hình vào một đơn vị duy nhất gọi là container. Khác với máy ảo (VM) truyền thống, container dùng chung hệ điều hành của máy chủ, giúp chúng khởi động nhanh hơn, hiệu quả hơn và dễ mở rộng hơn. 

Với các nhà khoa học dữ liệu và kỹ sư ML, điều này có nghĩa là bạn có thể xây dựng mô hình trên máy cá nhân và triển khai ở bất cứ đâu—dù là trên nền tảng đám mây, máy chủ, hay thậm chí là laptop của đồng nghiệp—mà không lo các vấn đề tương thích.

Trong hướng dẫn này, chúng ta sẽ xem cách container hóa một ứng dụng machine learning bằng Docker và Kubernetes. Kết thúc bài, bạn sẽ biết cách:

  1. Xây dựng một Docker container cho ứng dụng ML của bạn.
  2. Triển khai và quản lý ứng dụng dạng container bằng Kubernetes.
  3. Mở rộng và giám sát ứng dụng ML trong môi trường sản xuất.

Nếu bạn mới làm quen với Docker, hãy xem hướng dẫn Cách học Docker từ con số 0. Bạn cũng có thể học khóa Containerization and Virtualization with Docker and Kubernetes.  

Yêu cầu tiên quyết

Trước khi bắt đầu, bạn nên nắm cơ bản về Python, quy trình machine learning và làm việc với dòng lệnh. Nên quen thuộc với các khái niệm Docker (ví dụ: image, container, lệnh cơ bản), và kiến thức cơ bản về Kubernetes là tùy chọn nhưng hữu ích cho việc triển khai và mở rộng. 

Ứng dụng được container hóa là gì?

Ứng dụng được container hóa là phần mềm được đóng gói cùng toàn bộ phụ thuộc, thư viện và cấu hình vào một đơn vị nhẹ gọi là container. Với ứng dụng machine learning, điều này có nghĩa là đóng gói mọi thứ từ mô hình đã huấn luyện đến các thư viện Python mà nó phụ thuộc, bảo đảm ứng dụng chạy nhất quán ở mọi nơi.

Traditional application versus Containerized application

Ứng dụng truyền thống so với ứng dụng dạng container

Vì sao container hóa quan trọng với ứng dụng machine learning

Khi phát triển ứng dụng machine learning, hẳn bạn từng gặp vấn đề “chạy ổn trên máy tôi”. Có thể mô hình của bạn chạy hoàn hảo trên laptop nhưng thất bại khi triển khai lên cloud, hoặc đồng nghiệp không thể tái hiện kết quả vì họ cài phiên bản scikit-learn hay TensorFlow khác. 

Container hóa giải quyết các vấn đề này bằng cách tạo ra môi trường nhất quán, tách biệt cho ứng dụng. Dưới đây là những điểm khiến ứng dụng dạng container phù hợp hơn cho machine learning:

  1. Tính nhất quán: Ứng dụng của bạn hoạt động như nhau trên các môi trường—từ phát triển, kiểm thử đến sản xuất.
  2. Tách biệt: Mỗi container chạy trong môi trường riêng, tránh xung đột giữa các ứng dụng hoặc phụ thuộc khác nhau.
  3. Tính di động: Container có thể chạy trên bất kỳ nền tảng nào hỗ trợ container hóa—máy cá nhân, dịch vụ đám mây hay máy chủ on-premises.
  4. Khả năng mở rộng: Cần xử lý nhiều yêu cầu hơn? Container giúp mở rộng ngang dễ dàng bằng cách chạy nhiều phiên bản.

Container so với máy ảo

Cả container và máy ảo (VM) đều dùng để tách biệt ứng dụng, nhưng chúng khác nhau đáng kể về cách vận hành và tình huống sử dụng. Dưới đây là tổng quan các khác biệt và ưu điểm chính:

Khía cạnh

Container

Máy ảo (VM)

Kiến trúc

Dùng chung kernel của hệ điều hành máy chủ; nhẹ và tách biệt.

Bao gồm một hệ điều hành đầy đủ; chạy trên hypervisor.

Hiệu năng

Nhẹ, khởi động nhanh, và tiêu tốn ít tài nguyên.

Nặng hơn, khởi động chậm hơn, và dùng nhiều tài nguyên do overhead của hệ điều hành đầy đủ.

Tính di động

Rất linh động; chạy nhất quán trên nhiều môi trường.

Kém linh động hơn do phụ thuộc hệ điều hành; có thể gặp vấn đề tương thích.

Khả năng mở rộng

Dễ mở rộng bằng các công cụ điều phối như Kubernetes.

Có thể mở rộng nhưng cần nhiều tài nguyên và công sức quản trị hơn.

Bảo mật

Phụ thuộc bảo mật của hệ điều hành máy chủ; mức tách biệt kém hơn VM.

Tách biệt mạnh nhờ phiên bản hệ điều hành riêng; an toàn hơn cho ứng dụng nhạy cảm.

Với ứng dụng machine learning, những khác biệt này rất quan trọng. Khi bạn cần mở rộng mô hình để xử lý nhiều dự đoán hơn, hoặc muốn triển khai nhiều phiên bản mô hình để A/B testing, container mang lại sự linh hoạt và hiệu quả tài nguyên cần thiết.

Để tìm hiểu thêm về container hóa và ảo hóa, hãy xem lộ trình học: Containerization and Virtualization with Docker and Kubernetes.

Cách container hóa một ứng dụng machine learning 

Các phần dưới đây là hướng dẫn từng bước để container hóa một ứng dụng: 

1. Thiết lập môi trường

Trước khi container hóa ứng dụng machine learning, chúng ta cần cài đặt công cụ cần thiết và chuẩn bị môi trường. Phần này sẽ hướng dẫn bạn cài Docker và chuẩn bị một ứng dụng machine learning đơn giản để container hóa.

Công cụ bạn cần

Để container hóa một ứng dụng machine learning, bạn sẽ cần các công cụ sau:

  1. Docker: Nền tảng để xây dựng, phân phối và chạy container.
  2. Kubernetes (tùy chọn): Công cụ điều phối để quản lý container ở quy mô lớn. (Chúng ta sẽ đề cập ở phần sau.)

Bắt đầu bằng việc cài Docker.

Bước 1: Cài Docker

Docker có sẵn cho Windows, macOS và Linux. Dưới đây là các bước cài Docker trên hệ thống của bạn.

Đối với Windows/macOS:

  1. Truy cập trang Docker.
  2. Tải và cài Docker Desktop.
  3. Làm theo hướng dẫn của bộ cài.

Đối với Linux (Ubuntu/Debian):

Mở terminal và chạy các lệnh sau để cài Docker:

# Update your package list
sudo apt-get update

# Install required packages to allow apt to use a repository over HTTPS
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common

# Add Docker’s official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Add the Docker repository to your system
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Update your package list again
sudo apt-get update

# Install Docker
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# Verify Docker installation
sudo docker --version

Quy trình này thêm kho Docker vào hệ thống, xác thực bằng khóa GPG, và cài Docker engine cùng các công cụ dòng lệnh.

Bước 2: Xác minh cài đặt Docker 

Sau khi cài xong Docker, xác minh hoạt động bằng cách chạy lệnh sau trong command prompt:

# Check Docker version
docker --version

# Run hello-world container
docker run hello-world

Lệnh này sẽ kéo một image kiểm thử nhẹ và chạy nó như một container. Nếu thành công, bạn sẽ thấy thông điệp chào mừng xác nhận cài đặt hoạt động đúng, như dưới đây:

Hello from Docker!

2. Chuẩn bị ứng dụng machine learning của bạn

Giờ Docker đã sẵn sàng, hãy chuẩn bị một ứng dụng machine learning đơn giản để container hóa. Trong hướng dẫn này, chúng ta dùng một script Python cơ bản tải mô hình đã huấn luyện và phục vụ dự đoán qua Flask API.

Bước 1: Tạo một ứng dụng ML đơn giản

Tạo một thư mục mới cho dự án và thêm các tệp sau:

  1. app.py: Script Python phục vụ dự đoán qua Flask API.
  2. requirements.txt: Tệp liệt kê các phụ thuộc Python.

Dưới đây là mã cho app.py:

# Import required libraries
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from flask import Flask, request, jsonify
import numpy as np

# Initialize Flask app
app = Flask(__name__)

# Load and prepare the model
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = RandomForestClassifier(random_state=42)
model.fit(X_train, y_train)

@app.route('/predict', methods=['POST'])
def predict():
    # Get features from request
    features = request.json['features']
    
    # Make prediction
    prediction = model.predict([features])
    
    return jsonify({'prediction': int(prediction[0]),
                   'class_name': iris.target_names[prediction[0]]})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Đoạn mã tải bộ dữ liệu Iris, huấn luyện một bộ phân loại Random Forest, và thiết lập một endpoint Flask API nhận giá trị đặc trưng và trả về dự đoán. Chúng ta xây dựng như một dịch vụ web để phù hợp với container hóa.

Bước 2: Tạo requirements.txt

Tệp requirements.txt liệt kê các thư viện Python cần để chạy script. Tạo tệp này cùng thư mục với app.py:

# requirements.txt
scikit-learn==1.3.0
numpy==1.24.3
flask==2.0.1

Tệp này chỉ định chính xác phiên bản các gói Python mà ứng dụng cần. Cố định phiên bản giúp ứng dụng dạng container nhất quán và có thể tái lập.

Giờ môi trường đã sẵn sàng và ứng dụng ML đã chuẩn bị xong, chúng ta có thể chuyển sang xây dựng Docker container đầu tiên. Ở phần tiếp theo, chúng ta sẽ viết một Dockerfile và build một Docker image cho ứng dụng ML dựa trên Flask.

3. Xây dựng Docker container đầu tiên của bạn

Giờ ứng dụng machine learning đã sẵn sàng, bước tiếp theo là container hóa bằng Docker. Điều này bao gồm tạo một Dockerfile, là tập lệnh chứa hướng dẫn để build một Docker image. Khi image được build, ta có thể chạy nó như một container.

Ví dụ Dockerfile: Viết Dockerfile

Một Dockerfile là tài liệu văn bản chứa mọi lệnh để lắp ráp một image. Dưới đây là cách tạo Dockerfile cho ứng dụng ML dựa trên Flask của chúng ta.

  1. Trong cùng thư mục với app.py và requirements.txt, tạo tệp mới tên Dockerfile (không có phần mở rộng).
  2. Thêm nội dung sau vào Dockerfile:
# Use an official Python runtime as the base image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /app

# Copy the requirements file into the container
COPY requirements.txt .

# Install the Python dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy the rest of the application code into the container
COPY . .

# Expose port 5000 for the Flask app
EXPOSE 5000

# Define the command to run the Flask app
CMD ["python", "app.py"]

Giải thích:

  • FROM python:3.9-slim: Dùng image Python 3.9 slim chính thức làm base. Bản slim nhẹ, lý tưởng cho ứng dụng dạng container.
  • WORKDIR /app: Thiết lập thư mục làm việc bên trong container là /app. Mọi lệnh sau đó sẽ chạy từ đây.
  • COPY requirements.txt .: Sao chép tệp requirements.txt từ máy cục bộ vào container.
  • RUN pip install --no-cache-dir -r requirements.txt: Cài các phụ thuộc Python trong requirements.txt. Cờ --no-cache-dir giúp giảm kích thước image bằng cách không lưu cache.
  • COPY . .: Sao chép toàn bộ tệp từ thư mục hiện tại của máy cục bộ vào thư mục /app trong container.
  • EXPOSE 5000: Mở cổng 5000, là cổng ứng dụng Flask lắng nghe.
  • CMD ["python", "app.py"]: Xác định lệnh để chạy ứng dụng Flask khi container khởi động.

Build và kiểm thử Docker image

Khi đã có Dockerfile, giờ ta có thể build Docker image và chạy nó dưới dạng container. 

Bước 1: Build Docker image

Chạy lệnh sau trong terminal để build Docker image:

docker build -t ml-flask-app .

Lệnh này build Docker image từ Dockerfile trong thư mục hiện tại. Cờ -t ml-flask-app gắn thẻ image với tên ml-flask-app để dễ tham chiếu sau này.

Bước 2: Chạy Docker container

Khi image đã build xong, chạy nó như một container bằng lệnh sau:

docker run -p 5000:5000 ml-flask-app

Lệnh này khởi động container từ image ml-flask-app. Cờ -p 5000:5000 ánh xạ cổng 5000 trên máy cục bộ tới cổng 5000 trong container, cho phép bạn truy cập ứng dụng Flask từ trình duyệt hoặc công cụ như curl.

Bước 3: Kiểm thử ứng dụng dạng container

Mở một cửa sổ terminal mới và gửi yêu cầu kiểm thử đến ứng dụng Flask đang chạy trong container:

curl -X POST -H "Content-Type: application/json" -d '{"input": [5.1, 3.5, 1.4, 0.2]}' http://localhost:5000/predict

Bạn sẽ thấy phản hồi như sau:

{
  "prediction": 0
}

Điều này có nghĩa ứng dụng Flask dạng container chạy thành công và sẵn sàng phục vụ dự đoán.

Gỡ lỗi các vấn đề thường gặp

Nếu gặp sự cố khi build hoặc chạy container, dưới đây là vài mẹo để xử lý:

 Kiểm tra log của Docker: Dùng lệnh sau để xem log của container đang chạy:

docker logs <container_id>

Xác minh cú pháp Dockerfile: Kiểm tra kỹ Dockerfile để tránh lỗi chính tả hoặc cú pháp.

Kiểm tra xung đột cổng: Đảm bảo cổng 5000 chưa được dùng trên máy. Nếu đã dùng, bạn có thể ánh xạ sang cổng khác như sau:

docker run -p 5001:5000 ml-flask-app

Build lại image:

Nếu bạn thay đổi Dockerfile hoặc mã ứng dụng, hãy build lại image bằng:

docker build -t ml-flask-app .

Giờ khi chúng ta đã build và kiểm thử Docker container thành công, bước tiếp theo là học cách quản lý và mở rộng ứng dụng dạng container. Ở phần sau, chúng ta sẽ tìm hiểu cách dùng Kubernetes để triển khai và mở rộng ứng dụng ML.

Khám phá thêm các dự án Docker trong hướng dẫn 10 ý tưởng dự án Docker: từ mới bắt đầu đến nâng cao.

Chạy ứng dụng dạng container của bạn

Giờ chúng ta đã build Docker container, hãy xem cách quản lý hiệu quả. Phần này sẽ hướng dẫn các lệnh Docker thiết yếu để khởi động, dừng và kiểm tra container, cũng như làm việc với log và cổng.

Dùng Docker để quản lý container

Docker cung cấp bộ lệnh mạnh mẽ để quản lý container. Cùng điểm qua những lệnh thường dùng nhất.

Khởi động một container

Để khởi động container từ một image, dùng lệnh docker run. Ví dụ:

docker run -p 5000:5000 ml-flask-app

Lệnh này khởi động container từ image ml-flask-app và ánh xạ cổng 5000 trên máy cục bộ tới cổng 5000 trong container.

Nếu muốn chạy container dưới nền (chế độ tách), thêm cờ -d:

docker run -d -p 5000:5000 ml-flask-app

Cách này cho phép container chạy nền, giải phóng terminal của bạn.

Dừng một container

Để dừng container đang chạy, trước tiên tìm ID container bằng:

docker ps

Lệnh này liệt kê các container đang chạy với ID, tên và thông tin khác. Khi có ID, dừng container bằng:

docker stop <container_id>

Ví dụ:

docker stop a1b2c3d4e5f6

Kiểm tra một container

Để xem thông tin chi tiết về một container, dùng lệnh docker inspect:

docker inspect <container_id>

Lệnh này trả về JSON với các chi tiết như cài đặt mạng, volume gắn kèm và biến môi trường.

Liệt kê container

Để xem tất cả container (đang chạy và đã dừng), dùng:

docker ps -a

Lệnh này hữu ích để kiểm tra trạng thái container và tìm ID.

Làm việc với log và cổng

Log và cổng rất quan trọng cho việc gỡ lỗi và truy cập ứng dụng dạng container. Hãy xem cách làm việc với chúng.

Xem log của container

Để xem log của container đang chạy, dùng:

docker logs <container_id>

Ví dụ:

docker logs a1b2c3d4e5f6

Lệnh này hiển thị output của ứng dụng, gồm cả lỗi hoặc thông điệp in ra console. Nếu muốn theo dõi log theo thời gian thực (giống tail -f), thêm cờ -f:

docker logs -f <container_id>

Ánh xạ cổng

Khi chạy container, bạn có thể ánh xạ cổng của container ra máy cục bộ bằng cờ -p. Ví dụ:

docker run -p 5000:5000 ml-flask-app

Lệnh này ánh xạ cổng 5000 trong container ra cổng 5000 trên máy cục bộ. Nếu cổng 5000 đã được dùng, bạn có thể ánh xạ sang cổng khác như sau:

docker run -p 5001:5000 ml-flask-app

Giờ ứng dụng Flask sẽ truy cập được tại http://localhost:5001.

Kiểm tra ánh xạ cổng

Để xem các cổng được ánh xạ của container đang chạy, dùng:

docker port <container_id>

Lệnh này liệt kê ánh xạ cổng cho container, hữu ích khi gỡ lỗi các vấn đề kết nối. Ở phần tiếp theo, chúng ta sẽ xem cách triển khai ứng dụng ML dạng container lên Kubernetes và quản lý ở quy mô lớn.

Mở rộng với Kubernetes

Khi ứng dụng đã được container hóa, chúng ta có thể triển khai bằng Kubernetes. Kubernetes tự động hóa việc triển khai, mở rộng và quản lý ứng dụng dạng container, giúp xử lý khối lượng công việc lớn dễ dàng hơn. Phần này sẽ xem cách triển khai ứng dụng ML của chúng ta lên cụm Kubernetes.

Triển khai container trên Kubernetes

Kubernetes sử dụng các tệp YAML để định nghĩa trạng thái mong muốn của ứng dụng. Những tệp này mô tả cách container được triển khai, mở rộng và quản lý. Bắt đầu bằng việc tạo một deployment cho ứng dụng ML dựa trên Flask của chúng ta.

Bước 1: Viết tệp YAML cho deployment Kubernetes

Tạo tệp tên ml-flask-app-deployment.yaml với nội dung sau:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ml-flask-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ml-flask-app
  template:
    metadata:
      labels:
        app: ml-flask-app
    spec:
      containers:
      - name: ml-flask-app
        image: ml-flask-app
        ports:
        - containerPort: 5000

Tệp YAML này định nghĩa:

  •  Một Deployment tên ml-flask-app.
  • Ba replica của ứng dụng để đảm bảo tính sẵn sàng cao.
  • Một container dùng image ml-flask-app mà chúng ta đã build trước đó.
  • containerPort 5000, là cổng ứng dụng Flask lắng nghe.

Bước 2: Triển khai ứng dụng

Để triển khai ứng dụng trên Kubernetes, dùng lệnh kubectl apply:

kubectl apply -f ml-flask-app-deployment.yaml

Lệnh này yêu cầu Kubernetes tạo các tài nguyên đã định trong tệp YAML. Bạn có thể kiểm tra trạng thái deployment bằng:

kubectl get deployments

Lệnh này hiển thị trạng thái deployment, bao gồm số replica đang chạy.

Bước 3: Phơi bày (expose) ứng dụng

Để ứng dụng có thể truy cập từ bên ngoài cụm Kubernetes, hãy tạo một Service. Tạo tệp tên ml-flask-app-service.yaml với nội dung sau:

apiVersion: v1
kind: Service
metadata:
  name: ml-flask-app-service
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 5000
  selector:
    app: ml-flask-app

Tệp YAML này định nghĩa:

  • Một Service tên ml-flask-app-service.
  • Kiểu LoadBalancer, cho phép phơi bày ứng dụng ra internet.
  • Ánh xạ từ cổng 80 (bên ngoài) đến cổng 5000 (bên trong).

Áp dụng Service bằng:

kubectl apply -f ml-flask-app-service.yaml

Bạn có thể kiểm tra trạng thái Service bằng:

kubectl get services

Lệnh này hiển thị địa chỉ IP bên ngoài nơi ứng dụng của bạn có thể truy cập được.

Mở rộng và giám sát

Kubernetes giúp bạn dễ dàng mở rộng ứng dụng và theo dõi hiệu năng. Hãy cùng khám phá cách thực hiện.

Mở rộng ứng dụng

Để mở rộng ứng dụng, hãy cập nhật số lượng bản sao trong deployment. Ví dụ, để tăng lên 5 bản sao, chạy:

kubectl scale deployment ml-flask-app --replicas=5

Bạn cũng có thể cập nhật trường replicas trong tệp YAML và áp dụng lại:

spec:
  replicas: 5

Sau đó chạy:

kubectl apply -f ml-flask-app-deployment.yaml

Giám sát ứng dụng

Kubernetes cung cấp nhiều công cụ để giám sát ứng dụng của chúng ta. Hãy xem một số công cụ để theo dõi ứng dụng.

Dùng kubectl logs để xem log của một pod cụ thể:

kubectl logs <pod_name>
 

Dùng kubectl get pods để kiểm tra trạng thái các pod của bạn:

kubectl get pods

Dùng kubectl top để xem mức sử dụng CPU và bộ nhớ:

kubectl top pods

Tự động mở rộng

Kubernetes cũng hỗ trợ Horizontal Pod Autoscaler (HPA), tự động mở rộng số lượng pod dựa trên mức sử dụng CPU hoặc bộ nhớ. Để bật tự động mở rộng, chạy:

kubectl autoscale deployment ml-flask-app --cpu-percent=50 --min=3 --max=10

Thiết lập này đảm bảo deployment sẽ mở rộng trong khoảng từ 3 đến 10 bản sao dựa trên mức sử dụng CPU.

Thực tiễn tốt nhất cho các deployment trên Kubernetes

Dưới đây là một số thực tiễn tốt nhất nên tuân theo khi triển khai ứng dụng trên Kubernetes.

Sử dụng giới hạn tài nguyên

Đặt giới hạn CPU và bộ nhớ cho container của bạn để tránh cạn kiệt tài nguyên:

resources:
   limits:
     cpu: "1"
     memory: "512Mi"

Dùng liveness và readiness probe

Thêm kiểm tra tình trạng để đảm bảo ứng dụng của bạn chạy đúng:

livenessProbe:
  httpGet:
    path: /health
    port: 5000
  initialDelaySeconds: 5
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /ready
    port: 5000
  initialDelaySeconds: 5
  periodSeconds: 10
   

Sử dụng namespace

Tổ chức tài nguyên của bạn bằng namespace để tránh xung đột:

kubectl create namespace ml-app
kubectl apply -f ml-flask-app-deployment.yaml -n ml-app

Trong phần tiếp theo, chúng ta sẽ trình bày các mẹo tối ưu hóa Dockerfile, quản lý phụ thuộc và đảm bảo bảo mật.

Thực tiễn tốt nhất khi container hóa ứng dụng ML

Container hóa ứng dụng học máy đi kèm nhiều thách thức riêng, như quản lý phụ thuộc lớn, đảm bảo khả năng lặp lại và duy trì bảo mật. Dưới đây là một số thực tiễn tốt giúp bạn vượt qua các thách thức này và xây dựng ứng dụng ML dưới dạng container vững chắc.

Tối ưu hóa Dockerfile

Một Dockerfile được tối ưu tốt có thể giảm đáng kể thời gian build và kích thước image. Sau đây là một số gợi ý để tối ưu Dockerfile của bạn:

Sử dụng build nhiều giai đoạn (multi-stage)

Multi-stage build cho phép chúng ta dùng nhiều câu lệnh FROM trong một Dockerfile. Điều này giúp giảm kích thước image cuối cùng bằng cách loại bỏ tệp và phụ thuộc không cần thiết từ các giai đoạn trung gian. Ví dụ:

# Stage 1: Build the application
FROM python:3.9-slim as builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt

COPY . .

# Stage 2: Create the final image
FROM python:3.9-slim

WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY --from=builder /app .

ENV PATH=/root/.local/bin:$PATH
EXPOSE 5000
CMD ["python", "app.py"]

Dockerfile này:

  • Dùng một giai đoạn builder để cài đặt phụ thuộc và build ứng dụng.
  • Chỉ sao chép những tệp cần thiết (ví dụ: phụ thuộc đã cài và mã ứng dụng) sang image cuối, giúp giảm kích thước.

Giảm số lượng layer

Mỗi chỉ thị trong Dockerfile tạo ra một layer mới. Để giảm số layer và thu nhỏ kích thước image:

  • Kết hợp nhiều lệnh RUN thành một lệnh duy nhất bằng &&.
  • Ưu tiên dùng COPY thay vì ADD trừ khi bạn cần chức năng bổ sung của ADD.

Ví dụ:

RUN apt-get update && \
    apt-get install -y --no-install-recommends build-essential && \
    rm -rf /var/lib/apt/lists/*

Dùng image nền nhẹ

Chọn image nền nhẹ như python:3.9-slim thay vì các image lớn như python:3.9. Image "slim" chỉ chứa các gói thiết yếu, giúp giảm kích thước tổng thể.

Quản lý phụ thuộc và khả năng lặp lại

Tính lặp lại là yếu tố then chốt trong quy trình học máy. Dưới đây là cách quản lý phụ thuộc và đảm bảo khả năng lặp lại trong các ứng dụng dạng container của bạn.

Sử dụng requirements.txt hoặc pipen

Liệt kê tất cả phụ thuộc Python của bạn trong tệp requirements.txt hoặc dùng pipenv để quản lý. Ví dụ:

# requirements.txt
scikit-learn==1.3.0
numpy==1.24.3
Flask==2.3.2

Cài đặt phụ thuộc trong Dockerfile của bạn:

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

Cố định phiên bản phụ thuộc

Luôn cố định phiên bản phụ thuộc để tránh thay đổi ngoài ý muốn. Ví dụ:

scikit-learn==1.3.0
numpy==1.24.3
Flask==2.3.2

Dùng biến môi trường cho cấu hình

Sử dụng biến môi trường để cấu hình ứng dụng thay vì hardcode giá trị. Điều này giúp container linh hoạt hơn và dễ cấu hình ở các môi trường khác nhau. Ví dụ:

ENV MODEL_PATH=/app/models/model.pkl

Sau đó, truy cập biến môi trường trong ứng dụng của bạn:

import os
model_path = os.getenv('MODEL_PATH')

Các lưu ý về bảo mật

Bảo mật là khía cạnh quan trọng của ứng dụng dưới dạng container. Dưới đây là một số thực tiễn tốt để bảo vệ ứng dụng ML của bạn:

Tránh chạy dưới quyền root

Chạy container với người dùng root có thể khiến hệ thống gặp rủi ro bảo mật. Thay vào đó, tạo một người dùng không phải root và chạy container với người dùng đó. Ví dụ:

# Create a non-root user
RUN useradd -m myuser

# Switch to the non-root user
USER myuser

# Set the working directory
WORKDIR /home/myuser/app

# Copy the application code
COPY --chown=myuser:myuser . .

# Run the application
CMD ["python", "app.py"]

Quét lỗ hổng trên image

Dùng các công cụ như Trivy hoặc Clair để quét lỗ hổng trên Docker image của bạn. Ví dụ, để quét một image bằng Trivy:

trivy image ml-flask-app

Quản lý secrets an toàn

Không bao giờ hardcode thông tin nhạy cảm như khóa API hoặc thông tin đăng nhập cơ sở dữ liệu trong Dockerfile hay mã ứng dụng. Thay vào đó, sử dụng Kubernetes Secrets hoặc Docker Secrets để quản lý dữ liệu nhạy cảm. Ví dụ, trong Kubernetes:

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  api_key: <base64-encoded-api-key>

Sau đó, mount secret này dưới dạng biến môi trường trong deployment của bạn:

env:
- name: API_KEY
  valueFrom:
    secretKeyRef:
      name: my-secret
      key: api_key

Kiểm thử và gỡ lỗi

Kiểm thử và gỡ lỗi rất cần thiết để đảm bảo ứng dụng dạng container của bạn hoạt động như mong đợi. Một số gợi ý:

Kiểm thử cục bộ

Trước khi triển khai lên Kubernetes, hãy kiểm thử container của bạn cục bộ bằng Docker. Ví dụ:

docker run -p 5000:5000 ml-flask-app

Dùng log để gỡ lỗi

Dùng docker logs hoặc kubectl logs để gỡ lỗi sự cố trong ứng dụng dạng container của bạn. Ví dụ:

docker logs <container_id>
kubectl logs <pod_name>

Tự động hóa kiểm thử

Sử dụng pipeline CI/CD để tự động hóa kiểm thử và triển khai ứng dụng dạng container của bạn. Các công cụ như GitHub Actions, GitLab CI hoặc Jenkins có thể giúp chúng ta thiết lập quy trình tự động.

Bằng cách tuân theo các thực tiễn tốt này, chúng ta có thể xây dựng ứng dụng học máy dạng container hiệu quả, có khả năng lặp lại và an toàn. Từ việc tối ưu Dockerfile đến quản lý phụ thuộc và đảm bảo bảo mật, những chiến lược này sẽ giúp tinh gọn quy trình ML và triển khai mô hình một cách tự tin.

Kết luận

Container hóa ứng dụng học máy với Docker và Kubernetes giúp hợp lý hóa triển khai, đảm bảo khả năng lặp lại và tăng cường khả năng mở rộng. Bằng cách áp dụng các thực tiễn tốt như tối ưu Dockerfile, quản lý phụ thuộc và ưu tiên bảo mật, chúng ta có thể xây dựng quy trình ML vững chắc, hiệu quả và an toàn.

Để tiếp tục tìm hiểu về container hóa và nâng cao quy trình học máy của bạn, hãy tham khảo các khóa học sau:

Câu hỏi thường gặp về Container hóa ứng dụng ML

Việc container hóa có bắt buộc đối với các mô hình học máy không?

Không bắt buộc, nhưng nó giúp việc triển khai, mở rộng và kiểm soát phiên bản dễ dàng và đáng tin cậy hơn nhiều.

Tôi có thể cập nhật mô hình ML của mình mà không dừng container không?

 Có, bạn có thể thực hiện rolling update để thay thế container bằng phiên bản mô hình mới mà không gây gián đoạn.

Nhiều mô hình ML có thể chạy trong cùng một container không?

Có thể, dù tốt hơn là chạy mỗi mô hình trong các container riêng để quản lý tài nguyên hiệu quả hơn.

Sự khác nhau giữa Docker và Container là gì?

Docker là nền tảng tạo và quản lý container; còn container là gói ứng dụng thực tế.

Tôi có cần Kubernetes để chạy ứng dụng dạng container không?

Không, chỉ cần Docker là đủ để chạy container; Kubernetes chỉ cần khi bạn muốn mở rộng nhiều container.

Tác giả

Rajesh Kumar

Tôi là một biên tập viên nội dung về khoa học dữ liệu. Tôi yêu thích sáng tạo nội dung xoay quanh các chủ đề AI/ML/DS. Tôi cũng khám phá các công cụ AI mới và viết về chúng.

Chủ đề

Liên quan