Dockerが提供しているregistry:2のイメージを利用するとパススルーキャッシュを利用することができます。containerdを利用しているときには任意のリポジトリをパススルーキャッシュすることができますが、dockerdの場合はdocker.ioしか対応していないという問題があります。
It’s currently not possible to mirror another private registry. Only the central Hub can be mirrored.
ペパボでは、GitHub Actionsの環境にKubernertesを利用しており、Dockerについてはdind構成で提供しています。その場合に、なんか上手いこと任意のリポジトリをキャッシュできないか考えていたのですが、下記のようなラッパーをrunnerコンテナに差し込むことで対応できました。
#!/bin/bash
# 新しいイメージ名に変換する関数
translate_image_name() {
local image_name="$1"
local new_image_name="$image_name"
if [[ $image_name ==ghcr.io/* ]]; then
new_image_name="<your cache server>/${image_name#ghcr.io/}"
fi
echo "$new_image_name"
}
# Docker コマンドの引数を解析する
translated_args=()
is_pull_command=false
original_image_name=""
translated_image_name=""
for arg in "$@"; do
if [[ $arg == "pull" ]]; then
is_pull_command=true
elif $is_pull_command && [[ $arg =~ ^ghcr.io/.* ]]; then
original_image_name="$arg"
translated_image_name="$(translate_image_name "$arg")"
translated_args+=( "$translated_image_name" )
continue
fi
translated_args+=( "$arg" )
done
# 変換後の引数で /usr/bin/docker を実行
/opt/docker "${translated_args[@]}"
result=$?
# pull コマンド後でイメージ名が置換されていたら、オリジナルのイメージ名でタグ付け
if [[ $result -eq 0 && $is_pull_command == true && $translated_image_name != "" && $original_image_name != "" ]]; then
/opt/docker tag "$translated_image_name" "$original_image_name"
fi
exit $result
例としては、pullするときにイメージ名を ghcr.io/stns/stns:latest
から <your cache>/ghcr.io/stns/stns:latest
に書き換えることでパススルーキャッシュに捻じ曲げるようなイメージです。また透過的に動くようにその後タグも貼り直しています。
もっと早く思いつけばよかった。