Skip to main content

Docker Hubの無料枠が凍りついた朝、K3sクラスタは静かに詰む。Harborを自前で持つべきタイミング

1. Docker Hubのレート制限は「もう他人事」ではない

section01

朝、オートスケールで増えたはずのK3sワーカーノードが、いつまで経ってもRunning状態にならない。kubectl describe pod を叩くと、原因は ImagePullBackOff429 Too Many Requests だった——これは特殊な事故ではなく、Docker HubのHarbor container registry(自前運用のコンテナレジストリ)を検討すべきタイミングを知らせるシグナルだ。

Docker公式ドキュメントによると、Docker Hubの無料枠は「未認証ユーザー: 6時間あたり100pull」「無料認証ユーザー: 6時間あたり200pull」という枠で運用されている。問題は、この制限がIPv4アドレスまたはIPv6 /64サブネット単位でカウントされることだ。

社内ネットワークやクラウドのNAT Gateway配下では、複数の開発者・CI runner・K3sノードが同じパブリックIPを共有しているケースが珍しくない。oneuptimeの解説記事が指摘する通り、忙しいCIパイプラインだけで数分のうちにこの100pullの枠を使い切ってしまい、後から来たK3sノードのpullが 429 で弾かれる。オートスケールでノードを増やした瞬間にデプロイが止まる、というのはこの構造的な欠陥が引き起こす典型的な障害パターンだ。

2. なぜ「キャッシュを挟む」だけでは足りないのか

section02

この問題への第一の答えとして「pull-throughキャッシュを挟む」がよく挙げられる。container-registry.comの解説にある通り、一度取得したイメージをキャッシュ側に保存しておけば、同じイメージの再pullはDocker Hubを経由せずに済み、レート制限を実質的に回避できる。K3sであれば、registries.yamlmirrors 設定でDocker Hubへのリクエストをキャッシュ経由にルーティングするだけで導入できる手軽さもある。

ただし、キャッシュはあくまで「Docker Hubへの依存を減らす」ための緩和策であり、次の3つの課題には答えてくれない。

  • 可用性: キャッシュサーバー自体が単一障害点になり、キャッシュが落ちればDocker Hub直叩きに逆戻りする
  • 脆弱性スキャン: キャッシュされたイメージにCVEが含まれていないかを継続的に検査する仕組みがない
  • 来歴管理: 誰がどのイメージをいつビルドし、どこにデプロイしたかを追跡できない

つまり、「pullできない」という症状だけを止血する段階と、「本番で使うイメージの品質と出所を管理する」段階は別の問題であり、後者に踏み込むなら自前のコンテナレジストリが必要になる。この線引きは、突き詰めれば「K3s運用のどこまでを自分たちで背負うか」という設計判断でもある。KuboのようなマネージドK3s環境を選ぶ場合、この判断自体をクラスタ運用の一部としてベンダー側に委ねる選択肢も生まれる。

3. HarborをK3s/Kubernetesで動かすときに効いてくる設計判断

section03

ここで候補に上がるのが、Harbor(Harborコンテナレジストリ)だ。CNCFのプロジェクトページによれば、Harborは2018年にCNCFへ加入し、2020年6月にGraduatedステータスへ昇格した、CNCFの中でも成熟度の高いプロジェクトの一つとされている。

Harbor公式サイトが挙げる中核機能は、コンテンツの保存・署名・スキャンの3つだ。具体的には、脆弱性スキャン、コンテンツ署名と検証、マルチテナント対応のRBAC、そしてHarbor自身を含む複数レジストリ間のレプリケーション機能が標準で組み込まれている。単なる「イメージ置き場」ではなく、サプライチェーンセキュリティのゲートとして機能する設計になっている点が、単純なpull-throughキャッシュとの本質的な違いだ。

K3s側の設定はシンプルだ。K3s公式ドキュメントによれば、K3sは起動時に /etc/rancher/k3s/registries.yaml の存在を確認し、そこに定義された mirrors(レジストリのエンドポイント)と configs(認証情報・TLS設定)を元にcontainerdの設定を生成する。このファイルは、ミラーを利用したいすべてのノードに配置する必要があり、設定変更後はノードごとのK3s再起動が必要になる点は運用フローに組み込んでおきたい。

Civoの解説記事も指摘する通り、本番でHarborを動かすなら「高可用性モード」での運用を前提に設計する必要がある。ここが、次章で扱う「隠れたコスト」の入り口になる。

4. 「自前運用」の隠れたコスト — データベース・Redis・ストレージ

section04

Harbor自体はOSSであり、ライセンス費用はかからない。しかし「自前で持つ」ということは、Harborを支える周辺コンポーネントの運用責任もまるごと引き受けるということだ。

Harbor公式のHelm HAガイドを見ると、HelmでHarborをHA構成にする場合、以下はHarbor自身が面倒を見てくれないため、利用者側で別途用意する必要がある。

  • 高可用性PostgreSQL: Harbor core・Notary server・Notary signer用に複数のデータベースを作成する必要がある
  • 高可用性Redis: HarborのRedisクライアントはSentinelをサポートしないため、HAProxy等で単一エントリーポイントを作る構成が推奨される
  • 共有ストレージ: 複数ノードから書き込み可能なPVC(ReadWriteMany)か、S3互換のオブジェクトストレージ
  • 高可用性Ingressコントローラー: 外部公開エンドポイントの可用性もHarborの管轄外

つまりHarborの導入は「レジストリを1つ追加する」のではなく、「PostgreSQL・Redis・オブジェクトストレージ・Ingressという4つのステートフルなコンポーネントを新たに本番運用に組み込む」ことに近い。Canonicalのドキュメントも、本番環境では「プライベートレジストリでDocker Hubをミラーリングする」ことを強く推奨しつつ、その運用コストを織り込んだ設計を促している。

このステートフルな部分の運用工数を、K3sクラスタ本体の運用工数に上乗せできるかどうかが、自前運用に踏み切るかどうかの分岐点になる。KuboのようにRancher管理基盤とHelmチャート対応が標準搭載されたマネージドK3s環境であれば、Harborを含むエコシステムのデプロイ・監視・アップグレードをHelmチャート単位で一括管理でき、この「4つのステートフルコンポーネント」を人力で個別管理する負担を減らせる。

5. まとめ — 「自前で持つ」か「任せる」かの判断基準

section05

Docker Hubのレート制限は、単一クラスタ・小規模チームであればpull-throughキャッシュで当面しのげる問題だ。しかし、マルチクラスタ運用、エッジ環境への展開、あるいは脆弱性スキャンやイメージ署名がコンプライアンス要件に含まれる組織にとっては、Harborのような自前レジストリへの投資が避けられない選択肢になる。

判断基準はシンプルだ。

  • 単一クラスタ・検証環境レベル → pull-throughキャッシュで十分
  • マルチクラスタ・本番の可用性が問われる環境 → Harbor自前運用、ただしHA PostgreSQL/Redis/ストレージの運用体制とセットで検討する
  • 運用工数そのものを圧縮したい → レジストリ運用を含めてマネージドK3s環境に寄せる

Kuboは、K3sベースの標準構成にRancher管理基盤とHelm対応を組み込んでおり、EKSやAKSに対して月額48,000円からのコスト構成でフルスペックのKubernetesクラスタを運用できる。Harborを含むコンテナ基盤の設計判断を、コスト予測可能な形で相談したい場合は、お問い合わせから具体的な構成イメージを確認してみてほしい。データ主権やAir-Gapped環境が要件になる場合は、Kubo On-Premise側でオンプレミス完結の設計も可能だ。

Docker Hubの無料枠が凍りつく朝は、突然やってくる。その日が来る前に、自分たちのクラスタがどちらの選択肢を取るべきか、一度棚卸ししておく価値はある。

Related articles

← Back to all posts