K8S 镜像拉取 之 toomanyrequests 的解决方法

摘要

  • 本文介绍 K8S 镜像拉取 的 toomanyrequests 的解决方法 ,本文以 CentOS 8 为例。

  • K8S官网

  • k8s Github

toomanyrequests 介绍

  • 当我们通过k8s创建pod时需要从 dockerhub 上拉取镜像,但是 dockerhub 的api请求是有限制的,未认证用户限制为100/6h,如果超过这个限制就会返回429 Too Many Requests响应Docker Hub的使用和限制

  • 我们可以进行用户认证,这样可以将限制提高到2000/6h。如果还需要进一步提高请求限制,可以申请dockerhub的pro plan。

dockerhub 认证

  • 创建 Docker Registry Secret

1
2
3
4
5
6
7
8
9
10
# 指定 namespace, 默认命名空间是 default
kubectl create secret docker-registry dockerhub-secret \
--namespace=你的命名空间 \
--docker-server=https://index.docker.io/v1/ \
--docker-username=你的用户名 \
--docker-password=你的密码或访问令牌 \
--docker-email=你的邮箱

# 查看 secret
kubectl get secret dockerhub-secret -o yaml -n <namespace>
  • 可以在创建 pod 或 deployment 时指定凭证

pod

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: myapp
image: username/repository:tag
imagePullSecrets: # 添加凭证
- name: dockerhub-secret

deployment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: username/repository:tag
imagePullSecrets: # 添加凭证
- name: dockerhub-secret
  • 将 Secret 添加到 ServiceAccount,这样 Pod 创建的时候,会自动将 Secret 挂载到 Pod 中

每个 namespace 下 都有一个 名称为 default 的 ServiceAccount

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 查看 pod 的 ServiceAccount
$ k describe pod pi-n65gn | grep "Service Account"
Service Account: default

# 指定 namespace 下的 Pod 使用这个凭证
kubectl patch serviceaccount -n <namespace> default -p '{"imagePullSecrets": [{"name": "dockerhub-secret"}]}'

# 为所有 namespace 下的 Pod 添加凭证
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
kubectl patch serviceaccount default -n $ns \
--type=merge \
-p '{"imagePullSecrets": [{"name": "dockerhub-secret"}]}'
done

# 查看 ServiceAccount
$ kubectl get serviceaccount default -o yaml -n <namespace>
apiVersion: v1
imagePullSecrets:
- name: dockerhub-secret
kind: ServiceAccount
metadata:
creationTimestamp: "2025-06-29T14:41:35Z"
name: default
namespace: default
resourceVersion: "361001"
uid: cb3a0f99-5804-4f21-816a-70533cc3d29d

提高下载频率的其他建议

  • 1.使用镜像缓存:

    • 设置集群内镜像缓存(如 Harbor, Nexus Registry)
    1
    2
    3
    # 修改集群的镜像仓库配置(vim)
    kubectl edit configmap -n kube-system
    # 找到 imageRepository: 替换为你的仓库地址
    • 使用 Docker Hub 镜像加速器(如果在中国大陆)
  • 2.升级 Docker Hub 订阅:

    • 免费账户:200 pulls/6小时(匿名用户100 pulls/6小时)
    • Pro/Team 账户:无限制拉取
  • 3.使用多个账户:

    • 为不同节点配置不同的 Docker Hub 凭证
  • 4.减少不必要的拉取:

    • 使用 imagePullPolicy: IfNotPresent
    • 尽量使用固定版本标签而非 latest