Triển khai Docker: Cài đặt, thao tác container và xây dựng image tùy chỉnh

Mục tiêu

Bài viết tổng hợp quy trình làm việc thực tế với Docker trong môi trường production, bao gồm cài đặt môi trường, các thao tác container thường dùng và phương pháp đóng gói ứng dụng thành image có thể tái sử dụng.

Hiểu về container hóa

Container là đơn vị triển khai phần mềm độc lập, đóng gói ứng dụng cùng các phụ thuộc trong một môi trường cách ly. Khác với máy ảo truyền thống phải mang theo hệ điều hành riêng, container chia sẻ kernel với host, giúp khởi động nhanh và tiêu thụ ít tài nguyên hơn đáng kể.

Lĩnh vực áp dụng

  • Microservices và cloud-native: Container là nền tảng cho kiến trúc phân tán, kết hợp với Kubernetes để tự động hóa việc mở rộng quy mô.
  • AI/ML training: NVIDIA Container Toolkit cho phép container truy cập GPU, giải quyết bài toán cài đặt CUDA và framework phức tạp.

Thiết lập Docker trên Ubuntu

# Gỡ bỏ phiên bản cũ nếu có
sudo apt-get purge docker docker-engine docker.io

# Cài đặt các công cụ cần thiết
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release

# Thêm repository chính thức của Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
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

# Cài đặt Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# Cấu hình quyền truy cập không cần sudo (tùy chọn)
sudo usermod -aG docker $USER

Để sử dụng GPU trong container:

# Cài đặt NVIDIA Container Toolkit
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit nvidia-docker2
sudo systemctl restart docker

# Sử dụng lệnh nvidia-docker hoặc --gpus flag với docker run

Bộ lệnh Docker thiết yếu

# Khởi động daemon
sudo systemctl enable --now docker

# Thông tin phiên bản
docker --version

# Quản lý image
docker images                    # Liệt kê image local
docker pull registry/image:tag   # Tải image từ registry
docker rmi image_id              # Xóa image

# Quản lý container
docker ps                        # Container đang chạy
docker ps -a                     # Tất cả container
docker run -d --name svc -p 8080:80 nginx:alpine  # Chạy ngầm
docker run -it --rm ubuntu:22.04 /bin/bash        # Chạy tương tác, tự xóa khi exit

docker start/stop/restart container_name
docker attach container_name     # Gắn terminal vào container đang chạy
docker exec -it container_name /bin/bash  # Mở shell mới trong container

docker logs -f --tail 100 container_name  # Theo dõi log real-time
docker stats container_name      # Giám sát tài nguyên

docker rm container_name         # Xóa container đã stop
docker rm -f $(docker ps -aq)    # Xóa toàn bộ container

# Xuất/nhập dữ liệu
docker export container_name > backup.tar
docker import backup.tar imported-image:tag

docker save -o archive.tar image:tag
docker load -i archive.tar

# Thông tin chi tiết
docker inspect container_name    # Metadata đầy đủ
docker top container_name        # Tiến trình bên trong

Xây dựng image tùy chỉnh

Có hai phương pháp chính: chụp snapshot từ container đang chạy (commit) hoặc định nghĩa quy trình xây dựng qua Dockerfile (build).

Phương pháp 1: docker commit

# Đăng nhập registry
docker login registry.example.com

# Tạo image từ container đã chỉnh sửa
docker commit -a "Dev Team" -m "Added monitoring tools" web-server web-app:v2.1

# Đánh tag và đẩy lên registry
docker tag web-app:v2.1 registry.example.com/project/web-app:v2.1
docker push registry.example.com/project/web-app:v2.1

Phương pháp 2: Dockerfile (khuyên dùng)

Bước 1: Soạn Dockerfile

# Sử dụng base image OpenJDK
FROM eclipse-temurin:17-jre-alpine

# Thông tin bảo trì
LABEL maintainer="platform-team@company.com"

# Tham số build
ARG APP_VERSION=1.0.0
ARG BUILD_DATE

# Biến môi trường JVM
ENV JVM_OPTIONS="-XX:+UseG1GC -XX:MaxRAMPercentage=75.0 -XX:InitialRAMPercentage=50.0"
ENV SERVER_PORT=8080

# Thư mục làm việc
WORKDIR /opt/application

# Copy artifact vào container
COPY target/app-${APP_VERSION}.jar ./service.jar

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:${SERVER_PORT}/health || exit 1

# Expose port
EXPOSE ${SERVER_PORT}

# Khởi chạy ứng dụng
ENTRYPOINT ["sh", "-c", "java ${JVM_OPTIONS} -jar ./service.jar"]

Bước 2: Build và publish

# Build với tag đầy đủ
docker build \
  --build-arg APP_VERSION=2.5.0 \
  --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
  -t registry.example.com/backend/payment-service:2.5.0 \
  -f ./Dockerfile \
  .

# Kiểm tra image
docker run --rm -p 8080:8080 registry.example.com/backend/payment-service:2.5.0

# Đẩy lên registry
docker push registry.example.com/backend/payment-service:2.5.0

Vận hành container production

Khởi tạo container với đầy đủ tùy chọn

docker run -d \
  --name postgres-prod \
  --hostname db-primary \
  --restart unless-stopped \
  -p 5432:5432 \
  -e POSTGRES_USER=app_admin \
  -e POSTGRES_PASSWORD_FILE=/run/secrets/db_pass \
  -e PGDATA=/var/lib/postgresql/data/pgdata \
  -v /data/postgres/14/data:/var/lib/postgresql/data \
  -v /data/postgres/14/backups:/backups \
  -v /etc/localtime:/etc/localtime:ro \
  --memory=4g \
  --cpus=2.0 \
  --network backend-net \
  postgres:14-alpine

Kiểm tra cấu hình runtime

# Xem toàn bộ metadata
docker inspect postgres-prod | jq '.[0].NetworkSettings.Networks'

# Kiểm tra mount point
docker inspect postgres-prod -f '{{range .Mounts}}{{.Type}}: {{.Source}} -> {{.Destination}}{{println}}{{end}}'

# Theo dõi hiệu năng real-time
docker stats postgres-prod --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"

Lưu ý kết nối mạng

Khi hai container cần giao tiếp trên cùng host, không dùng hostIP:mappedPort mà sử dụng:

  • Tên container làm hostname (trong cùng custom network)
  • Địa chỉ IP nội bộ từ docker inspect
  • Docker DNS service discovery
# Tạo network riêng
docker network create app-network

# Chạy container trong network
docker run -d --name api --network app-network myapp:latest
docker run -d --name cache --network app-network redis:7-alpine

# Từ api container, truy cập cache qua: redis://cache:6379

Thẻ: docker containerization dockerfile nvidia-docker DevOps

Đăng vào ngày 14 tháng 8 lúc 18:13