iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0
自我挑戰組

30天打造自己的RSS閱讀器:Go語言與DevOps的實戰應用系列 第 20

Day 20:番外篇 - 自架的 GitHub Actions Runner 如何在 container 內執行工作

  • 分享至 

  • xImage
  •  

我從 Day 18 開始評估如何 porting GitLab CI/CD Pipelines 成 GitHub Actions,過去是採用「runner 在 container 內、job 也在獨立的 container 內執行」的執行模式,如果 GitHub 有一樣的模式可以照搬,那就可以省很多功夫在 porting 上。

我評估了一下,執行 CI/CD job 的方式若以「是否採用容器化技術」來做區別的話,有 4 種組合:

  1. runner 不在 container 內,job 執行不另外開 container
    • 官方文件的最基本設定方式,我們在 Day 17 的旅程中已確定可行
  2. runner 位於 container 內,job 執行不另外開 container
    • 執行環境與 host 有基本的隔離,至少 host 不會輕易地被 shell 指令 (run:) 給弄亂
    • 我們在 Day 18 已確定可行
  3. runner 不在 container 內,job 執行於另一個 container 內
    • 官方文件有教學,Day 19 已經確認可以在 GitHub 提供的 runner 環境執行
  4. runner 位於 container 內,job 執行於另一個 container 內 (Docker in Docker)
    • 目前我部門的 GitLab CI/CD Pipeline 使用此方式執行
    • 能不能執行是個未知數

今天繼續看 3.,目標是實驗 self-hosted runner 是否也可以在 container 內執行 job。

更新 workflow

我想做個實驗:測試 self-hosted runner 執行 workflow 時不跑在 container 裡面,跟跑在 container 裡面時有甚麼差別。

Workflow 現在有 2 個

  • containerized-build.yml (原本的 main.yml)
  • non-containerized-build.yml

https://ithelp.ithome.com.tw/upload/images/20230923/20162813qypeeV10B0.png

其中 non-containerized-build.yml workflow 定義如下:

name: .NET Core CI/CD in non-Containerized Environment

on:
  push:
    branches:
      - main

jobs:
  build:
    # 執行在自建 runner 上
    runs-on: self-hosted
    
    # 不再定義 container
    # container:
	#   image: mcr.microsoft.com/dotnet/sdk:6.0

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

	# 這邊使用官方提供的 action 來安裝 .NET SDK
    - name: Setup .NET SDK
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: '6.0.x'
        
    - name: Restore dependencies
      run: dotnet restore
      
    # 後面跟昨天的 workflow 一樣,省略 ...

可以看到有 3 點不同:

  • 執行在自建 runner 上
  • build job 未定義 container:
  • Checkout code 後面多了一步 Setup .NET SDK,使用官方的 action 來下載安裝 .NET SDK。

另外,containerized-build.yml 裡面記得也把 runs-on 改為 self-hosted

執行 workflow

一樣直接上。
這次我不再以 root 帳號執行 self-hosted runner,盡量貼近實際部署時的情況。

來看看這兩個 workflow 的執行結果吧:

https://ithelp.ithome.com.tw/upload/images/20230923/20162813U7rIYfiWqF.png

嗯?一個成功,一個失敗?

看到這個結果時有點意外,我以為要不是全部成功,要不然就是全部失敗。

執行 job 時不使用 container

看一下為什麼不使用 container 的 workflow 為什麼失敗:

https://ithelp.ithome.com.tw/upload/images/20230923/20162813wOjl4GteXr.png

Annotations 的訊息已經說明了一切:

Failed to install dotnet, exit code: 1. mkdir: cannot create directory ‘/usr/share/dotnet’: Permission denied

再點進去看詳細訊息,可以看到 Setup .NET SDK 這一步竟然想在 /usr/share 裡面裝東西:

Run actions/setup-dotnet@v3
[2](https://github.com/..../actions/runs/.../job/...#step:3:2) with:
[3](https://github.com/..../actions/runs/.../job/...#step:3:3) dotnet-version: 6.0.x
[4](https://github.com/..../actions/runs/.../job/...#step:3:4) cache: false
[5](https://github.com/..../actions/runs/.../job/...#step:3:6)/home/**masked**/_work/_actions/actions/setup-dotnet/v3/externals/install-dotnet.sh --channel 6.0
[6](https://github.com/..../actions/runs/.../job/...#step:3:7)mkdir: cannot create directory ‘/usr/share/dotnet’: Permission denied
[7](https://github.com/..../actions/runs/.../job/...#step:3:8)Error: Failed to install dotnet, exit code: 1. mkdir: cannot create directory ‘/usr/share/dotnet’: Permission denied

這進一步證明:在不是一次性 VM 的環境,「runner 不在 container 內,job 執行不另外開 container」有多危險。

執行 job 時使用 container

來看一下今天的主角:「runner 不在 container 內,job 執行於另一個 container 內」的 workflow 執行起來如何:

正常,非常好

https://ithelp.ithome.com.tw/upload/images/20230923/20162813xX13ETLIAF.png

今天的實驗證明我們至少要把某種東西放在 container 內執行,runner 或是 job 都好,但我的希望其實放在最後一種組合:「runner 位於 container 內,job 執行於另一個 container 內」

明天我們再來看最後一種組合。


上一篇
Day 19:番外篇 - GitHub Actions 跟 GitLab CI/CD 執行方式有些不同
下一篇
Day 21:番外篇 - 挑戰 Docker Swarm 多開 GitHub Actions Runner
系列文
30天打造自己的RSS閱讀器:Go語言與DevOps的實戰應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言