在 Fedora CoreOS 上运行 GitHub Actions
CI CD GitHub
![](/data/attachment/album/202110/03/110314hhrbobyxzd55dhho.jpg)


[GitHub Actions](https://docs.github.com/en/actions) 是一项为快速建立持续集成和交付（CI/CD）工作流程而提供的服务。这些工作流程在被称为“<ruby> 运行器 <rt>  runner </rt></ruby>”的主机上运行。GitHub 提供的 [托管运行器](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners) 的操作系统的选择是有限的（Windows Server、Ubuntu、MacOS）。


另一个选择是使用 [自托管](https://docs.github.com/en/actions/hosting-your-own-runners) 的运行器，这让仓库管理员对运行器有更多控制。自托管的运行程序是专门为某个存储库或组织服务的。下面的文章介绍了使用 Fedora CoreOS 配置自托管运行程序的步骤。


### 入门


Fedora CoreOS 是一个精简的操作系统，旨在便于大规模的部署和维护。该操作系统会自动更新，并默认提供运行容器所需的工具。由于这些原因，Fedora CoreOS 是运行 CI/CD 工作流程的一个极佳选择。


配置和配备 Fedora CoreOS 机器的第一步是生成一个 [Ignition](https://github.com/coreos/ignition) 文件。[Butane](https://github.com/coreos/butane) 允许你使用更友好的格式（YAML）生成 Ignition 文件。


#### 配置一个 Fedora CoreOS 运行器


要在 Fedora CoreOS 上执行 GitHub Actions，托管主机需要用于注册和运行该运行器的二进制文件和脚本。从 [Actions 运行器项目](https://github.com/actions/runner) 下载二进制文件和脚本，并部署在 `/usr/local/sbin/actions-runner` 下。



```
version: "1.3.0"
variant: fcos
storage:
  directories:
    - path: /usr/local/sbin/actions-runner
      mode: 0755
      user:
        name: core
      group:
        name: core
  files:
    - path: /usr/local/sbin/actions-runner/actions-runner-linux.tar.gz
      overwrite: true
      contents:
        source: https://github.com/actions/runner/releases/download/v2.278.0/actions-runner-linux-x64-2.278.0.tar.gz
      mode: 0755
      user:
        name: core
      group:
        name: core

```

#### 注册和删除令牌


为一个项目配置运行器需要一个“<ruby> 令牌 <rt>  token </rt></ruby>”。这可以防止在没有正确权限的情况下从项目中注册或删除自托管的运行器。GitHub 提供的令牌有一个小时的过期时间。如果运行器在这个时间之后重新启动，它将需要一个新的注册令牌。


该令牌可能出问题，特别是在 Fedora CoreOS 自动更新时。更新过程希望托管主机在收到新数据后至少每隔几周重启一次。


幸运的是，可以使用 GitHub REST API 来获取这些令牌，并在托管主机每次重启时自动配置运行器。下面的 `manage-runner.sh` 脚本使用 API 来获取令牌，删除任何已经配置好的运行器，并用新的令牌注册运行器。



```
#!/bin/bash
# Handles the Github Action runner configuration.
# Remove and Registration token expires after 1 hour, if we want our runner
# to work after a reboot (auto update) we need to refresh the tokens.

# First remove the runner with a fresh remove token
REMOVE_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/actions/runners/remove-token | jq -r '.token')
/usr/local/sbin/actions-runner/config.sh remove --token ${REMOVE_TOKEN}


# Then register the runner with a fresh registration token
REGISTRATION_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/actions/runners/registration-token | jq -r '.token')
/usr/local/sbin/actions-runner/config.sh --url https://github.com/cverna/fcos-actions-runner --token ${REGISTRATION_TOKEN} --labels fcos --unattended

```

上面的脚本使用了一些环境变量，包含 GitHub 用户名和用于验证 REST API 请求的 <ruby> <a href="https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token">  个人访问令牌 </a> <rt>  Personal Access Token </rt></ruby>。个人访问令牌需要存储库权限，以便成功检索运行器的注册和移除令牌。该令牌是安全敏感信息，所以最好将其存储在一个具有更严格权限的不同文件中。在这个例子中，这个文件是 `actions-runner`。



```
GITHUB_USER=<user>
GITHUB_REPO=<repo>
GITHUB_TOKEN=<personal_access_token>

```

以下是创建这两个文件 `manage-runner.sh` 和 `actions-runner` 的 Butane 片段。



```
- path: /usr/local/sbin/actions-runner/manage-runner.sh
      contents:
        local: manage-runner.sh
      mode: 0755
      user:
        name: core
      group:
        name: core
    - path: /etc/actions-runner
      contents:
        local: actions-runner
      mode: 0700
      user:
        name: core
      group:
        name: core

```

### 在 Fedora CoreOS 上运行 Actions


最后，创建用于配置和启动运行器的 systemd 服务。在 Butane 配置文件中定义这些服务。



```
systemd:
  units:
    - name: github-runner-configure.service
      enabled: true
      contents: |
        [Unit]
        Description=Configure the github action runner for a repository
        After=network-online.target boot-complete.target
        Requires=boot-complete.target
        [Service]
        EnvironmentFile=/etc/actions-runner
        Type=oneshot
        RemainAfterExit=yes
        User=core
        WorkingDirectory=/usr/local/sbin/actions-runner
        ExecStartPre=tar xvf actions-runner-linux.tar.gz --no-same-owner
        ExecStart=/usr/local/sbin/actions-runner/manage-runner.sh
        [Install]
        WantedBy=multi-user.target
    - name: github-runner.service
      enabled: true
      contents: |
        [Unit]
        Description=Run the github action runner
        After=github-runner-configure.service
        [Service]
        WorkingDirectory=/usr/local/sbin/actions-runner
        User=core
        ExecStart=/usr/local/sbin/actions-runner/run.sh
        [Install]
        WantedBy=multi-user.target

```

这将创建两个服务：`github-runner-configure.service`（在主机启动完成后运行一次）和 `github-runner.service`（运行 Actions 运行器二进制文件并等待新的 CI/CD 作业）。


现在 Butane 配置已经完成，从中生成一个 Ignition 文件并配备一个 Fedora CoreOS Actions 运行器。



```
$ podman run -i --rm -v $PWD:/code:z --workdir /code quay.io/coreos/butane:release --pretty --strict --files-dir /code config.yaml -o config.ignition

```

一旦 Ignition 文件生成，它就可以用来在 [支持](https://docs.fedoraproject.org/en-US/fedora-coreos/bare-metal/) Fedora CoreOS 的平台上配备一个运行器。


### 配置一个 Action 来使用一个自托管的运行器


下面的测试 Action 工作流程将测试 FCOS 的自托管的运行器。在你的 git 存储库中创建以下文件 `.github/workflows/main.yml`。



```
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run.
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: fcos

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: podman run --rm fedora-minimal:34 echo Hello World !

```

请注意，`runs-on` 的配置被设置为使用标签为 `fcos` 的运行器。


本文介绍的代码可以在 [这里](https://github.com/cverna/fcos-actions-runner) 中找到。




---


via: <https://fedoramagazine.org/run-github-actions-on-fedora-coreos/>


作者：[Clément Verna](https://fedoramagazine.org/author/cverna/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
[GitHub Actions](https://docs.github.com/en/actions) is a service provided to quickly setup continuous integration and delivery (CI/CD) workflows . These workflows run on hosts called *runners*. GitHub provides [hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners) with a limited set of operating system choice (Windows Server, Ubuntu, MacOS).

Another option is to use [self-hosted](https://docs.github.com/en/actions/hosting-your-own-runners) runners which gives the repository administrator more control on the runners. Self-hosted runners are dedicated to a repository or organization. The following article goes through the steps of configuring self-hosted runners using Fedora CoreOS.

## Getting Started

Fedora CoreOS is a minimalist operating system designed to be easy to deploy and maintain at scale. The operating system will automaticaly update and provide, by default, the tools needed to run containers. For all of these reasons, Fedora CoreOS is a great choice to consider for running CI/CD workflows.

The first step to configure and provision a Fedora CoreOS machine is to generate an [Ignition](https://github.com/coreos/ignition) file. [Butane](https://github.com/coreos/butane) allows you to generate Ignition’s file using a friendlier format (YAML).

### Configure a Fedora CoreOS runner

To execute GitHub actions on Fedora CoreOS, the host needs the binaries and scripts used to register and run the runner. Download the binaries and scripts from the [actions runner project](https://github.com/actions/runner) and deploy under */usr/local/sbin/actions-runner*.

version: "1.3.0" variant: fcos storage: directories: - path: /usr/local/sbin/actions-runner mode: 0755 user: name: core group: name: core files: - path: /usr/local/sbin/actions-runner/actions-runner-linux.tar.gz overwrite: true contents: source: https://github.com/actions/runner/releases/download/v2.278.0/actions-runner-linux-x64-2.278.0.tar.gz mode: 0755 user: name: core group: name: core

### Registration and Removal token

Configuring runners for a project requires a “token”. This prevents registering or removing self-hosted runners from projects without the correct permissions. Tokens provided by Github have a one hour expiration time. If the runner restarts after this time it will require a new registration token.

The token can be problematic, in particular with Fedora CoreOS automatic updates. The update process expects that the host will restart at least once every couple weeks after receiving new data.

Luckily, it is possible to use GitHub REST API to obtain these tokens and automatically configure the runner every time the host restarts. The following *manage-runner.sh* script uses the APIs to retrieve a token, remove any runner already configured and register the runner with a new token.

#!/bin/bash # Handles the Github Action runner configuration. # Remove and Registration token expires after 1 hour, if we want our runner # to work after a reboot (auto update) we need to refresh the tokens. # First remove the runner with a fresh remove token REMOVE_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/actions/runners/remove-token | jq -r '.token') /usr/local/sbin/actions-runner/config.sh remove --token ${REMOVE_TOKEN} # Then register the runner with a fresh registration token REGISTRATION_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/actions/runners/registration-token | jq -r '.token') /usr/local/sbin/actions-runner/config.sh --url https://github.com/cverna/fcos-actions-runner --token ${REGISTRATION_TOKEN} --labels fcos --unattended

The script above uses a few environment variables that contain a GitHub username and a [Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) used to authenticate the REST API requests. The Personal Access Token requires the repo permissions in order to successfully retrieve the runner registration and removal tokens. The token is security sensitive so it is better to store it in a different file with stricter permissions. In this example that file is *actions-runner*.

GITHUB_USER=<user> GITHUB_REPO=<repo> GITHUB_TOKEN=<personal_access_token>

Following is the Butane snippet that creates these two files – *manage-runner.sh* and *actions-runner*.

- path: /usr/local/sbin/actions-runner/manage-runner.sh contents: local: manage-runner.sh mode: 0755 user: name: core group: name: core - path: /etc/actions-runner contents: local: actions-runner mode: 0700 user: name: core group: name: core

## Running Actions on Fedora CoreOS

Finally, create the systemd services that will configure and start the runner. Define the services in the Butane configuration file.

systemd: units: - name: github-runner-configure.service enabled: true contents: | [Unit] Description=Configure the github action runner for a repository After=network-online.target boot-complete.target Requires=boot-complete.target [Service] EnvironmentFile=/etc/actions-runner Type=oneshot RemainAfterExit=yes User=core WorkingDirectory=/usr/local/sbin/actions-runner ExecStartPre=tar xvf actions-runner-linux.tar.gz --no-same-owner ExecStart=/usr/local/sbin/actions-runner/manage-runner.sh [Install] WantedBy=multi-user.target - name: github-runner.service enabled: true contents: | [Unit] Description=Run the github action runner After=github-runner-configure.service [Service] WorkingDirectory=/usr/local/sbin/actions-runner User=core ExecStart=/usr/local/sbin/actions-runner/run.sh [Install] WantedBy=multi-user.target

This creates two services, *github-runner-configure.service *(running once when the host has finished booting) and *github-runner.service *(running the Actions runner binaries and waiting for new CI/CD jobs).

Now that the Butane configuration is complete, generate an Ignition file out of it and provision a Fedora CoreOS Actions runner.

$ podman run -i --rm -v $PWD:/code:z --workdir /code quay.io/coreos/butane:release --pretty --strict --files-dir /code config.yaml -o config.ignition

Once the Ignition file is generated, it can be used to provision a runner on the platforms where Fedora CoreOS is [available](https://docs.fedoraproject.org/en-US/fedora-coreos/bare-metal/).

## Configure an Action to use a self-hosted runner

The following test Action workflow will test the FCOS self-hosted worker. Create the following file in your git repository *.github/workflows/main.yml*

# This is a basic workflow to help you get started with Actions name: CI # Controls when the action will run. on: # Triggers the workflow on push or pull request events but only for the main branch push: branches: [ main ] pull_request: branches: [ main ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on runs-on: fcos # Steps represent a sequence of tasks that will be executed as part of the job steps: # Runs a single command using the runners shell - name: Run a one-line script run: podman run --rm fedora-minimal:34 echo Hello World !

Note that the *runs-on* configuration is set up to use a runner with the label *fcos*.

The code presented in this article is available [here](https://github.com/cverna/fcos-actions-runner).

## GitLabber

Very nice. One can also use docker images, though compute time limits and overhead still make a self configured runner useful.

## VladimirSlavik

Thank you, that’s a nice concise write-up.

## Ralf Seidenschwang

https://coreos.github.io/ignition/supported-platforms/

I‘m not pretty sure what this kernel parameter does? This seems to be for installation without any disks, so the kernel pulls the configuration from a link and configures the machine according to the config-files that was downloaded, and I assume disk partitioning is one of the tasks that can be found here. So the disks are not in use here and the pulled configuration via this Kernel parameter can be applied to the disks without the disks being touched upfront.

This sounds reasonable, but I would be very cautious with these automatic installation methods that are available for different products (like OpenShift), since they are pulling the same files from a internet source, ignoring my firewall settings completely.

Is that the way these installer scripts work?

## Sergey

Sorry to be off-topic, but I don’t think that’s what fcos is for. In my opinion, fkos is only supposed to ensure the launch of containers and no more.

And everything else should already be in them. For example the same ubi, etc.

## Elliott

I have to agree with Sergey; this really isn’t a use case for FCOS. FCOS is for having a clean, immutable environment for hosting containers. If you want to run your Github actions in a clean immutable image, then that is a great use case for running a container on FCOS.

The benefit of using a container on top of FCOS is that you can have multiple images with multiple runners. Maybe you’re compiling and packaging an application? Well with containers you can have a Fedora, RHEL, Debian, and an Ubuntu image so now you’re application gets compiled and packaged for all of them while only requiring a single FCOS host.

If you’re don’t have to use Github but want to pipeline your application, I’d recommend Gitlab instead. They have an RPM package for their runner. You can have the ignition file install the RPM and the podman-docker package, register the runner, and then set the executor to Docker. Then your pipelines can deploy images and containers on demand for running your jobs.

## Clément Verna

My interest in using FCOS in that case was to be able to very easily destroy and provision new runners. And also not having to care about updating the host since FCOS does that automatically for me.

With that configuration I can have a couple of long running runners, and quickly (a minute or so) burst new runners if needed.

Running GitLab CI runner on FCOS would be super interesting too, I believe that they provide a container image which could make it super easy.

Would you be interested do write a Fedora Magazine article about it ?

## Stephen Snow

Nice article Clement. Thanks for more useful tips, and another very suitable use for FCOS, as a Github Actions server.

## Ralf Seidenschwang

For people relatively new to the topic:

I’ve found that very helpful, the tutorial is half an hour long:

https://www.youtube.com/watch?v=R8_veQiYBjI

## Jiri Konecny

Hi, I just want to warn anyone using this guide. The guide is correct but GitHub self hosted runners are not recommended by GitHub because they are easy to attack.

Problem starts when external contributor will create a PR with a change to GitHub workflow. One problem is that external contributor could attach your self-hosted runner to any existing workflow with a pull_request trigger by just changing the workflow. The second problem is that the self-hosted runner immediately executing any code written to PR. So it’s pretty easy to use your host to access internal resources or use your runner for crypto currency mining.

To avoid such an issue you can do three things.

– Use private repository.

– Use only

and not

trigger. (beware, if you do it wrong, contributor has a write permissions and access to your secrets)

– Manually gate all external contributors to verify that they don’t changing your workflow. (See the third option here: https://github.blog/changelog/2021-07-01-github-actions-new-settings-for-maintainers/ )

## Aricjoshua

In that situation, my motivation for utilizing FCOS was to be able to quickly delete and provide new runners. Also, I don’t have to worry about upgrading the host because FCOS does it for me.

With that setup, I can have a few long-distance runners and rapidly (a minute or two) blast in fresh runners if needed. https://cookieclicker2.io/

Thank you!