我從 Day 18 開始評估如何 porting GitLab CI/CD Pipelines 成 GitHub Actions,過去是採用「runner 在 container 內、job 也在獨立的 container 內執行」的執行模式,如果 GitHub 有一樣的模式可以照搬,那就可以省很多功夫在 porting 上。
我評估了一下,執行 CI/CD job 的方式若以「是否採用容器化技術」來做區別的話,有 4 種組合:
run:
) 給弄亂今天繼續看 3.,目標是實驗 self-hosted runner 是否也可以在 container 內執行 job。
我想做個實驗:測試 self-hosted runner 執行 workflow 時不跑在 container 裡面,跟跑在 container 裡面時有甚麼差別。
Workflow 現在有 2 個
containerized-build.yml
(原本的 main.yml
)non-containerized-build.yml
其中 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 點不同:
build
job 未定義 container:
Checkout code
後面多了一步 Setup .NET SDK
,使用官方的 action 來下載安裝 .NET SDK。另外,containerized-build.yml
裡面記得也把 runs-on
改為 self-hosted
。
一樣直接上。
這次我不再以 root 帳號執行 self-hosted runner,盡量貼近實際部署時的情況。
來看看這兩個 workflow 的執行結果吧:
嗯?一個成功,一個失敗?
看到這個結果時有點意外,我以為要不是全部成功,要不然就是全部失敗。
看一下為什麼不使用 container 的 workflow 為什麼失敗:
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」有多危險。
來看一下今天的主角:「runner 不在 container 內,job 執行於另一個 container 內」的 workflow 執行起來如何:
正常,非常好
今天的實驗證明我們至少要把某種東西放在 container 內執行,runner 或是 job 都好,但我的希望其實放在最後一種組合:「runner 位於 container 內,job 執行於另一個 container 內」
明天我們再來看最後一種組合。