LỗiNó thường xảy ra vào thời điểm tồi tệ nhất có thể. Hệ thống CI/CD của bạn đang hoạt động trơn tru, và rồi một bản build thất bại với mã trạng thái 429. Docker engine từ chối pull image cơ sở của bạn và đưa ra thông báo cụ thể này:
toomanyrequests: You have reached your pull rate limit.
Tại sao điều này lại xảy raDocker Hub không phải là một kho băng thông miễn phí vô tận. Từ cuối năm 2020, Docker đã áp dụng các giới hạn nghiêm ngặt để quản lý chi phí. Nếu bạn pull image mà không đăng nhập, Docker sẽ theo dõi địa chỉ IP của bạn. Nếu bạn đã đăng nhập, nó sẽ theo dõi tài khoản cụ thể của bạn.
- Người dùng ẩn danh: 100 lần pull mỗi 6 giờ (theo dõi qua IP).- Người dùng miễn phí đã xác thực: 200 lần pull mỗi 6 giờ.- Tài khoản Pro/Team/Business: 5.000 lần pull mỗi ngày hoặc không giới hạn.Các môi trường dùng chung gây ra nhiều vấn đề nhất. Trong một văn phòng lớn hoặc một VPC đám mây, hàng chục lập trình viên thường dùng chung một địa chỉ IP NAT duy nhất. Điều này có nghĩa là việc kiểm thử cục bộ của một người có thể làm cạn kiệt giới hạn pull của toàn bộ đội ngũ kỹ thuật.
Giải pháp 1: Xác thực Docker CLI của bạnCách khắc phục nhanh nhất là đăng nhập. Ngay cả một tài khoản miễn phí cũng giúp tăng gấp đôi giới hạn của bạn từ 100 lên 200 lần pull. Quan trọng hơn, giới hạn này sẽ gắn liền với tên người dùng của bạn thay vì địa chỉ IP chung của văn phòng.
# Đăng nhập trên máy cục bộ hoặc máy chủ của bạn
docker login --username your_dockerhub_username
Tránh sử dụng mật khẩu chính của bạn trong các hệ thống CI/CD. Thay vào đó, hãy tạo một Personal Access Token (PAT) trong Docker Hub tại mục Account Settings > Security. Sử dụng token này như một biến bí mật (secret variable) trong các script tự động hóa của bạn.
Ví dụ với GitHub Actions:```
- name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }}
## Giải pháp 2: Thiết lập Pull-Through CacheNếu bạn quản lý một cụm Kubernetes hoặc một hệ thống build lớn, việc pull từ Docker Hub mỗi lần là rất kém hiệu quả. Một registry mirror cục bộ, như Harbor hoặc Sonatype Nexus, sẽ lưu tạm (cache) các image tại chỗ. Yêu cầu đầu tiên sẽ pull từ Docker Hub, nhưng mọi yêu cầu sau đó sẽ nằm trong mạng nội bộ của bạn.
Để cấu hình một mirror, hãy chỉnh sửa tệp `/etc/docker/daemon.json` trên máy chủ Linux của bạn:
{ "registry-mirrors": ["https://"] }
Áp dụng các thay đổi bằng cách khởi động lại dịch vụ Docker:
sudo systemctl restart docker
## Giải pháp 3: Chuyển sang các Registry thay thếNhiều image chính thức được sao lưu trên các registry có giới hạn cao hơn hoặc các gói miễn phí cho người dùng đám mây. Việc thay đổi dòng `FROM` trong Dockerfile có thể bỏ qua hoàn toàn Docker Hub.
- **GitHub Container Registry:** `ghcr.io/owner/image:tag`- **Google Artifact Registry:** `mirror.gcr.io/library/image:tag`- **Amazon ECR Public Gallery:** `public.ecr.aws/docker/library/image:tag`Ví dụ, hãy pull image Python chính thức từ AWS để tránh chạm ngưỡng giới hạn của Hub:
Thay vì: FROM python:3.11
FROM public.ecr.aws/docker/library/python:3.11
## Giải pháp 4: Khắc phục lỗi ImagePullBackOff trong KubernetesCác pod của Kubernetes thường bị kẹt ở trạng thái `ImagePullBackOff` khi các node chạm giới hạn số lần pull. Bạn có thể khắc phục điều này bằng cách tạo một đối tượng `imagePullSecrets`. Thông tin xác thực này cho phép K8s tự định danh với Docker Hub.
1. Tạo secret trong namespace của bạn
kubectl create secret docker-registry dockerhub-creds
--docker-username=YOUR_USER
--docker-password=YOUR_PAT_TOKEN
--docker-email=YOUR_EMAIL
2. Tham chiếu secret trong file deployment.yaml của bạn
spec: template: spec: containers: - name: my-app image: nginx:1.25 imagePullSecrets: - name: dockerhub-creds
## Cách kiểm tra giới hạn còn lại của bạnBạn không cần phải đoán xem mình còn bao nhiêu lượt pull. Sử dụng `curl` để yêu cầu một token và kiểm tra các header của phản hồi. Điều này xác nhận xem việc xác thực của bạn có đang hoạt động chính xác hay không.
Lấy token cho dịch vụ giới hạn lưu lượng (rate limit)
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)
Kiểm tra các header của giới hạn lưu lượng
curl -I -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest
Kiểm tra các dòng cụ thể sau trong kết quả đầu ra của terminal:
ratelimit-limit: 200;w=21600 ratelimit-remaining: 185;w=21600
Dòng `w=21600` đại diện cho khoảng thời gian 6 giờ tính bằng giây. Nếu `ratelimit-limit` hiển thị 200 hoặc 5000, nghĩa là việc xác thực của bạn đã có hiệu lực.
## Các thực hành tốt nhất cho môi trường Production- **Chốt phiên bản (Pin versions):** Ngừng sử dụng tag `:latest`. Nó buộc Docker phải kiểm tra các bản cập nhật trên registry mỗi lần, làm lãng phí hạn ngạch pull của bạn.- **Nội bộ hóa các phụ thuộc:** Đối với các ứng dụng quan trọng, hãy sao chép các image công khai vào kho lưu trữ ECR hoặc GCR riêng của bạn. Điều này bảo vệ bạn nếu Docker Hub gặp sự cố hoặc thay đổi chính sách giá.- **Bộ nhớ đệm lớp (Layer Caching):** Cấu hình nhà cung cấp CI của bạn để cache các layer của Docker. Điều này giúp tránh việc tải lại các image cơ sở mỗi khi có commit mới.

