setup-javaで取ってくるJDKをキャッシュしてセルフホストランナーの転送量を節約する
こんにちは。サイボウズ株式会社、生産性向上チームの平木場です。今回は、GitHub Actions のセルフホストランナーの通信量削減のために行った setup-java で取ってくる JDK をあらかじめキャッシュした方法を紹介します。
内容としては、以前チームメンバーが発表したスライドの「Amazon Corretto との転送量を削減」(P14-P18)をちょっと詳しくしたものになります。背景や転送量の分析方法の詳しい説明はスライドをご覧ください。
背景
生産性向上チームでは、社内向けにオートスケールする GitHub Actions セルフホストランナー環境[1]を提供しており、広く利用していただいています。
我々のセルフホストランナーは AWS の EC2 インスタンスを利用しており、構成的にランナーとインターネットとの通信に NAT ゲートウェイを通るようになっています。
NAT ゲートウェイは転送量に応じて課金されます。VPC フローログを分析したところ、通信先のドメイン上位に corretto.aws
がランクインしていました。
corretto.aws
は Amazon Corretto という OpenJDK ディストリビューションのダウンロード元です。
この Amazon Corretto ですが、圧縮された状態で Corretto 21 が 210MB、Corretto 17 が 194MB となっており、毎回ダウンロードすると転送量がかさみます。
調べたところ、Amazon Corretto は GitHub Actions の actions/setup-java を使ってダウンロードされていました。
setup-java
は対象の JDK がインストール済みであれば JDK のダウンロードをスキップする仕組みになっています。したがってランナーのインスタンスを使い回すことでキャッシュを効かせることが可能です。
しかし、我々のセルフホストランナーは環境をクリーンにするためにインスタンスは使いまわさない(1 ジョブ終わったらインスタンスは破棄される)ようにしており、必ず setup-java
を使うジョブで JDK をダウンロードしてしまっているという状況でした。
やりたいこと
そこで、setup-java
でダウンロードする JDK(今回は Amazon Corretto)をあらかじめキャッシュしておいて、転送量を削減したいというのが今回のテーマです。
我々のセルフホストランナーは、ランナーや各種入ってると嬉しいソフトウェア(Docker や jq、GitHub CLI や AWS CLI など)のインストールをあらかじめ行った共通の Amazon Machine Image (AMI) を用意し、その AMI からインスタンスを起動することで、ランナー起動の高速化と利用者のインストール作業の省略を計っています。
AMI 自体は定期的に作成・更新されるようになっており、その AMI に setup-java と同じような方法で JDK をあらかじめインストールしておくことで、setup-java が毎回ダウンロードしなくても済むようにします。
setup-java の JDK キャッシュの仕組み
この方法を考えるにあたって、まず setup-java
が JDK をどうインストールしているのか、どうやってインストール済みと判断しているのかを知る必要があります。
まず前提として、今回は次のような入力を setup-java
に与えているとします。
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018 # v4.2.2
with:
distribution: 'corretto'
java-version: '21'
インストールの大まかな流れは次のようになっています。
キャッシュディレクトリを調べる
「1.1 キャッシュディレクトリより、キャッシュ済みのバージョン一覧を取得」を調べることでどこに JDK をキャッシュしているかがわかります。
tc.findAllVersions()
でキャッシュされている JDK のバージョンを取得しています。この関数は @actions/tool-cache にあります。
@actions/tool-cache
は GitHub Actions の公式ツールキットで、ツールのダウンロードやキャッシュを行うためのユーティリティです。これを使うことで setup-*
系のアクションを作る人はランナーのどこにキャッシュすればいいかを気にせずに済むということですね。
ではどこのディレクトリにキャッシュしているかを調べるために findAllVersions
関数を調べます。
_getCacheDirectory()
があやしいですね。さらに見てみましょう。
どうやら RUNNER_TOOL_CACHE
環境変数を参照しているようです。GitHub Actions マニアの人ならどこかで見たことありませんか?
そう。実は公式ドキュメントにちゃんと載っているんですよね。
RUNNER_TOOL_CACHE
: The path to the directory containing preinstalled tools for GitHub-hosted runners. For more information, see "Using GitHub-hosted runners". For example,C:\hostedtoolcache\windows
https://docs.github.com/en/enterprise-cloud@latest/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
ドキュメントには GitHub ホストランナー用のディレクトリと書いてありますが、セルフホストランナーでも同じように使えるようです。
では環境変数の中身はなんなのか調べてみます。
EC2 でまっさらな Ubuntu のインスタンスを作り、GitHub のドキュメントにあるやり方で手動でセルフホストランナーをセットアップ、起動して実験します。
steps:
- run: echo $RUNNER_TOOL_CACHE
実行結果は次のようになりました。
$ echo $RUNNER_TOOL_CACHE
/home/ssm-user/actions-runner/_work/_tool
ホームディレクトリでランナーセットアップを行ったため、セルフホストランナー関係のファイルは ~/actions-runner
以下に配置されています。
<ランナーのディレクトリ>/_work/_tool
がキャッシュディレクトリとなったようです。
_work
については、ランナーのセットアップ時に聞かれる work folder にあたります。
Enter name of work folder: [press Enter for _work]
<work folder>/_tool
が RUNNER_TOOL_CACHE
になることがわかりました。
キャッシュディレクトリの大元はわかりました。次は JDK がどう配置されるかを調べます。
findAllVersions()
では引数に「ツール名(toolName
)」、「アーキテクチャ(arch
)」を取り、それらを組み合わせて探すディレクトリのパスを構築しています。
toolcacheFolderName
を調べます。
toolcacheFolderName
は Java_<ディストリビューション名>_<パッケージタイプ>
で決定されます。ディストリビューション名は Corretto
、パッケージタイプはデフォルト値の jdk
です。
したがって、toolcacheFolderName
は Java_Corretto_jdk
となります。
architecture
については指定しない場合自動でマシンのアーキテクチャを推定するようです。今回の実験では x64
となりました。
それではとうとう実際に JDK がどこにキャッシュされるかを調べます。
Corretto 21 を setup-java でインストールし、キャッシュディレクトリの構造を調べます。
$ cd ~/actions-runner
$ ls _work/_tool/Java_Corretto_jdk
21.0.4-7.1
$ ls _work/_tool/Java_Corretto_jdk/21.0.4-7.1
x64 x64.complete
$ ls _work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64
ADDITIONAL_LICENSE_INFO ASSEMBLY_EXCEPTION LICENSE README.md bin commitId.txt conf include jmods legal lib man release version.txt
どうやら次のような構成になってるようですね。これで JDK のキャッシュディレクトリの構造がわかりました。
$RUNNER_TOOL_CACHE
└── Java_<ディストリビューション>_jdk (Java_Corretto_jdk)
└── <バージョン> (21.0.4-7.1)
├── <アーキテクチャ>.complete (x64.complete)
└── <アーキテクチャ> (x64)
└── JDK のファイル群
これらがどのように決定されているかと、x64.complete
の謎は findAllVersions()
を読めばわかります。
export function findAllVersions(toolName: string, arch?: string): string[] {
const versions: string[] = [] // 👀 見つけたバージョン一覧
arch = arch || os.arch()
// 👀 arch -> x64
const toolPath = path.join(_getCacheDirectory(), toolName)
// 👀 toolPath -> $RUNNER_TOOL_CACHE/Java_Corretto_jdk -> ~/actions-runner/_work/_tool/Java_Corretto_jdk
if (fs.existsSync(toolPath)) {
const children: string[] = fs.readdirSync(toolPath) // 👀 toolPath ディレクトリ内を抽出
// 👀 children -> ['21.0.4-7.1']
for (const child of children) {
if (isExplicitVersion(child)) { // 👀 バージョンが一意に定まるか?調べてるっぽい
const fullPath = path.join(toolPath, child, arch || '')
// 👀 fullPath -> ~/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64
if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) {
// 👀 組み立てたパスが存在している、
// かつ、~/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64.complete が存在している
versions.push(child)
// 👀 見つけたバージョン一覧に 21.0.4-7.1 を追加
}
}
}
}
return versions
}
バージョンディレクトリ内のアーキテクチャごとに <アーキテクチャ>.complete
というファイルがないとキャッシュされていないと判断されるようですね。
これは注意が必要ですねぇ。
インストールで何をやっているか調べる
ではどのように JDK をインストールしているかを調べます。
setup-java でのインストール方法がわかればそれを真似してうまい具合に同じインストールができるはず。
ダウンロード URL の取得
「2.1: ダウンロード URL の取得」を調べます。
ダウンロード URL は CorrettoDistribution クラスの findPackageForDownload
メソッドで取得しているようです。
findPackageForDownload
は大まかに次のことをやっています。
バージョン一覧は https://corretto.github.io/corretto-downloads/latest_links/indexmap_with_checksum.json
から取得しているようです。ちょっと中をのぞいてみましょう。
たくさんのプラットフォームに対応しているようですが、今回は Ubuntu を想定しているので Linux の部分を見てみます。
{
...
"linux": {
"aarch64": { ... },
"arm": { ... },
"arm-musl": { ... },
"x64": {
"jdk": {
"8": { ... },
"11": { ... },
"15": { ... },
"16": { ... },
"17": { ... },
"18": { ... },
"19": { ... },
"20": { ... },
"21": {
"deb": { ... },
"rpm": { ... },
"tar.gz": {
"checksum": "3f0a55a891b72d567d0e7220777b969a",
"checksum_sha256": "ee88014fe758f93180f34cfca2158de4e1834472136296521998f52e146afb3c",
"resource": "/downloads/resources/21.0.4.7.1/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz"
},
"tar.gz.pub": { ... },
"tar.gz.sig": { ... }
},
"22": { ... },
"23": { ... }
}
},
"x86": { ... }
}
...
}
色々詰まった json となっていますが、次のような構造になっていました。
.
└── <プラットフォーム>
└── <アーキテクチャ>
└── <バージョン>
└── <パッケージタイプ>
└── <ファイルタイプ>
├── checksum
├── checksum_sha256
└── resource
ファイルタイプについて、Linux の場合は tar.gz
になる模様です。
これで resource
にあるパスを組み合わせると我々の求めているダウンロード URL を得られますね。
Ubuntu で Corretto 21 をインストールする場合のダウンロード URL は次のようになります。
https://corretto.aws/downloads/resources/21.0.4.7.1/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz
また、findPackageForDownload
メソッドでは、URL に加えてフルのバージョン番号も呼び出し元関数に返しています。
そもそも OpenJDK には、<メジャー>.<マイナー>.<パッチ>+<ビルド番号>
とするバージョン番号の形式[2]があり、Amazon Corretto もこの形式に従っています。
したがって、ダウンロード URL から取得できる 21.0.4.7.1
は整形されたものであり、実際は 21.0.4+7.1
となります。
このフルのバージョン番号は GitHub Actions でログとして出力されたり、後ほどインストール先ディレクトリを作るために使用されます。
ダウンロードしてインストール
「2.2: ダウンロードしてインストール」を調べます。
インストールは CorrettoDistribution
クラスの downloadTool
メソッドで行っているようです。
大まかに次のことをやっています。
- ダウンロード URL からファイルをダウンロード (ref)
- ダウンロードした tar.gz を展開 (ref)
- バージョン番号の修正 (ref)
- キャッシュディレクトリに配置 (ref)
-
.complete
ファイルを配置 (ref)
3. について、前節で説明した findPackageForDownload
メソッドからフルのバージョン番号(21.0.4+7.1
)を得ましたが、このままでは +
記号があるためディレクトリ名として使えません。したがって、+
を -
に置換しています。ややこしいですね。
5. について、「キャッシュディレクトリを調べる」にもあったように、.complete
ファイルを配置することで JDK がインストール済みと判断されるため、.complete
ファイルの配置が必要です。
.complete
の中身についてですが、どうやら中身は空で良いようです。
なお、我々は最初 .complete ファイルの存在に気づいておらず、ちゃんと展開した tar.gz の中身を置いたのになぜダウンロードが走るのかと頭を抱えました。
setup-java のキャッシュの仕組みを再現する
とうとう本題です。setup-java のキャッシュの仕組みを再現し、あらかじめ Corretto をインストールすることで setup-java が Corretto をダウンロードしないようにしましょう。
setup-java の Corretto キャッシュの仕組みを調べてわかったことをざっくりまとめると次のようになります。
-
RUNNER_TOOL_CACHE
環境変数で指定されているディレクトリに JDK はインストールされる-
$RUNNER_TOOL_CACHE/Java_<ディストリビューション>_jdk/<バージョン>/<アーキテクチャ>
に JDK が配置される
-
- Corretto のダウンロード URL、フルのバージョン番号は https://corretto.github.io/corretto-downloads/latest_links/indexmap_with_checksum.json から取得できる
- バージョン番号はダウンロード URL から取得できるが、
21.0.4.7.1
のような形式から21.0.4-7.1
のような形式に変換してディレクトリを用意する必要がある
- バージョン番号はダウンロード URL から取得できるが、
- インストール済であることを示すために、
$RUNNER_TOOL_CACHE/Java_<ディストリビューション>_jdk/<バージョン>
配下に<アーキテクチャ>.complete
というファイルを配置する必要がある
そしてこれらの情報を踏まえて、次のスクリプトを作成しました。
#!/usr/bin/env bash
set -euxo pipefail
# インストールする Corretto のバージョン
INSTALL_MAJOR_VERSION=21
# RUNNER_TOOL_CACHE に当たるディレクトリ
TOOL_CACHE_DIR=/home/ssm-user/actions-runner/_work/_tool # 環境によって異なることに注意。今回は `/home/ssm-user/actions-runner` 配下でセットアップしたためこのパスとなっている
# ダウンロード情報の取得
CORRETTO_DOWNLOADS=/tmp/corretto_downloads.json
curl -fsSL -o $CORRETTO_DOWNLOADS --retry 3 https://corretto.github.io/corretto-downloads/latest_links/indexmap_with_checksum.json
# ダウンロードURLを取得
JAVA_RESOURCE=$(jq ".linux.x64.jdk.\"${INSTALL_MAJOR_VERSION}\".\"tar.gz\"" ${CORRETTO_DOWNLOADS})
DOWNLOAD_URL_SUFFIX=$(echo ${JAVA_RESOURCE} | jq -r '.resource')
# actions/setup-javaのキャッシュディレクトリと同じ名前になるような置換処理
# Javaのバージョンとしては"+"区切りが正しいがディレクトリとして不正なので"-"に置換している
VERSION=$(echo ${DOWNLOAD_URL_SUFFIX} | awk -F '/' '{print $4}' | sed 's/\./-/3')
# インストール先ディレクトリの作成
JAVA_PATH=${TOOL_CACHE_DIR}/Java_Corretto_jdk/${VERSION}/x64
mkdir -p ${JAVA_PATH}
# ダウンロード
FILENAME=${DOWNLOAD_URL_SUFFIX##*/}
curl -fsSL -o "/tmp/${FILENAME}" --retry 3 "https://corretto.aws${DOWNLOAD_URL_SUFFIX}"
# チェックサムの確認
CHECKSUM_SHA256=$(echo ${JAVA_RESOURCE} | jq -r '.checksum_sha256')
echo "${CHECKSUM_SHA256} /tmp/${FILENAME}" | shasum -a 256 -c
# インストール
# $RUNNER_TOOL_CACHE/Java_Corretto_jdk/17.0.8-7.1/x64 の下に bin/ などが配置されるように展開する
tar xzf /tmp/${FILENAME} --strip-components 1 -C ${JAVA_PATH}
# インストール済であることを示すためのファイルを配置
touch ${JAVA_PATH}.complete
# 後始末
rm /tmp/${FILENAME}
rm ${CORRETTO_DOWNLOADS}
動作確認
では実際に動作確認しましょう。
動作確認の流れは次になります。
- まっさらな EC2 インスタンスを立ち上げる
- jq のインストール
- セルフホストランナーをセットアップする
- Corretto インストールスクリプトを動かして Corretto をインストールする
- ランナーを起動する
- GitHub Actions で setup-java を実行する
1. まっさらな EC2 インスタンスを立ち上げる
今回は Ubuntu 22.04 (ami-0162fe8bfebb6ea16
)の EC2 インスタンスを立ち上げました。
2. jq のインストール
デフォルトでは jq がインストールされていないのでインストールします。
~/actions-runner$ jq --version
jq-1.6
しました。
3. セルフホストランナーをセットアップする
いつもの
今回は手動でセットアップを流す。
/var/snap/amazon-ssm-agent/7993$ cd
~$ mkdir actions-runner && cd actions-runner
~/actions-runner$ curl -o actions-runner-linux-x64-2.319.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.319.0/actions-runner-linux-x64-2.319.0.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 186M 100 186M 0 0 89.1M 0 0:00:02 0:00:02 --:--:-- 122M
~/actions-runner$ echo "52b8f9c5abb1a47cc506185a1a20ecea19daf0d94bbf4ddde7e617e7be109b14 actions-runner-linux-x64-2.319.0.tar.gz" | shasum -a 256 -c
actions-runner-linux-x64-2.319.0.tar.gz: OK
~/actions-runner$ tar xzf ./actions-runner-linux-x64-2.319.0.tar.gz
~/actions-runner$ ./config.sh --name corretto-cache --runnergroup Default --labels corretto-cache --work _work --ephemeral --url ***/github-actions-playground --token ***
--------------------------------------------------------------------------------
| ____ _ _ _ _ _ _ _ _ |
| / ___(_) |_| | | |_ _| |__ / \ ___| |_(_) ___ _ __ ___ |
| | | _| | __| |_| | | | | '_ \ / _ \ / __| __| |/ _ \| '_ \/ __| |
| | |_| | | |_| _ | |_| | |_) | / ___ \ (__| |_| | (_) | | | \__ \ |
| \____|_|\__|_| |_|\__,_|_.__/ /_/ \_\___|\__|_|\___/|_| |_|___/ |
| |
| Self-hosted runner registration |
| |
--------------------------------------------------------------------------------
# Authentication
√ Connected to GitHub
# Runner Registration
√ Runner successfully added
√ Runner connection is good
# Runner settings
√ Settings Saved.
~/actions-runner$
4. Corretto インストールスクリプトを動かして Corretto をインストールする
先ほど書いた Corretto インストールスクリプトを動かします。
~/actions-runner$ vim setup-corretto.sh
~/actions-runner$ chmod +x setup-corretto.sh
~/actions-runner$ ./setup-corretto.sh
+ INSTALL_MAJOR_VERSION=21
+ TOOL_CACHE_DIR=/home/ssm-user/actions-runner/_work/_tool
+ CORRETTO_DOWNLOADS=/tmp/corretto_downloads.json
+ curl -fsSL -o /tmp/corretto_downloads.json --retry 3 https://corretto.github.io/corretto-downloads/latest_links/indexmap_with_checksum.json
++ jq '.linux.x64.jdk."21"."tar.gz"' /tmp/corretto_downloads.json
+ JAVA_RESOURCE='{
"checksum": "3f0a55a891b72d567d0e7220777b969a",
"checksum_sha256": "ee88014fe758f93180f34cfca2158de4e1834472136296521998f52e146afb3c",
"resource": "/downloads/resources/21.0.4.7.1/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz"
}'
++ echo '{' '"checksum":' '"3f0a55a891b72d567d0e7220777b969a",' '"checksum_sha256":' '"ee88014fe758f93180f34cfca2158de4e1834472136296521998f52e146afb3c",' '"resource":' '"/downloads/resources/21.0.4.7.1/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz"' '}'
++ jq -r .resource
+ DOWNLOAD_URL_SUFFIX=/downloads/resources/21.0.4.7.1/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz
++ echo /downloads/resources/21.0.4.7.1/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz
++ awk -F / '{print $4}'
++ sed 's/\./-/3'
+ VERSION=21.0.4-7.1
+ JAVA_PATH=/home/ssm-user/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64
+ mkdir -p /home/ssm-user/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64
+ FILENAME=amazon-corretto-21.0.4.7.1-linux-x64.tar.gz
+ curl -fsSL -o /tmp/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz --retry 3 https://corretto.aws/downloads/resources/21.0.4.7.1/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz
++ echo '{' '"checksum":' '"3f0a55a891b72d567d0e7220777b969a",' '"checksum_sha256":' '"ee88014fe758f93180f34cfca2158de4e1834472136296521998f52e146afb3c",' '"resource":' '"/downloads/resources/21.0.4.7.1/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz"' '}'
++ jq -r .checksum_sha256
+ CHECKSUM_SHA256=ee88014fe758f93180f34cfca2158de4e1834472136296521998f52e146afb3c
+ echo 'ee88014fe758f93180f34cfca2158de4e1834472136296521998f52e146afb3c /tmp/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz'
+ shasum -a 256 -c
/tmp/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz: OK
+ tar xzf /tmp/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz --strip-components 1 -C /home/ssm-user/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64
+ touch /home/ssm-user/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64.complete
+ rm /tmp/amazon-corretto-21.0.4.7.1-linux-x64.tar.gz
+ rm /tmp/corretto_downloads.json
やったか!?
/actions-runner$ ls ~/actions-runner/_work/_tool/ ~/actions-runner/_work/_tool/Java_Corretto_jdk/ ~/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/ ~/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64
/home/ssm-user/actions-runner/_work/_tool/:
Java_Corretto_jdk
/home/ssm-user/actions-runner/_work/_tool/Java_Corretto_jdk/:
21.0.4-7.1
/home/ssm-user/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/:
x64 x64.complete
/home/ssm-user/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64:
ADDITIONAL_LICENSE_INFO ASSEMBLY_EXCEPTION LICENSE README.md bin commitId.txt conf include jmods legal lib man release version.txt
ディレクトリ構造は想定通り。
5. ランナーを起動する
~/actions-runner$ ./run.sh
6. GitHub Actions で setup-java を実行する
次のような GitHub Actions ワークフローを流します。
runs-on: [self-hosted, corretto-cache]
steps:
- uses: actions/setup-java@v4
with:
distribution: 'corretto'
java-version: '17'
- run: java --version
- uses: actions/setup-java@v4
with:
distribution: 'corretto'
java-version: '21'
- run: java --version
比較できるようにキャッシュ済みの Corretto 21 とキャッシュされていない Corretto 17 を setup-java でインストールしてみます。
Run actions/setup-java@v4
with:
distribution: corretto
java-version: 17
java-package: jdk
check-latest: false
server-id: github
server-username: GITHUB_ACTOR
server-password: GITHUB_TOKEN
overwrite-settings: true
job-status: success
token: ***
Installed distributions
Trying to resolve the latest version from remote
Print information about available versions
Retrieving available versions for Coretto took: 81.543ms
Resolved latest version as 17.0.12+7.1
Trying to download...
Downloading Java 17.0.12+7.1 (Corretto) from https://corretto.aws/downloads/resources/17.0.12.7.1/amazon-corretto-17.0.12.7.1-linux-x64.tar.gz ...
Extracting Java archive...
/usr/bin/tar xz -v --warning=no-unknown-keyword --overwrite -C /home/ssm-user/actions-runner/_work/_temp/64177bce-c48b-4f4c-ab43-bd39ebd4e66d -f /home/ssm-user/actions-runner/_work/_temp/be07c810-3657-4266-8a28-e8eb27f16050
<展開のログ>
Java 17.0.12+7.1 was downloaded
Setting Java 17.0.12+7.1 as the default
Creating toolchains.xml for JDK version 17 from corretto
Overwriting existing file /home/ssm-user/.m2/toolchains.xml
Java configuration:
Distribution: corretto
Version: 17.0.12+7.1
Path: /home/ssm-user/actions-runner/_work/_tool/Java_Corretto_jdk/17.0.12-7.1/x64
Run java --version
openjdk 17.0.12 2024-07-16 LTS
OpenJDK Runtime Environment Corretto-17.0.12.7.1 (build 17.0.12+7-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.12.7.1 (build 17.0.12+7-LTS, mixed mode, sharing)
Downloading Java 17.0.12+7.1 ...
がログに出たように、今回キャッシュしていない Corretto 17 はダウンロードが走りました。想定通りです。
ちなみにインストールには 15 秒ほどかかりました。
Run actions/setup-java@v4
Installed distributions
Resolved Java 21.0.4+7.1 from tool-cache
Setting Java 21.0.4+7.1 as the default
Creating toolchains.xml for JDK version 21 from corretto
Overwriting existing file /home/ssm-user/.m2/toolchains.xml
Java configuration:
Distribution: corretto
Version: 21.0.4+7.1
Path: /home/ssm-user/actions-runner/_work/_tool/Java_Corretto_jdk/21.0.4-7.1/x64
Creating settings.xml with server-id: github
Overwriting existing file /home/ssm-user/.m2/settings.xml
Run java --version
openjdk 21.0.4 2024-07-16 LTS
OpenJDK Runtime Environment Corretto-21.0.4.7.1 (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.4.7.1 (build 21.0.4+7-LTS, mixed mode, sharing)
Resolved Java 21.0.4+7.1 from tool-cache
がログに出たように、キャッシュ済みの Corretto 21 はダウンロードが走りませんでした!!
ちなみにインストールには 1 秒もかかりませんでした!
やりましたね!
やってみて
冒頭でも説明した通り、今回の内容は以前発表したスライドにおける、Amazon Corretto のキャッシュについて詳しく説明したものでした。
実際に今回の方法を取ったのはもう 1 年ほど前になるのですが、我々の目論見通り、転送量上位から corretto.aws
がいなくなり、転送料金削減につながりました。
今回は setup-java における Amazon Corretto をキャッシュしましたが、今回の知見をもとにその他の setup-* 系アクションの事前のキャッシュにも適用できると考えます。
とはいえ、発表スライドにもあるように、どの通信にお金がかかっているかを把握し、優先度をつけて対応することが大事です。まずは計測してみましょう。
もし今後 setup-node や setup-python などのアクションを使った際の転送量が上位に来てまあまあな額になっていたら今回の方法はまた使えそうですね。
おわりに
今回は GitHub Actions の setup-java における Amazon Corretto のキャッシュを再現し、ランナーを起動する前にキャッシュすることでダウンロードをスキップする方法を紹介しました。
これにより、我々のセルフホストランナー環境における転送量、転送料金の削減が実現できました。
なかなか GitHub Actions、setup-java の表に出づらい知識が求められるため、当時はコードリーディングと試行錯誤に時間をかけていました。当時関わった人みんな大変だったと言ってた思い出です。
これを読んでくれた皆さんも、GitHub Actions 関連のソースコードを読んでみて深淵に近づきましょう。
さて、実はこの記事は CYBOZU SUMMER BLOG FES '24 (生産性向上セイサンシャインビーチ Stage) DAY 6 の記事でした。明日は @miyajan さんの記事が飛び出ることでしょう。お楽しみに!
Discussion