[{"data":1,"prerenderedAt":424},["ShallowReactive",2],{"blog-en-k3s-harbor-private-registry-docker-hub-rate-limit":3,"blog-related-en-k3s-harbor-private-registry-docker-hub-rate-limit":365,"blog-en-k3s-harbor-private-registry-docker-hub-rate-limit-alt":354},{"id":4,"title":5,"author":6,"body":7,"date":349,"description":350,"extension":351,"image":177,"locale":352,"meta":353,"navigation":354,"path":355,"seo":356,"stem":357,"tags":358,"__hash__":364},"blog\u002Fblog\u002Fen\u002Fk3s-harbor-private-registry-docker-hub-rate-limit.md","Our CI Died at Midnight from Docker Hub's Pull Rate Limit. Designing a Harbor Private Registry for K3s\u002FKubo","Kubo Team",{"type":8,"value":9,"toc":334},"minimark",[10,15,23,26,37,40,49,58,62,68,77,80,109,117,126,129,133,139,148,163,172,179,183,189,210,219,224,227,231,234,238,241,248,252,258,267,270,290,299,302,311,315,318,321],[11,12,14],"h2",{"id":13},"_1-the-night-our-ci-died-docker-hubs-pull-limit-an-invisible-dependency","1. The Night Our CI Died — Docker Hub's Pull Limit, an Invisible Dependency",[16,17,18],"p",{},[19,20],"img",{"alt":21,"src":22},"section01","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fk3s-harbor-private-registry-docker-hub-rate-limit\u002Fsection01.webp",[16,24,25],{},"Late on a Friday night, right before a release, the CI pipeline suddenly went red. The error: \"toomanyrequests.\" Everything had worked fine locally — it only failed the moment we tried to deploy to a production-equivalent K3s cluster.",[16,27,28,29,36],{},"The culprit was Docker Hub's pull rate limit. According to Docker's official documentation, anonymous pulls are ",[30,31,35],"a",{"href":32,"rel":33},"https:\u002F\u002Fdocs.docker.com\u002Fdocker-hub\u002Fusage\u002Fpulls\u002F",[34],"nofollow","limited to 100 per 6 hours per IPv4 address or IPv6 \u002F64 subnet",". Even authenticated free accounts are capped at 200 per 6 hours.",[16,38,39],{},"A K3s cluster has multiple worker nodes. When CI builds scale and a large volume of concurrent pulls all come through the same NAT gateway — the same global IP — that ceiling gets hit surprisingly fast. And this limit doesn't fire because production traffic actually increased; it fires simply because the requests \"come from the same IP.\" Nobody did anything wrong, yet one day, deployment just stops. This is the invisible dependency that nearly every K3s operations team trips over at least once.",[16,41,42,43,48],{},"Dealing with this kind of invisible dependency is really part of a broader question about how you design K3s cluster operations overall. Whether you choose a managed K3s environment like ",[30,44,47],{"href":45,"rel":46},"https:\u002F\u002Fkubo.hexabase.io\u002F",[34],"Kubo",", for instance, comes down to a design decision about how much of this operational burden you want to take on yourselves.",[16,50,51,52,57],{},"There are broadly two ways to address this problem: move to an authenticated paid plan, or route through your own private registry to reduce direct traffic to Docker Hub in the first place. At the center of the latter approach sits ",[30,53,56],{"href":54,"rel":55},"https:\u002F\u002Fgoharbor.io\u002F",[34],"Harbor",", a CNCF Graduated project.",[11,59,61],{"id":60},"_2-what-harbor-actually-is-more-than-just-a-private-registry","2. What Harbor Actually Is — More Than \"Just a Private Registry\"",[16,63,64],{},[19,65],{"alt":66,"src":67},"section02","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fk3s-harbor-private-registry-docker-hub-rate-limit\u002Fsection02.webp",[16,69,70,71,76],{},"Harbor joined CNCF in 2018 and reached Graduated status in 2020, making it an ",[30,72,75],{"href":73,"rel":74},"https:\u002F\u002Fwww.cncf.io\u002Fblog\u002F2025\u002F12\u002F08\u002Fharbor-enterprise-grade-container-registry-for-modern-private-cloud\u002F",[34],"enterprise-grade container registry project",". It isn't simply \"a self-hosted Docker Hub.\"",[16,78,79],{},"According to its official positioning, Harbor's core capabilities fall into four categories:",[81,82,83,91,97,103],"ul",{},[84,85,86,90],"li",{},[87,88,89],"strong",{},"Security",": image vulnerability scanning, content trust verification, and project-level role-based access control (RBAC)",[84,92,93,96],{},[87,94,95],{},"Replication",": replicating images across multiple Harbor instances for disaster recovery and distributing content to multiple clusters",[84,98,99,102],{},[87,100,101],{},"Extensibility",": LDAP\u002FAD authentication integration, support for multiple storage backends",[84,104,105,108],{},[87,106,107],{},"Manageability",": a user-friendly UI for managing projects, users, and images",[16,110,111,116],{},[30,112,115],{"href":113,"rel":114},"https:\u002F\u002Ftrivy.dev\u002F",[34],"Trivy"," is commonly built in for vulnerability scanning. Trivy is a single-binary scanner that handles CVE detection, Infrastructure-as-Code misconfiguration detection, SBOM generation, and secret scanning — the Harbor team itself has praised it for raising the bar on \"both usability and performance.\"",[16,118,119,120,125],{},"For signature verification, ",[30,121,124],{"href":122,"rel":123},"https:\u002F\u002Fdocs.sigstore.dev\u002Fquickstart\u002Fquickstart-cosign\u002F",[34],"Cosign"," is available. Cosign issues short-lived certificates via OIDC from Sigstore's certificate authority (Fulcio), enabling \"keyless signing\" with no key management required. Signing and verification records are stored in a transparency log called Rekor, so you can later trace exactly who signed which image and when.",[16,127,128],{},"In other words, adopting Harbor means more than just \"dodging the pull rate limit.\" It's a decision to bring the mechanism that guarantees the provenance and safety of your images under your own control.",[11,130,132],{"id":131},"_3-solving-the-pull-limit-by-design-with-harbor-proxy-cache","3. Solving the Pull Limit \"By Design\" with Harbor Proxy Cache",[16,134,135],{},[19,136],{"alt":137,"src":138},"section03","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fk3s-harbor-private-registry-docker-hub-rate-limit\u002Fsection03.webp",[16,140,141,142,147],{},"Since v2.1, Harbor has shipped a ",[30,143,146],{"href":144,"rel":145},"https:\u002F\u002Fgoharbor.io\u002Fblog\u002Fharbor-2.1\u002F",[34],"Proxy Cache (pull-through cache) feature",". The mechanism is simple:",[149,150,151,154,157,160],"ol",{},[84,152,153],{},"A K3s node pulls an image through Harbor.",[84,155,156],{},"Harbor first checks its cache and compares it against the latest manifest on the target registry.",[84,158,159],{},"If the image hasn't changed, it's served immediately from the cache.",[84,161,162],{},"If it has changed, only the new image gets pulled and the cache is updated.",[16,164,165,166,171],{},"The key detail is how the update check works. According to ",[30,167,170],{"href":168,"rel":169},"https:\u002F\u002Fgoharbor.io\u002Fdocs\u002F2.1.0\u002Fadministration\u002Fconfigure-proxy-cache\u002F",[34],"Harbor's official documentation",", Proxy Cache since v2.1.1 checks for layer updates using HEAD requests, and this check itself is designed not to trigger Docker Hub's rate limit. That means only actual new-image pulls count against the limit, dramatically cutting down on wasted pull requests.",[16,173,174,175],{},"Setup is just a matter of enabling \"Proxy Cache\" when creating a project and specifying the target registry endpoint (e.g. Docker Hub). Existing manifests or `image: ",[30,176,177],{"href":177,"rel":178},"https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fk3s-harbor-private-registry-docker-hub-rate-limit\u002Feyecatch.webp",[34],[11,180,182],{"id":181},"_4-implementation-design-for-k3skubo-clusters-and-production-operations","4. Implementation Design for K3s\u002FKubo Clusters and Production Operations",[16,184,185],{},[19,186],{"alt":187,"src":188},"section04","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fk3s-harbor-private-registry-docker-hub-rate-limit\u002Fsection04.webp",[16,190,191,192,197,198,202,203,206,207,209],{},"When actually wiring Harbor into a K3s\u002FKubo cluster, the Pod-side configuration is a standard procedure straight from ",[30,193,196],{"href":194,"rel":195},"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Ftasks\u002Fconfigure-pod-container\u002Fpull-image-private-registry",[34],"Kubernetes' official documentation",". You create registry credentials as an ",[199,200,201],"code",{},"imagePullSecrets"," object with ",[199,204,205],{},"kubectl create secret docker-registry",", then reference it in your Pod manifest's ",[199,208,201],{}," field. That's it.",[16,211,212,213,218],{},"Running Harbor itself at production quality, on the other hand, takes more design work than a single-instance install. ",[30,214,217],{"href":215,"rel":216},"https:\u002F\u002Fwww.cncf.io\u002Fblog\u002F2026\u002F02\u002F24\u002Fmaking-harbor-production-ready-essential-considerations-for-deployment\u002F",[34],"CNCF's guide to making Harbor production-ready"," calls out at least the following considerations.",[220,221,223],"h3",{"id":222},"high-availability-and-the-data-layer","High availability and the data layer",[16,225,226],{},"Run Harbor's core, jobservice, portal, and registry components across multiple replicas so there's no single point of failure. It's recommended to move off the bundled PostgreSQL\u002FRedis and onto an externally managed, highly available setup.",[220,228,230],{"id":229},"security-and-monitoring","Security and monitoring",[16,232,233],{},"Enable TLS for internal communication as well, and centralize authentication via LDAP\u002FOIDC. Build Trivy vulnerability scanning and Cosign\u002FNotation signature verification into your operational workflow, monitor metrics with Prometheus\u002FGrafana, and use an aggregated logging platform to catch early signs of trouble.",[220,235,237],{"id":236},"storage-and-backups","Storage and backups",[16,239,240],{},"Beyond picking the right StorageClass and planning capacity, you need backup operations paired with regular recovery testing. Don't forget periodic garbage collection to remove unreferenced blobs.",[16,242,243,244,247],{},"All of this means Harbor can't be treated as \"install it and you're done\" — it needs to be brought into your operational scope at the same level as other cluster components like monitoring and certificate management. With a managed K3s environment like ",[30,245,47],{"href":45,"rel":246},[34],", where Prometheus + Grafana monitoring and cert-manager + Let's Encrypt certificate automation come standard, part of the extra monitoring and certificate layer that Harbor operations demand can be covered by the cluster's built-in capabilities.",[11,249,251],{"id":250},"_5-when-you-actually-need-a-self-hosted-harbor-vs-managed-registries","5. When You Actually Need a Self-Hosted Harbor — vs. Managed Registries",[16,253,254],{},[19,255],{"alt":256,"src":257},"section05","https:\u002F\u002Fcdn.kubo.hexabase.io\u002Fimages\u002Fblog\u002Fk3s-harbor-private-registry-docker-hub-rate-limit\u002Fsection05.webp",[16,259,260,261,266],{},"Of course, not every team should run Harbor themselves. A cloud-managed registry like ",[30,262,265],{"href":263,"rel":264},"https:\u002F\u002Faws.amazon.com\u002Fecr\u002Fpricing\u002F",[34],"Amazon ECR"," — with free data transfer to AWS services in the same region, for example — carries a far lower operational burden if you're staying within a single cloud.",[16,268,269],{},"Running your own Harbor pays off when:",[81,271,272,278,284],{},[84,273,274,277],{},[87,275,276],{},"Multi-cloud\u002Fedge deployment",": you want to distribute the same images consistently across cloud and on-prem\u002Fedge K3s clusters",[84,279,280,283],{},[87,281,282],{},"Data sovereignty requirements",": your industry (finance, healthcare, etc.) can't have container images sitting with an external cloud vendor",[84,285,286,289],{},[87,287,288],{},"Unified scanning\u002Fsigning policy",": you want to enforce the same Trivy\u002FCosign policies across multiple clouds' managed registries",[16,291,292,293,298],{},"For environments with especially strict data sovereignty requirements, an option like ",[30,294,297],{"href":295,"rel":296},"https:\u002F\u002Fwww.hexabase.com\u002Fproduct\u002Fkubo\u002Fon-premise",[34],"Kubo On-Premise"," — which delivers fully managed K8s operations on your own infrastructure — is worth considering.",[16,300,301],{},"Conversely, if you're operating within a single cloud and a single cluster with no special compliance requirements, staying on a managed registry is often just fine. Harbor isn't a magic wand that always pays off — adopting it means accepting a trade-off between operational burden and control.",[16,303,304,305,310],{},"If you want to revisit your overall vulnerability scanning and signing policy for container images, our ",[30,306,309],{"href":307,"rel":308},"https:\u002F\u002Fkubo.hexabase.io\u002Fblog\u002Fja\u002Fk3s-container-image-security-supply-chain-checklist",[34],"article on container image security from signing through admission control"," is a good companion read.",[11,312,314],{"id":313},"_6-summary","6. Summary",[16,316,317],{},"Docker Hub's pull rate limit goes unnoticed while a K3s cluster is still small. But as CI build frequency rises and node counts grow, this invisible dependency inevitably surfaces.",[16,319,320],{},"Running Harbor as a private registry isn't just a rate-limit workaround. On top of adding a caching layer via Proxy Cache, it's a design decision spanning your entire container supply chain — vulnerability scanning, signature verification, and replication. And operating it comes with added responsibilities: monitoring, certificate management, and backups.",[16,322,323,324,327,328,333],{},"You don't have to keep wrestling with EKS\u002FAKS's high costs, complexity, and lock-in. With K3s-based ",[30,325,47],{"href":45,"rel":326},[34],", you get the full power of real Kubernetes while offloading part of that operational layer to built-in standard features — running production clusters at dramatically better cost efficiency. If you want to rethink your entire infrastructure design, registry operations included, feel free to reach out via our ",[30,329,332],{"href":330,"rel":331},"https:\u002F\u002Fwww.hexabase.com\u002Fcontact-us\u002F",[34],"contact page",".",{"title":335,"searchDepth":336,"depth":336,"links":337},"",2,[338,339,340,341,347,348],{"id":13,"depth":336,"text":14},{"id":60,"depth":336,"text":61},{"id":131,"depth":336,"text":132},{"id":181,"depth":336,"text":182,"children":342},[343,345,346],{"id":222,"depth":344,"text":223},3,{"id":229,"depth":344,"text":230},{"id":236,"depth":344,"text":237},{"id":250,"depth":336,"text":251},{"id":313,"depth":336,"text":314},"2026-09-08","Ever had a K3s cluster blocked by Docker Hub's pull rate limit? Here's how a Harbor private registry with Proxy Cache dodges the limit, plus vulnerability scanning, signing, and production-grade operational design.","md","en",{},true,"\u002Fblog\u002Fen\u002Fk3s-harbor-private-registry-docker-hub-rate-limit",{"title":5,"description":350},"blog\u002Fen\u002Fk3s-harbor-private-registry-docker-hub-rate-limit",[359,360,361,362,363],"k3s","kubernetes","harbor","container-registry","private-registry","ivBlATf1Npv7QMiZLmcFsHUu-U1JIkVA5Nke9EGqvvw",[366,374,384,395,404,414],{"path":367,"title":368,"description":369,"date":370,"tags":371},"\u002Fblog\u002Fen\u002Fcncf-project-maturity-graduation-criteria-production","10,000 GitHub Stars Isn't a Diploma. Why the Real Criterion for Choosing a CNCF Project Isn't Commit Count but Maturity Stage","When adopting CNCF projects for your Kubernetes stack, are you judging them by GitHub stars and name recognition alone? Learn the Sandbox\u002FIncubating\u002FGraduated maturity framework and the Harbor case study to know what to check before production.","2026-08-19",[359,360,372,373,362],"cncf","oss-governance",{"path":375,"title":376,"description":377,"date":378,"tags":379},"\u002Fblog\u002Fen\u002Fcontainer-registry-harbor-setup","Building a Private Container Registry with Harbor","Complete guide to deploying and operating Harbor as your private container registry. Covers Trivy integration, RBAC, image replication, Helm deployment, and enterprise security features.","2026-05-27",[361,362,380,360,381,382,383],"docker","security","trivy","rbac",{"path":385,"title":386,"description":387,"date":388,"tags":389},"\u002Fblog\u002Fen\u002Fk3s-local-path-provisioner-capacity-node-affinity-pvc-pending","Your K3s Pod Won't Leave Pending. The 'Ignored Capacity' and Node Affinity Trap in Local Storage","A K3s PVC stuck in Pending often traces back to one fact: local-path-provisioner never enforces capacity limits. This post digs into hypervisor thin provisioning, Volume Node Affinity Conflicts, and the backup misconceptions hiding in K3s local storage design.","2026-09-12",[359,360,390,391,392,393,394],"storage","local-path-provisioner","persistent-volume","node-affinity","zfs",{"path":396,"title":397,"description":398,"date":399,"tags":400},"\u002Fblog\u002Fen\u002Fk3s-keda-vs-hpa-event-driven-autoscaling-decision","KEDA vs HPA on K3s: A Decision Framework for Event-Driven Autoscaling","When CPU\u002Fmemory-based HPA on K3s can't keep up with event-driven workloads, should you extend HPA or adopt KEDA, the CNCF-graduated project? Here's a 3-point decision framework, plus what to watch for on K3s.","2026-09-10",[359,360,401,402,403],"hpa","keda","autoscaling",{"path":405,"title":406,"description":407,"date":408,"tags":409},"\u002Fblog\u002Fen\u002Fk3s-proxmox-live-migration-etcd-quorum-affinity-design","Proxmox Live Migration Quietly Breaks K3s etcd Quorum: When Virtualization Collides with Raft","A deep dive into how live-migrating a K3s control plane VM on Proxmox can break etcd quorum, explained through heartbeat\u002Felection-timeout mechanics and Proxmox affinity design, with concrete operational countermeasures.","2026-09-09",[359,360,410,411,412,413],"proxmox","etcd","live-migration","high-availability",{"path":415,"title":416,"description":417,"date":418,"tags":419},"\u002Fblog\u002Fen\u002Faks-cost-optimization-fixed-cost-structure-k3s-comparison","You Optimized AKS Costs to the Letter. So Why Won't the Bill Move?","Right-sizing nodes and adopting Spot VMs on AKS often plateaus because LoadBalancer-per-service billing and monitoring add-ons are structural fixed costs that operational tuning can't touch. We break down the real bottleneck and compare it to K3s's lightweight cost structure.","2026-09-07",[359,360,420,421,422,423],"aks","azure","cost-optimization","managed-kubernetes",1792488903061]