Skip to content

Scaling Up Runners

vzakaznikov edited this page Feb 28, 2024 · 2 revisions

The program scales up runners by looking for any jobs that have queued status. For each such job, a corresponding Hetzner Cloud server instance is created with the following name:

github-hetzner-runner-{job.run_id}-{job.id}

The server is configured using the default setup and startup scripts. The default setup.sh script is defined in testflows/github/hetzner/runners/scripts/setup.sh. The default startup-x64.sh and startup-arm64.sh scripts are defined in testflows/github/hetzner/runners/scripts/startup-x64.sh and testflows/github/hetzner/runners/scripts/startup-x64.sh.

The runner's name is set to be the same as the server name so that servers can be deleted for any unused runner that, for some reason does not pick up a job for which it was created within the max-unused-runner-time period.

Note: Given that the server name is fixed and specific for each job.id, if multiple github-hetzner-runners are running in parallel, then only one server will be created for a given job, and any other attempts to create a server with the same name will be rejected by the Hetzner Cloud.

Also,

Note: There is no guarantee that a given runner will pick the job with the exact job.id that caused it to be created. This is expected, and for each queued job a unique runner will be created. The number of runners will be equal the number of jobs, and therefore, under normal conditions, all jobs will be executed as expected.

Maximum Number of Runners

By default, the maximum number of runners and, therefore, the maximum number of server instances are not set and are therefore unlimited. You can set the maximum number of runners using the --max-runners option.

github-hetzner-runners --max-runners 10

New Server

The new server is accessed using SSH. It boots up with the specified OS image and is configured using the setup and startup scripts.

Server Type:

The default server type is cx11 which is an Intel, 1 vCPU, 2GB RAM shared-cpu x64 instance.

You can specify different x64 server instance type by using the type-{name} runner label. The {name} must be a valid Hetzner Cloud server type name such as cx11, cpx21 etc.

For example, to use an AMD, 3 vCPU, 4GB RAM shared-cpu x64 instance, you can define the runs-on as follows:

job-name:
   runs-on: [self-hosted, type-cpx21]
Server Location:

The server location can be specified by using the --default-location option or the in-<name> runner label. By default, location is not set, as some server types are not available in some locations.

Image:

The server is configured to have the image specified by the --default-image option or the image-{architecture}-{type}-{name} runner label.

SSH Access:

The server is configured to be accessed using the ssh utility, and the SSH public key path is specified using the --ssh-key option.

Image Configuration:

Each new server instance is configured using the setup and the startup scripts.

The Setup Script

The setup script creates and configures a runner user that has sudo privileges.

The default setup.sh script is defined in testflows/github/hetzner/runners/scripts/setup.sh.

You can specify a custom setup script if needed. See Specifying The Custom Runner Server Setup Script.

Setup:
set -x

echo "Create and configure ubuntu user"

adduser ubuntu --disabled-password --gecos ""
echo "%wheel   ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers
addgroup wheel
usermod -aG wheel ubuntu
usermod -aG sudo ubuntu

The Start-up Script

The startup script installs the GitHub Actions runner. After installation, it configures the runner to start in an --ephemeral mode. The --ephemeral mode causes the runner to exit as soon as it completes a job. After the runner exits, the server is powered off.

The default startup-x64.sh and startup-arm64.sh scripts are defined in testflows/github/hetzner/runners/scripts/startup-x64.sh and testflows/github/hetzner/runners/scripts/startup-x64.sh.

You can specify a custom startup script if needed. See Specifying The Custom Runner Server Startup Script.

✋ Note: The startup script is executed as a ubuntu user, and therefore you must use sudo for any commands that need root privileges.

The x64 startup script installs and configures the x64 version of the runner.

x64:
set -x
echo "Install runner"
cd /home/ubuntu
curl -o actions-runner-linux-x64-2.306.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.306.0/actions-runner-linux-x64-2.306.0.tar.gz
echo "b0a090336f0d0a439dac7505475a1fb822f61bbb36420c7b3b3fe6b1bdc4dbaa  actions-runner-linux-x64-2.306.0.tar.gz" | shasum -a 256 -c
tar xzf ./actions-runner-linux-x64-2.306.0.tar.gz

echo "Configure runner"
./config.sh --unattended --replace --url https://github.com/${GITHUB_REPOSITORY} --token ${GITHUB_RUNNER_TOKEN} --name "$(hostname)" --runnergroup "${GITHUB_RUNNER_GROUP}" --labels "${GITHUB_RUNNER_LABELS}" --work _work --ephemeral

echo "Start runner"
bash -c "screen -d -m bash -c './run.sh; sudo poweroff'"

The ARM64 startup script is similar to the x64 script but installs an ARM64 version of the runner.

ARM64:
set -x
echo "Install runner"
cd /home/ubuntu

curl -o actions-runner-linux-arm64-2.306.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.306.0/actions-runner-linux-arm64-2.306.0.tar.gz# Optional: Validate the hash
echo "842a9046af8439aa9bcabfe096aacd998fc3af82b9afe2434ddd77b96f872a83  actions-runner-linux-arm64-2.306.0.tar.gz" | shasum -a 256 -c# Extract the installer
tar xzf ./actions-runner-linux-arm64-2.306.0.tar.gz

echo "Configure runner"
./config.sh --unattended --replace --url https://github.com/${GITHUB_REPOSITORY} --token ${GITHUB_RUNNER_TOKEN} --name "$(hostname)" --runnergroup "${GITHUB_RUNNER_GROUP}" --labels "${GITHUB_RUNNER_LABELS}" --work _work --ephemeral

echo "Start runner"
bash -c "screen -d -m bash -c './run.sh; sudo poweroff'"
Clone this wiki locally