Skip to content

Default helperPod image (busybox) hits Docker Hub anonymous pull rate limits (429) #569

@AAbiAbi

Description

@AAbiAbi

Problem

The default helperPod.yaml in the local-path-config ConfigMap hardcodes image: busybox without a registry prefix or pinned tag:

https://github.com/rancher/local-path-provisioner/blob/v0.0.26/deploy/local-path-storage.yaml#L131

helperPod.yaml: |-
    apiVersion: v1
    kind: Pod
    metadata:
      name: helper-pod
    spec:
      ...
      containers:
      - name: helper-pod
        image: busybox              # resolves to docker.io/library/busybox:latest
        imagePullPolicy: IfNotPresent

This resolves to docker.io/library/busybox:latest, which is subject to Docker Hub's anonymous pull rate limits (100 pulls / 6 hours / IP).

Impact

In environments with shared egress IPs (NAT'd datacenters, CI runners, corporate networks), the rate limit is easily exhausted. When this happens:

  1. Helper pods fail with ImagePullBackOff / ErrImagePull (HTTP 429)
  2. PV directories are never created on the node
  3. PVCs remain stuck in Pending indefinitely
  4. All workloads depending on local-path StorageClass (e.g. Redis, Prometheus, Mimir, Loki) cannot start

This is especially problematic during fresh cluster deployments where multiple PVCs are created simultaneously — each triggering a separate helper pod on potentially different nodes, all pulling busybox from Docker Hub concurrently.

Observed Error

Events:
  Type     Reason   Age   From     Message
  ----     ------   ----  ----     -------
  Normal   Pulling  25s   kubelet  Pulling image "busybox"
  Warning  Failed   25s   kubelet  Failed to pull image "busybox": rpc error: code = Unknown desc = failed to pull and unpack image "docker.io/library/busybox:latest": ... toomanyrequests: You have reached your pull rate limit.
  Warning  Failed   25s   kubelet  Error: ErrImagePull

Suggested Fix

Replace the default helper image with one from a registry that has no anonymous pull rate limits, for example:

image: registry.k8s.io/e2e-test-images/busybox:1.36.1-1

Or alternatively:

image: ghcr.io/rancher/busybox:latest

Benefits:

  • registry.k8s.io has no pull rate limits and is already trusted by kubeadm/k3s clusters
  • Pinning a version tag instead of relying on latest improves reproducibility

Workaround

kubectl patch configmap local-path-config -n local-path-storage --type merge -p '{
  "data": {
    "helperPod.yaml": "apiVersion: v1\nkind: Pod\nmetadata:\n  name: helper-pod\nspec:\n  priorityClassName: system-node-critical\n  tolerations:\n    - key: node.kubernetes.io/disk-pressure\n      operator: Exists\n      effect: NoSchedule\n  containers:\n    - name: helper-pod\n      image: registry.k8s.io/e2e-test-images/busybox:1.36.1-1\n      imagePullPolicy: IfNotPresent\n"
  }
}'

Environment

  • local-path-provisioner v0.0.26
  • Kubernetes 1.33.0 (kubeadm)
  • Nodes behind shared NAT (3-node cluster, all sharing one egress IP)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions