Điều khiển tài nguyên CPU và bộ nhớ cho container Docker

Docker cung cấp nhiều cơ chế để giới hạn và phân bổ tài nguyên hệ thống cho container, giúp đảm bảo hiệu năng ổn định và tránh xung đột giữa các workload.

Phân bổ lõi CPU cụ thể

Bạn có thể ràng buộc container chỉ chạy trên một tập hợp lõi CPU nhất định bằng tham số --cpuset-cpus. Cú pháp hỗ trợ cả danh sách rời rạc và khoảng liên tục:

$ docker run -it --cpuset-cpus="2,4" alpine:latest sh

→ Các tiến trình trong container chỉ được thực thi trên lõi CPU thứ 2 và thứ 4.

$ docker run -it --cpuset-cpus="0-3" alpine:latest sh

→ Container được phép sử dụng bốn lõi đầu tiên: 0, 1, 2 và 3.

Hạn chế vùng nhớ NUMA

Trên hệ thống đa node NUMA, bạn có thể kiểm soát node bộ nhớ mà container được phép truy cập qua --cpuset-mems:

$ docker run -it --cpuset-mems="0" nginx:alpine

→ Container chỉ dùng RAM từ node NUMA 0 — hữu ích khi tối ưu độ trễ truy cập bộ nhớ gần (local memory access).

$ docker run -it --cpuset-mems="0-1" redis:7-alpine

→ Cho phép sử dụng bộ nhớ từ hai node đầu tiên, tăng tính linh hoạt trong môi trường NUMA cân bằng.

Giới hạn thời gian CPU theo cơ chế CFS

Linux sử dụng trình lập lịch CFS (Completely Fair Scheduler) với chu kỳ mặc định 100ms. Docker cho phép tinh chỉnh chính xác thời gian CPU dành riêng cho mỗi container thông qua hai tham số:

  • --cpu-period: chu kỳ lập lịch (đơn vị microsecond, giá trị hợp lệ từ 1000–1000000 → tương ứng 1ms–1s)
  • --cpu-quota: lượng thời gian CPU tối đa được phép sử dụng trong mỗi chu kỳ (đơn vị microsecond, tối thiểu 1000)
$ docker run -d --name cpu-limited \
  --cpu-period=25000 \
  --cpu-quota=12500 \
  ubuntu:22.04 tail -f /dev/null

→ Mỗi 25ms, container được cấp tối đa 12.5ms CPU → chiếm ~50% sức mạnh của một lõi vật lý.

$ docker run -d --name double-vcpu \
  --cpu-period=10000 \
  --cpu-quota=20000 \
  ubuntu:22.04 tail -f /dev/null

→ Với quota gấp đôi period, container có thể tiêu thụ toàn bộ thời gian của hai luồng CPU song song — tương đương 2 vCPU ở mức 100%.

Tương tác giữa trọng số chia sẻ CPU và giới hạn tuyệt đối

Khi nhiều container cạnh tranh cùng một tài nguyên CPU bị giới hạn, trọng số --cpu-shares (mặc định là 1024) quyết định tỷ lệ phân bổ thời gian trong phạm vi giới hạn chung.

Ví dụ: Hai container cùng bị giới hạn bởi --cpu-period=50000 --cpu-quota=50000, nhưng có trọng số khác nhau:

# Container A (mặc định)
$ docker run -d --name worker-a --cpu-period=50000 --cpu-quota=50000 ubuntu:22.04 stress-ng --cpu 1

# Container B (ưu tiên cao hơn)
$ docker run -d --name worker-b --cpu-period=50000 --cpu-quota=50000 --cpu-shares=2048 ubuntu:22.04 stress-ng --cpu 1

Kết quả quan sát qua docker stats sẽ cho thấy worker-b chiếm khoảng 66% tổng thời gian CPU khả dụng trong chu kỳ, còn worker-a chiếm ~33% — phản ánh đúng tỷ lệ trọng số 2048 : 1024 = 2 : 1.

Thẻ: docker cfs NUMA cpu-quota cpuset

Đăng vào ngày 1 tháng 7 lúc 16:11