Gcr、Quay、DockerHub イメージのダウンロードの問題を完全に解決します。

Gcr、Quay、DockerHub イメージのダウンロードの問題を完全に解決します。

[[382055]]

 この記事は、Michelangelo Yang 氏が執筆した WeChat 公開アカウント「Cloud Native Lab」から転載したものです。この記事を転載する場合は、Cloud Native Lab 公式アカウントまでご連絡ください。

序文

Docker と Kubernetes を使用する場合、gcr.io および quay.io イメージ リポジトリにアクセスする必要があることがよくあります。よく知られている理由により、これらの画像リポジトリは中国ではアクセスできません。唯一アクセスできるのはDocker Hubですが、速度も非常に遅いです。 gcr.azk8s.cn は、gcr.io イメージ リポジトリのプロキシ サイトです。元々は、gcr.azk8s.cn を介して gcr.io リポジトリ内のイメージにアクセスできましたが、現在 *.azk8s.cn は Azure China IP でのみ使用され、外部サービスは提供されなくなりました。他のほとんどの国内画像高速化ソリューションでは、キャッシュに時間同期を使用します。この方法には一定の遅延があり、タイムリーな更新を保証することはできません。 ustc や Qiniu Cloud などの画像アクセラレータを試してみましたが、信頼性が低く、多くの画像では機能しません。

gcr.io などのイメージ リポジトリに正常にアクセスするには、ファイアウォールの外側に gcr.azk8s.cn に似たイメージ リポジトリ プロキシ サイトを構築する必要があります。この要件は、Dockerのオープンソースプロジェクトレジストリ[1]を使用することで満たすことができます。レジストリは、ローカルのプライベート イメージ リポジトリとしてだけでなく、アップストリーム イメージ リポジトリのキャッシュ、つまりプル スルー キャッシュとしても使用できます。

まずはスピードを体感してみましょう:

1. 前提条件

魔法のようなことができるサーバー(つまり、gcr.io に直接アクセスする)

ドメイン名と、ドメイン名に関連付けられた SSL 証明書 (Docker がイメージをプルするときに検証するためにドメイン名証明書が必要です)。一般的にはLet's Encrypt[2]で十分です。

2. 核となる考え方

パラメータ remoteurl を設定することにより、レジストリをリモート リポジトリのキャッシュ リポジトリとして使用できます。このように、このプライベート リポジトリのアドレスを通じてイメージをプルすると、レジストリは最初にイメージをローカル ストレージにキャッシュし、次にそれをプル クライアントに提供します (これら 2 つの手順が同時に実行される可能性もありますが、確信はありません)。まずプライベート レジストリをデプロイし、次に remoteurl を高速化する必要があるイメージ リポジトリのアドレスに設定します。基本的にはこれで完了です。

3. レジストリをカスタマイズする

docker.io、gcr.io、k8s.gcr.io、quay.io、ghcr.io などの一般的なパブリック イメージ リポジトリのキャッシュをサポートするには、レジストリ構成ファイルをカスタマイズする必要があります。 Dockerfile は次のとおりです。

  1. レジストリから:2.6
  2. ラベル メンテナー = "registry-proxy Docker メンテナー https://fuckcloudnative.io"  
  3. ENV PROXY_REMOTE_URL = "" \
  4. DELETE_ENABLED = ""  
  5. コピー entrypoint.sh /entrypoint.sh

entrypoint.sh は、環境変数を構成ファイルに渡すために使用されます。

エントリポイント

  1. #!/bin/sh
  2.  
  3. セット-e
  4.  
  5. config_yml = /etc/docker/registry/config.yml です。
  6.  
  7. if [ -n "$PROXY_REMOTE_URL" -a `grep -c "$PROXY_REMOTE_URL" $CONFIG_YML` -eq 0 ];それから 
  8. echo "プロキシ:" >> $CONFIG_YML
  9. echo "リモートURL: $PROXY_REMOTE_URL" >> $CONFIG_YML
  10. echo "ユーザー名: $PROXY_USERNAME" >> $CONFIG_YML
  11. echo "パスワード: $PROXY_PASSWORD" >> $CONFIG_YML
  12. echo "------ リモートへのプロキシが有効になりました: $PROXY_REMOTE_URL ------"  
  13. elif [ $DELETE_ENABLED = true -a `grep -c "delete:" $CONFIG_YML` -eq 0 ];それから 
  14. sed -i '/rootdirectory/a\ 削除:' $CONFIG_YML
  15. sed -i '/delete/a\ 有効: true' $CONFIG_YML
  16. echo "------ ローカルストレージの削除を有効にしました -----"  
  17. フィ
  18.  
  19. sed -i "/headers/a\ アクセス制御許可元: ['*']" $CONFIG_YML
  20. sed -i "/headers/a\ アクセス制御許可メソッド: ['HEAD', 'GET', 'OPTIONS', 'DELETE']" $CONFIG_YML
  21. sed -i "/headers/a\ アクセス制御公開ヘッダー: ['Docker-Content-Digest']" $CONFIG_YML
  22.  
  23. 場合  「$1」   
  24. *.yaml|*.yml)を設定  --registry サーブ "$@" ;;  
  25. サーブ|ガベージコレクト|ヘルプ|-*)セット  --registry "$@" ;;  
  26. エサック
  27.  
  28. 実行者  「$@」  

4. キャッシュサービスを開始する

Docker イメージをビルドしたら、サービスを開始できます。自分でビルドしたくない場合は、私のイメージ yangchuansheng/registry-proxy を直接使用できます。

一般的に言えば、docker.io、gcr.io、k8s.gcr.io、quay.io、ghcr.io を同時にキャッシュする場合でも、1C 2G のクラウド ホストで十分です (他のサービスを実行していない場合)。私のブログ、コメント サービス、その他さまざまなサービスはすべてクラウド ホスト上で実行されるため、1 つのサーバーではニーズを満たすのに不十分です。 Tencent Cloud Hong Kong の軽量サーバーを 2 台直接購入しました。

マシンを 2 台購入したので、k3s クラスターをセットアップする必要があります。ホスト名を見れば、何に使用するかがわかります。このうち、2C 4G はマスターノードとして使用され、1C 2G はノードノードとして使用されます。

docker.io を例にしてリソース リストを作成します。

dockerhub.yaml

  1. APIバージョン: アプリ/v1
  2. 種類: デプロイメント
  3. メタデータ:
  4. 名前: dockerhub
  5. ラベル:
  6. アプリ: dockerhub
  7. 仕様:
  8. レプリカ: 1
  9. セレクタ:
  10. 一致ラベル:
  11. アプリ: dockerhub
  12. テンプレート:
  13. メタデータ:
  14. ラベル:
  15. アプリ: dockerhub
  16. 仕様:
  17. 親和性:
  18. ポッドアンチアフィニティ:
  19. 優先スケジュール中は無視実行中:
  20. -podアフィニティ用語:
  21. ラベルセレクター:
  22. 一致表現:
  23. -キー: アプリ
  24. 演算子:  
  25. - ドッカーハブ
  26. トポロジキー: kubernetes.io/ホスト名
  27. 重量: 1
  28. dnsポリシー: なし
  29. dnsConfig:
  30. ネームサーバー:
  31. - 8.8.8.8
  32. - 8.8.4.4
  33. コンテナ:
  34. -名前: dockerhub
  35. イメージ: yangchuansheng/registry-proxy:latest
  36. 環境:
  37. -名前: PROXY_REMOTE_URL
  38. 値: https://registry-1.docker.io
  39. -名前: PROXY_USERNAME
  40. 値: 揚川勝
  41. -名前: PROXY_PASSWORD
  42. 価値: ********
  43. ポート:
  44. - コンテナポート: 5000
  45. プロトコル: TCP
  46. ボリュームマウント:
  47. - マウントパス: /etc/localtime
  48. 名前: 現地時間
  49. - マウントパス: /var/lib/registry
  50. 名前: レジストリ
  51. ボリューム:
  52. -名前: 現地時間
  53. ホストパス:
  54. パス: /etc/localtime
  55. -名前: レジストリ
  56. ホストパス:
  57. パス: /var/lib/registry
  58. ---  
  59. APIバージョン: v1
  60. 種類: サービス
  61. メタデータ:
  62. 名前: dockerhub
  63. ラベル:
  64. アプリ: dockerhub
  65. 仕様:
  66. セレクタ:
  67. アプリ: dockerhub
  68. ポート:
  69. - プロトコル: TCP
  70. 名前: http
  71. ポート: 5000
  72. ターゲットポート: 5000

リソース リストを使用して、対応するサービスを作成します。

  1. 🐳 → kubectl apply -f dockerhub.yaml

ホストが 1 つしかない場合は、docker-compose を使用してコンテナーをオーケストレーションできます。 k8s 設定を参照して、設定ファイルを自分で変更することもできます。この記事では詳細には触れません。

5. エージェントの選択

docker.io のみをキャッシュする場合は、registry-proxy のポートを 443 に直接変更し、SSL 証明書の設定を追加できます。複数のパブリック イメージ リポジトリをキャッシュする場合は、443 ポートが 1 つしかなく、複数のレジストリ プロキシ サービスが同じポートを共有できないため、キャッシュすることはお勧めしません。合理的なアプローチは、エッジ プロキシ サービスを使用して、ドメイン名に基づいて異なるレジストリ プロキシ サービスにリクエストを転送することです。

Kubernetes クラスターの場合、Ingress Controller はエッジ プロキシです。一般的な Ingress コントローラーは、基本的に Nginx または Envoy によって実装されます。 Envoy はプロキシの世界では新参者ですが、適切なタイミングで誕生しました。その機能の多くはクラウド向けにネイティブに準備されており、真にクラウド ネイティブな L7 プロキシおよび通信バスとなっています。たとえば、サービス検出機能や動的構成機能は、Nginx などのプロキシのホットロードとは異なります。 Envoy は API を通じてコン​​トロール プレーンを実装できます。コントロール プレーンはサービス検出を集中管理し、データ プレーン プロキシを再起動せずに API インターフェイスを介してデータ プレーンの構成を動的に更新できます。それだけでなく、コントロール プレーンは API を介して構成を階層化し、レイヤーごとに更新することもできます。

現在、Envoyを使用して実装されているIngressコントローラには、ContourとGloo[3]が含まれます。 Envoy に興味があり、Ingress Controller をエッジ プロキシとして使用したい場合は、Contour を試してみてください。 Ingress Controller は、基盤となるレイヤーを抽象化し、多くの詳細を隠蔽します。すべての詳細な構成を考慮することはできず、基盤となるプロキシのすべての構成項目をサポートするわけではありません。したがって、私はネイティブ Envoy をエッジ プロキシとして使用することを選択しました。スタンドアロンのレジストリ プロキシ サービスを実行している場合は、Envoy を試すこともできます。

6. プロキシ設定

まず、Envoy リソース リストを作成します。

エンボイ.yaml

  1. APIバージョン: アプリ/v1
  2. 種類: デプロイメント
  3. メタデータ:
  4. 名前: 特使
  5. 名前空間: kube-system
  6. ラベル:
  7. アプリ: エンボイ
  8. 仕様:
  9. レプリカ: 2
  10. セレクタ:
  11. 一致ラベル:
  12. アプリ: エンボイ
  13. 戦略:
  14. ローリングアップデート:
  15. 最大サージ: 0
  16. 最大利用不可: 1
  17. タイプ: ローリングアップデート
  18. テンプレート:
  19. メタデータ:
  20. ラベル:
  21. アプリ: エンボイ
  22. 仕様:
  23. ホストネットワーク: true  
  24. dnsポリシー: ClusterFirstWithHostNet
  25. コンテナ:
  26. -名前: 特使
  27. イメージ: envoyproxy/envoy:v1.17-latest
  28. イメージプルポリシー: IfNotPresent
  29. 指示:
  30. -特使
  31. :envoy.yaml のファイル
  32. ポート:
  33. - コンテナポート: 443
  34. 名前: https
  35. - コンテナポート: 80
  36. 名前: http
  37. - コンテナポート: 15001
  38. 名前: http-metrics
  39. ボリュームマウント:
  40. - マウントパス: /etc/localtime
  41. 名前: 現地時間
  42. - マウントパス: /etc/envoy
  43. 名前: 特使
  44. - マウントパス: /root/.acme.sh/fuckcloudnative.io
  45. 名前: ssl
  46. ボリューム:
  47. -名前: 現地時間
  48. ホストパス:
  49. パス: /etc/localtime
  50. -名前: ssl
  51. ホストパス:
  52. パス: /root/.acme.sh/fuckcloudnative.io
  53. -名前: 特使
  54. ホストパス:
  55. パス: /etc/envoy

リソース リストを使用して、対応するサービスを作成します。

  1. 🐳 → kubectl apply -f envoy.yaml

ここでは、hostPath を使用して envoy 構成をコンテナーにマウントし、ファイルを通じて構成を動的に更新することを選択します。 Envoy の構成を見てみましょう。まず、/etc/envoy ディレクトリに入ります。

ブートストラップ構成:

  1. ノード:
  2. id: ノード0
  3. クラスター: cluster0
  4. 動的リソース:
  5. lds_config:
  6. パス: /etc/envoy/lds.yaml
  7. cds_config:
  8. パス: /etc/envoy/cds.yaml
  9. 管理者:
  10. アクセスログパス: "/dev/stdout"  
  11. 住所:
  12. ソケットアドレス:
  13. アドレス: "0.0.0.0"  
  14. ポート値: 15001

LDS 構成:

lds.yaml

  1. バージョン情報: "0"  
  2. リソース:
  3. - "@type" : type.googleapis.com/envoy.config.listener.v3.Listener
  4. 名前: listener_http
  5. 住所:
  6. ソケットアドレス:
  7. アドレス: 0.0.0.0
  8. ポート値: 80
  9. フィルターチェーン:
  10. - フィルター:
  11. -名前: envoy.filters.network.http_connection_manager
  12. 入力された構成:
  13. "@type" : type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
  14. 統計プレフィックス: ingress_http
  15. コーデックタイプ: AUTO
  16. アクセスログ:
  17. 名前: envoy.access_loggers.file
  18. 入力された構成:
  19. "@type" : type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
  20. パス: /dev/stdout
  21. ルート設定:
  22. 名前: http_route
  23. 仮想ホスト:
  24. -名前:デフォルト 
  25. ドメイン:
  26. - 「*」  
  27. ルート:
  28. - マッチ:
  29. プレフィックス: "/"  
  30. リダイレクト:
  31. https_redirect:有効 
  32. ポートリダイレクト: 443
  33. 応答コード: 「見つかりました」  
  34. http_フィルター:
  35. -名前: envoy.filters.http.router
  36. - "@type" : type.googleapis.com/envoy.config.listener.v3.Listener
  37. 名前: listener_https
  38. 住所:
  39. ソケットアドレス:
  40. アドレス: 0.0.0.0
  41. ポート値: 443
  42. リスナーフィルター:
  43. -名前: "envoy.filters.listener.tls_inspector"  
  44. 入力された構成: {}
  45. フィルターチェーン:
  46. - トランスポートソケット:
  47. 名前: envoy.transport_sockets.tls
  48. 入力された構成:
  49. "@type" : type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
  50. 共通TLSコンテキスト:
  51. alpn_プロトコル: h2、http/1.1
  52. tls_証明書:
  53. - 証明書チェーン:
  54. ファイル名: "/root/.acme.sh/fuckcloudnative.io/fullchain.cer"  
  55. 秘密鍵:
  56. ファイル名: "/root/.acme.sh/fuckcloudnative.io/fuckcloudnative.io.key"  
  57. フィルター:
  58. -名前: envoy.filters.network.http_connection_manager
  59. 入力された構成:
  60. "@type" : type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
  61. 統計プレフィックス: ingress_https
  62. コーデックタイプ: AUTO
  63. リモートアドレスの使用: true  
  64. アクセスログ:
  65. 名前: envoy.access_loggers.file
  66. 入力された構成:
  67. "@type" : type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
  68. パス: /dev/stdout
  69. ルート設定:
  70. 名前: https_route
  71. 追加するレスポンスヘッダー:
  72. - ヘッダー:
  73. キー: 厳格なトランスポートセキュリティ
  74. 値: "max-age=15552000; includeSubdomains; preload"  
  75. 仮想ホスト:
  76. -名前: docker
  77. ドメイン:
  78. ネイティブ
  79. ルート:
  80. - マッチ:
  81. プレフィックス: "/"  
  82. ルート:
  83. クラスター: dockerhub
  84. タイムアウト: 600秒
  85. http_フィルター:
  86. -名前: envoy.filters.http.router
  87. 入力された構成:
  88. "@type" : type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

CDS 構成:

cds.yaml

  1. バージョン情報: "0"  
  2. リソース:
  3. - "@type" : type.googleapis.com/envoy.config.cluster.v3.Cluster
  4. 名前: dockerhub
  5. 接続タイムアウト: 15秒
  6. タイプ: strict_dns
  7. dns_lookup_family: V4_ONLY
  8. lb_policy: ラウンドロビン
  9. 負荷割り当て:
  10. クラスター名: dockerhub
  11. エンドポイント:
  12. - lb_エンドポイント:
  13. - 終点:
  14. 住所:
  15. ソケットアドレス:
  16. アドレス: dockerhub.default  
  17. ポート値: 5000

ここでのアドレスは、Kubernetes クラスターの内部ドメイン名を使用します。他の展開方法については、ご自身の判断でご検討ください。

Envoy を設定したら、プロキシ サーバー経由で docker.io イメージをプルできます。

7.加速効果を確認する

これで、プロキシ サーバー経由でパブリック イメージを取得できるようになりました。たとえば、nginx:alpine イメージをプルする場合は、次のコマンドを使用できます。

  1. 🐳 → docker pull docker.fuckcloudnative.io/library/nginx:alpine
  2.  
  3. alpine: library/nginxから取得
  4. 801bfaa63ef2: プル完了
  5. b1242e25d284: プルが完了しました
  6. 7453d3e6b909: プル完了
  7. 07ce7418c4f8: プル完了
  8. e295e0624aa3: プル完了
  9. ダイジェスト: sha256:c2ce58e024275728b00a554ac25628af25c54782865b3487b11c21cafb7fabda
  10. ステータス: docker.fuckcloudnative.io/library/nginx:alpine新しいイメージをダウンロードしました
  11. docker.fuckcloudnative.io/library/nginx:alpine

8. すべての画像リポジトリをキャッシュする

前の例では、docker.io のみをキャッシュします。すべてのパブリックイメージリポジトリをキャッシュする場合は、セクション 4-6 を参照してください。 k8s.gcr.io を例にとると、まずリソース リストを準備します。

gcr-k8s.yaml

  1. APIバージョン: アプリ/v1
  2. 種類: デプロイメント
  3. メタデータ:
  4. 名前: gcr-k8s
  5. ラベル:
  6. アプリ: gcr-k8s
  7. 仕様:
  8. レプリカ: 1
  9. セレクタ:
  10. 一致ラベル:
  11. アプリ: gcr-k8s
  12. テンプレート:
  13. メタデータ:
  14. ラベル:
  15. アプリ: gcr-k8s
  16. 仕様:
  17. 親和性:
  18. ポッドアンチアフィニティ:
  19. 優先スケジュール中は無視実行中:
  20. -podアフィニティ用語:
  21. ラベルセレクター:
  22. 一致表現:
  23. -キー: アプリ
  24. 演算子:  
  25. - gcr-k8s
  26. トポロジキー: kubernetes.io/ホスト名
  27. 重量: 1
  28. dnsポリシー: なし
  29. dnsConfig:
  30. ネームサーバー:
  31. - 8.8.8.8
  32. - 8.8.4.4
  33. コンテナ:
  34. -名前: gcr-k8s
  35. イメージ: yangchuansheng/registry-proxy:latest
  36. 環境:
  37. -名前: PROXY_REMOTE_URL
  38. 値: https://k8s.gcr.io
  39. ポート:
  40. - コンテナポート: 5000
  41. プロトコル: TCP
  42. ボリュームマウント:
  43. - マウントパス: /etc/localtime
  44. 名前: 現地時間
  45. - マウントパス: /var/lib/registry
  46. 名前: レジストリ
  47. ボリューム:
  48. -名前: 現地時間
  49. ホストパス:
  50. パス: /etc/localtime
  51. -名前: レジストリ
  52. ホストパス:
  53. パス: /var/lib/registry
  54. ---  
  55. APIバージョン: v1
  56. 種類: サービス
  57. メタデータ:
  58. 名前: gcr-k8s
  59. ラベル:
  60. アプリ: gcr-k8s
  61. 仕様:
  62. セレクタ:
  63. アプリ: gcr-k8s
  64. ポート:
  65. - プロトコル: TCP
  66. 名前: http
  67. ポート: 5000
  68. ターゲットポート: 5000

Kubernetes クラスターにデプロイします。

  1. 🐳 → kubectl apply -f gcr-k8s.yaml

lds.yaml に関連する設定を追加します。

  1. 仮想ホスト:
  2. -名前: docker
  3. ...
  4. ...
  5. -名前: k8s
  6. ドメイン:
  7. - k8s.fuckcloudnative.io
  8. ルート:
  9. - マッチ:
  10. プレフィックス: "/"  
  11. ルート:
  12. クラスター: gcr-k8s
  13. タイムアウト: 600秒

cds.yaml に関連する構成を追加します。

  1. - "@type" : type.googleapis.com/envoy.config.cluster.v3.Cluster
  2. 名前: gcr-k8s
  3. 接続タイムアウト: 1秒
  4. タイプ: strict_dns
  5. dns_lookup_family: V4_ONLY
  6. lb_policy: ラウンドロビン
  7. 負荷割り当て:
  8. クラスター名: gcr-k8s
  9. エンドポイント:
  10. - lb_エンドポイント:
  11. - 終点:
  12. 住所:
  13. ソケットアドレス:
  14. アドレス: gcr -k8s.default  
  15. ポート値: 5000

他のイメージリポジトリでも上記の手順に従うことができます。私が自分で実行しているキャッシュ サービス コンテナーは次のとおりです。

  1. 🐳 → kubectl get pod -o ワイド
  2.  
  3. gcr-8647ffb586-67c6g 1/1 実行中 0 21h 10.42.1.52 blog-k3s02
  4. ghcr-7765f6788b-hxxvc 1/1 実行中 0 21h 10.42.1.55 blog-k3s01
  5. dockerhub-94bbb7497-x4zwg 1/1 実行中 0 21h 10.42.1.54 blog-k3s02
  6. gcr-k8s-644db84879-7xssb 1/1 実行中 0 21h 10.42.1.53 blog-k3s01
  7. quay-559b65848b-ljclb 1/1 実行中 0 21h 10.42.0.154 blog-k3s01

9. コンテナのランタイム構成

すべてのキャッシュ サービスを構成したら、プロキシ経由でパブリック イメージをプルできます。以下のリストに従って、画像アドレスのフィールドを置き換えるだけです。

元のURL 置き換えられたURL
docker.io/xxx/xxx または xxx/xxx docker.fuckcloudnative.io/xxx/xxx
docker.io/library/xxx または xxx docker.fuckcloudnative.io/library/xxx
gcr.io/xxx/xxx gcr.fuckcloudnative.io/xxx/xxx
k8s.gcr.io/xxx/xxx k8s.fuckcloudnative.io/xxx/xxx
quay.io/xxx/xxx 岸壁.fuckcloudnative.io/xxx/xxx
ghcr.io/xxx/xxx ghcr.fuckcloudnative.io/xxx/xxx

もちろん、最善の方法はレジストリミラーを直接構成することです。 Docker は docker.io のレジストリ ミラーの構成のみをサポートしていますが、Containerd と Podman はすべてのイメージ リポジトリのレジストリ ミラーの構成をサポートしています。

ドッカー

Docker は設定ファイル /etc/docker/daemon.json を変更し、次のコンテンツを追加できます。

  1. {
  2. 「レジストリミラー」 : [
  3. 「https://docker.fuckcloudnative.io」  
  4. ]
  5. }

その後、Docker サービスを再起動すると、プロキシ サーバーのアドレスを指定せずに docker.io からイメージを直接プルできるようになります。 Docker サービス自体は、プロキシ サーバーを介してイメージを自動的にプルします。例えば:

  1. 🐳 → docker pull nginx:alpine
  2. 🐳 → docker pull docker.io/library/nginx:alpine

コンテナ

Containerd は比較的シンプルです。あらゆるレジストリのミラーリングをサポートします。設定ファイル /etc/containerd/config.toml を変更し、次の設定を追加するだけです。

  1. [プラグイン。 ["io.containerd.grpc.v1.cri" .レジストリ]
  2. [プラグイン。 ["io.containerd.grpc.v1.cri" .registry.mirrors]
  3. [プラグイン。 "io.containerd.grpc.v1.cri" .registry.mirrors. [[docker.io] ]
  4. エンドポイント = [ "https://docker.fuckcloudnative.io" ]
  5. [プラグイン。 "io.containerd.grpc.v1.cri" .registry.mirrors. [[ ... [
  6. エンドポイント = [ "https://k8s.fuckcloudnative.io" ]
  7. [プラグイン。 "io.containerd.grpc.v1.cri" .registry.mirrors. [[[gcr.io] ]
  8. エンドポイント = [ "https://gcr.fuckcloudnative.io" ]
  9. [プラグイン。 "io.containerd.grpc.v1.cri" .registry.mirrors. ["ghcr.io" ]
  10. エンドポイント = [ "https://ghcr.fuckcloudnative.io" ]
  11. [プラグイン。 "io.containerd.grpc.v1.cri" .registry.mirrors. [[[quay.io] ]
  12. エンドポイント = [ "https://quay.fuckcloudnative.io" ]

Containerd サービスを再起動すると、プレフィックスを変更せずにすべてのイメージを直接プルできるようになります。 Containerd は、設定に基づいてイメージをプルするための対応するプロキシ URL を自動的に選択します。

ポッドマン

Podman は、任意のレジストリのミラーリングもサポートします。設定ファイル /etc/containers/registries.conf を変更し、次の設定を追加するだけです。

  1. 非修飾検索レジストリ = [ 'docker.io' 'k8s.gcr.io' 'gcr.io' 'ghcr.io' 'quay.io' ]
  2.  
  3. [[レジストリ]]
  4. プレフィックス = "docker.io"  
  5. 安全でない =本当 
  6. 場所 = "registry-1.docker.io"  
  7.  
  8. [[レジストリミラー]]
  9. 場所 = "docker.fuckcloudnative.io"  
  10.  
  11. [[レジストリ]]
  12. プレフィックス = "k8s.gcr.io"  
  13. 安全でない =本当 
  14. 場所 = "k8s.gcr.io"  
  15.  
  16. [[レジストリミラー]]
  17. 場所 = "k8s.fuckcloudnative.io"  
  18.  
  19. [[レジストリ]]
  20. プレフィックス = "gcr.io"  
  21. 安全でない =本当 
  22. 場所 = "gcr.io"  
  23.  
  24. [[レジストリミラー]]
  25. 場所 = "gcr.fuckcloudnative.io"  
  26.  
  27. [[レジストリ]]
  28. プレフィックス = "ghcr.io"  
  29. 安全でない =本当 
  30. 場所 = "ghcr.io"  
  31.  
  32. [[レジストリミラー]]
  33. 場所 = "ghcr.fuckcloudnative.io"  
  34.  
  35. [[レジストリ]]
  36. プレフィックス = "quay.io"  
  37. 安全でない =本当 
  38. 場所 = "quay.io"  
  39.  
  40. [[レジストリミラー]]
  41. 場所 = "quay.fuckcloudnative.io"  

その後、プレフィックスを変更せずにすべてのイメージを直接プルできます。 Podman は、設定に基づいてイメージをプルするための対応するプロキシ URL を自動的に選択します。 Podman にはフォールバック メカニズムもあります。上記の構成は、最初に registry.mirror の location フィールドの URL を通じてイメージをプルしようとすることを意味します。失敗した場合は、レジストリの場所フィールドの URL を通じて取得を試みます。

10. キャッシュをクリアする

キャッシュ サービスはプルされたイメージをローカルにキャッシュするため、ディスク容量を消費します。一般的に、クラウド ホストのディスク容量はそれほど大きくなく、OSS や S3 ストレージは比較的高価で、コスト効率があまり良くありません。

この問題を解決するには、ローカル ディスクにキャッシュされた一部のイメージを定期的に削除するか、すべてのイメージを削除することをお勧めします。方法は比較的簡単です。他のレジストリのストレージを共有するために別のレジストリをデプロイし、削除機能を有効にして、API またはダッシュボードから削除します。

まずリソース リストを準備します。

  1. APIバージョン: アプリ/v1
  2. 種類: デプロイメント
  3. メタデータ:
  4. 名前: reg-ローカル 
  5. ラベル:
  6. アプリ: reg-ローカル 
  7. 仕様:
  8. レプリカ: 1
  9. セレクタ:
  10. 一致ラベル:
  11. アプリ: reg-ローカル 
  12. テンプレート:
  13. メタデータ:
  14. ラベル:
  15. アプリ: reg-ローカル 
  16. 仕様:
  17. 親和性:
  18. ポッドアンチアフィニティ:
  19. 優先スケジュール中は無視実行中:
  20. -podアフィニティ用語:
  21. ラベルセレクター:
  22. 一致表現:
  23. -キー: アプリ
  24. 演算子:  
  25. - reg-ローカル 
  26. トポロジキー: kubernetes.io/ホスト名
  27. 重量: 1
  28. コンテナ:
  29. -名前: reg-ローカル 
  30. イメージ: yangchuansheng/registry-proxy:latest
  31. 環境:
  32. -名前: DELETE_ENABLED
  33. 値: "true"  
  34. ポート:
  35. - コンテナポート: 5000
  36. プロトコル: TCP
  37. ボリュームマウント:
  38. - マウントパス: /etc/localtime
  39. 名前: 現地時間
  40. - マウントパス: /var/lib/registry
  41. 名前: レジストリ
  42. ボリューム:
  43. -名前: 現地時間
  44. ホストパス:
  45. パス: /etc/localtime
  46. -名前: レジストリ
  47. ホストパス:
  48. パス: /var/lib/registry
  49. ---  
  50. APIバージョン: v1
  51. 種類: サービス
  52. メタデータ:
  53. 名前: reg-ローカル 
  54. ラベル:
  55. アプリ: reg-ローカル 
  56. 仕様:
  57. セレクタ:
  58. アプリ: reg-ローカル 
  59. ポート:
  60. - プロトコル: TCP
  61. 名前: http
  62. ポート: 5000
  63. ターゲットポート: 5000

Kubernetes クラスターにデプロイします。

  1. 🐳 → kubectl apply -f reg-ローカル.yaml

Docker レジストリ UI のリソース リストを準備します。

  1. APIバージョン: アプリ/v1
  2. 種類: デプロイメント
  3. メタデータ:
  4. 名前: レジストリUI
  5. ラベル:
  6. アプリ: レジストリUI
  7. 仕様:
  8. レプリカ: 1
  9. セレクタ:
  10. 一致ラベル:
  11. アプリ: レジストリUI
  12. テンプレート:
  13. メタデータ:
  14. ラベル:
  15. アプリ: レジストリUI
  16. 仕様:
  17. 親和性:
  18. ポッドアンチアフィニティ:
  19. 優先スケジュール中は無視実行中:
  20. -podアフィニティ用語:
  21. ラベルセレクター:
  22. 一致表現:
  23. -キー: アプリ
  24. 演算子:  
  25. - レジストリUI
  26. トポロジキー: kubernetes.io/ホスト名
  27. 重量: 1
  28. 許容範囲:
  29. -キー: node-role.kubernetes.io/ingress
  30. 演算子: 存在する
  31. 効果: NoSchedule
  32. コンテナ:
  33. -名前: レジストリUI
  34. イメージ: joxit/docker-registry-ui:静的 
  35. 環境:
  36. -名前: REGISTRY_TITLE
  37. 値: 私のプライベートDockerレジストリ
  38. -名前: REGISTRY_URL
  39. 値: "http://reg-local:5000"  
  40. -名前: DELETE_IMAGES
  41. 値: "true"  
  42. ポート:
  43. - コンテナポート: 80
  44. プロトコル: TCP
  45. ボリュームマウント:
  46. - マウントパス: /etc/localtime
  47. 名前: 現地時間
  48. ボリューム:
  49. -名前: 現地時間
  50. ホストパス:
  51. パス: /etc/localtime
  52. ---  
  53. APIバージョン: v1
  54. 種類: サービス
  55. メタデータ:
  56. 名前: レジストリUI
  57. ラベル:
  58. アプリ: レジストリUI
  59. 仕様:
  60. セレクタ:
  61. アプリ: レジストリUI
  62. ポート:
  63. - プロトコル: TCP
  64. 名前: http
  65. ポート: 80
  66. ターゲットポート: 80

Kubernetes クラスターにデプロイします。

  1. 🐳 → kubectl apply -f レジストリ ui.yaml

この方法では、ダッシュボードを通じてイメージをクリーンアップし、スペースを解放することができます。

または、ストレージ ディレクトリ全体の内容を一定の時間に削除するだけです。たとえば、crontab -e コマンドを実行し、次の内容を追加します。

  1. * * */2 * * /usr/bin/rm -rf /var/lib/registry/* &>/dev/ null  

/var/lib/registry/ ディレクトリが 2 日ごとにクリーンアップされることを示します。

11. 反無料品認定

最後に、もう1つ問題があります。キャッシュサービスのドメイン名をすべて公開しました。みんなが無料で使うようになれば、私のクラウドサーバーは絶対に耐えられなくなります。フリーロードを防ぐために、registry-proxy に認証を追加する必要があります。最も簡単な方法は、基本認証を使用し、htpasswd を使用してパスワードを保存することです。

パスワード admin を使用して、ユーザー admin のパスワード ファイルを作成します。

  1. 🐳 → docker run \
  2. --entrypoint htpasswd \  
  3. レジストリ:2.6 -Bbn 管理者 管理者 > htpasswd

シークレットを作成する:

  1. 🐳 → kubectlシークレットジェネリックレジストリ認証--from-file=htpasswdを作成します 

docker.io を例にして、リソース リストの構成を変更します。

  1. APIバージョン: アプリ/v1
  2. 種類: デプロイメント
  3. メタデータ:
  4. 名前: dockerhub
  5. ラベル:
  6. アプリ: dockerhub
  7. 仕様:
  8. レプリカ: 1
  9. セレクタ:
  10. 一致ラベル:
  11. アプリ: dockerhub
  12. テンプレート:
  13. メタデータ:
  14. ラベル:
  15. アプリ: dockerhub
  16. 仕様:
  17. 親和性:
  18. ポッドアンチアフィニティ:
  19. 優先スケジュール中は無視実行中:
  20. -podアフィニティ用語:
  21. ラベルセレクター:
  22. 一致表現:
  23. -キー: アプリ
  24. 演算子:  
  25. - ドッカーハブ
  26. トポロジキー: kubernetes.io/ホスト名
  27. 重量: 1
  28. dnsポリシー: なし
  29. dnsConfig:
  30. ネームサーバー:
  31. - 8.8.8.8
  32. - 8.8.4.4
  33. コンテナ:
  34. -名前: dockerhub
  35. イメージ: yangchuansheng/registry-proxy:latest
  36. 環境:
  37. -名前: PROXY_REMOTE_URL
  38. 値: https://registry-1.docker.io
  39. -名前: PROXY_USERNAME
  40. 値: 揚川勝
  41. -名前: PROXY_PASSWORD
  42. 価値: ********
  43. + -名前: REGISTRY_AUTH_HTPASSWD_REALM
  44. + 値: レジストリ領域
  45. + -名前: REGISTRY_AUTH_HTPASSWD_PATH
  46. + 値: /auth/htpasswd
  47. ポート:
  48. - コンテナポート: 5000
  49. プロトコル: TCP
  50. ボリュームマウント:
  51. - マウントパス: /etc/localtime
  52. 名前: 現地時間
  53. - マウントパス: /var/lib/registry
  54. 名前: レジストリ
  55. + - マウントパス: /auth
  56. +名前: 認証
  57. ボリューム:
  58. -名前: 現地時間
  59. ホストパス:
  60. パス: /etc/localtime
  61. -名前: レジストリ
  62. ホストパス:
  63. パス: /var/lib/registry
  64. + -名前: 認証
  65. + 秘密:
  66. + シークレット名: レジストリ認証

効果を上げるには、次のように適用します。

  1. 🐳 → kubectl apply -f dockerhub.yaml

イメージをプルしてみます:

  1. 🐳 → docker pull docker.fuckcloudnative.io/library/nginx:latest
  2.     
  3. デーモンからのエラー応答: https://docker.fuckcloudnative.io/v2/library/nginx/manifests/latest を取得:基本認証資格情報がありません

イメージリポジトリにログインします。

  1. 🐳 → docker ログイン docker.fuckcloudnative.io
  2. ユーザー名: admin
  3. パスワード:
  4. 警告!パスワードは暗号化されずに/root/.docker/config.json保存されます
  5. この警告を削除するには、資格情報ヘルパーを構成します。見る
  6. https://docs.docker.com/engine/reference/commandline/login/#credentials-store
  7.  
  8. ログインに成功しました

これで、イメージを正常にプルできるようになります。

より細かく権限を制御したい場合は、認証にトークンを使用できます。詳細についてはdocker_auth[4]プロジェクトを参照してください。

参考文献

[1]レジストリ: https://docs.docker.com/registry/

[2]レッツ・エンクリプト:https://letsencrypt.org/

[3]Gloo: https://github.com/solo-io/gloo

[4]docker_auth: https://github.com/cesanta/docker_auth

<<:  2021年春節ガラステージでブラックテクノロジーを披露 - XRテクノロジー

>>:  2020 年グローバル コンピューティング パワー インデックス評価レポート - グローバル コンピューティング パワー インデックスの結果とランキング

推薦する

キーワードの価値を高める方法についての簡単な説明

ウェブサイトのキーワードとは、ユーザーが検索エンジンを通じてウェブサイトを見つけられるように、ウェブ...

Kubernetesを導入することで、企業は時間とコストを節約できる

COVID-19パンデミックは、わずか1年余りで、あらゆる企業のビジネスのやり方に、以前なら何年もか...

レポート予測: 医療クラウドインフラ市場規模は2028年に1,420億ドルに達する

ResearchAndMarkets によると、世界のヘルスケア クラウド インフラストラクチャ市場...

ニュース寄稿プロモーションのメリットは何ですか?

最近では、フォーラムプロモーション、ブログプロモーション、質疑応答プロモーション、電子メールプロモー...

マルチクラウド/ハイブリッドIT環境の企業導入が主流になる

451 Research によると、2019 年までに企業の 69% がマルチクラウド/ハイブリッド...

FrontRangeHosting-768m メモリ KVM/44g ハードディスク/1500g フロー/6 USD

最近、frontrangehostingはONAPPを立ち上げ、新しい請求管理システムhostbil...

ウェブサイト最適化キーワード

ZZD5 ブログより引用: ウェブサイトが数多く存在するこの時代では、ウェブサイトが上位にランクされ...

ウェブサイトに偽のユーザーエクスペリエンスを作り出す方法

2013 年以前は外部リンクが王様でしたが、2013 年以降はユーザーが王様です。実際、検索エンジン...

クラウド コンピューティング アーキテクチャにおける Cloud TiDB の技術的秘密 (パート 2)

「クラウド コンピューティング アーキテクチャにおけるクラウド TiDB の技術的秘密 (パート 1...

モバイル Web サイト構築プラットフォームを使用する際に注意すべき点は何ですか?

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますモバイルイ...

フラッシュウィザードをめぐるテンセントと360の戦いの裏側:テンセントは「自らの名誉回復」を担う

これは起業家たちを舞台裏で戦う珍しい戦いであり、戦いの双方の陣営はテンセントのCEO、馬化騰氏と36...

debian/ubuntu 出力: 次のキー ID に使用できる公開キーがありません

今日、VPS を更新したときに、エラー W: 次のキー ID に使用できる公開キーがありません: が...

SEO担当者の4つのタブー:本質を理解することが成長の鍵

SEO 初心者でも熟練した SEO 経験者でも、SEO 最適化プロセスで多かれ少なかれ問題に遭遇して...

ブルーハットSEOを行うときは、独自の姿勢を持つ必要があります。

社会はあまりにも速く進歩しており、多くの人々は衝動的すぎます。Blue Hat SEO は落ち着いて...

Google、データ需要の増加に伴いアジア太平洋地域のクラウドリージョンを3つ追加

Google は、データ分析、オープン インフラストラクチャ、オンライン接続の需要が高まっているアジ...