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:
- Helper pods fail with
ImagePullBackOff / ErrImagePull (HTTP 429)
- PV directories are never created on the node
- PVCs remain stuck in
Pending indefinitely
- 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)
Problem
The default
helperPod.yamlin thelocal-path-configConfigMap hardcodesimage: busyboxwithout a registry prefix or pinned tag:https://github.com/rancher/local-path-provisioner/blob/v0.0.26/deploy/local-path-storage.yaml#L131
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:
ImagePullBackOff/ErrImagePull(HTTP 429)Pendingindefinitelylocal-pathStorageClass (e.g. Redis, Prometheus, Mimir, Loki) cannot startThis 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
busyboxfrom Docker Hub concurrently.Observed Error
Suggested Fix
Replace the default helper image with one from a registry that has no anonymous pull rate limits, for example:
Or alternatively:
Benefits:
registry.k8s.iohas no pull rate limits and is already trusted by kubeadm/k3s clusterslatestimproves reproducibilityWorkaround
Environment