Github action self-hosted runner 사용시 주의사항 (feat. use container)
ruinnel
gitgithubgithub-actionself-hosted runnerdocker
888 Words CHANGE ME READ TIME 4 Minutes, 2 Seconds
2024-12-27 06:52 +0000
한줄 정리
- github-action self-hosted runner에서
jobs.<job_id>.container
를 사용 할 경우, checkout이나 build output들이 root 권한으로 생성되어jobs.<job_id>.container
를 사용하지 않은 job이 실패 할 수 있습니다.
권한 문제 발생
이 github action은 cleanup
에서 삭제 rm -rf dist;
명령은 파일 접근 권한이 없어서 실패하게 됩니다
name: publish
on:
push:
tags:
- "*"
jobs:
build:
runs-on: [self-hosted, Linux]
container:
image: "node:22"
steps:
- name: checkout code
uses: actions/checkout@v4
- name: build observable
run: |
make publish out-dir=./dist;
cleanup:
runs-on: [self-hosted, Linux]
needs: build
steps:
- name: remove build output
run: |
rm -rf dist;
왜?
- 이유 아래 2가지가 원인 입니다.
- docker container 내에서 실행 되는 명령은 기본적으로 root 권한(
userID=0
)으로 실행 됩니다. - github action에서 container를 사용하게 되면 workspace 및 temp 디렉토리는 container 없이 실행할때와 동일한 경로의 디렉토리가 container에 mount 되는 형태로 작동 합니다.
- github action의 로그 중
Initialize containers
의 로그를 보면 알 수 있습니다.
- github action의 로그 중
- docker container 내에서 실행 되는 명령은 기본적으로 root 권한(
/usr/bin/docker create --name 34ab908b78a34c2a9ff8116de7bb9d7e_node22_a144dc \
--label b3cf3f --workdir /__w/<repository-name>/<repository-name> \
--network github_network_086481fb0d294dcc870557186e416af1 \
-e "HOME=/github/home" -e GITHUB_ACTIONS=true -e CI=true \
-v "/var/run/docker.sock":"/var/run/docker.sock" \
-v "/home/ruinnel/actions-runner/_work":"/__w" \
-v "/home/ruinnel/actions-runner/externals":"/__e":ro \
-v "/home/ruinnel/actions-runner/_work/_temp":"/__w/_temp" \
-v "/home/ruinnel/actions-runner/_work/_actions":"/__w/_actions" \
-v "/home/ruinnel/actions-runner/_work/_tool":"/__w/_tool" \
-v "/home/ruinnel/actions-runner/_work/_temp/_github_home":"/github/home" \
-v "/home/ruinnel/actions-runner/_work/_temp/_github_workflow":"/github/workflow" \
--entrypoint "tail" node:22 "-f" "/dev/null"
회피하는 방법
action-runner를 root 권한으로 실행하면 해결 될 수 있습니다. 하지만 보안상 추천하지 않습니다.jobs.<job_id>.container.options
에--user <UID>
을 추가 합니다.- UID는 linux라면
id -u
으로 획득 가능합니다. - UID는 서버에 첫 등록된 사용자라면
1000
입니다. 하지만 환경에 따라 달라질 수 있습니다. - 그러므로, container 밖에서 동작하는 job에서
id -u
명령으로 획득 후output
으로 다음 job에 전달 할 수 있습니다.
- UID는 linux라면
name: publish
on:
push:
tags:
- "*"
jobs:
detect-user:
runs-on: [self-hosted, Linux]
outputs:
UID: ${{ steps.get-uid.outputs.UID }}
steps:
- name: get action-runner`s UID
id: get-uid
run: |
echo "UID=$(id -u)" >> $GITHUB_OUTPUT
build:
runs-on: [self-hosted, Linux]
needs: [detect-user]
container:
image: "node:22"
options: --user ${{ needs.detect-user.outputs.UID }}
steps:
- name: checkout code
uses: actions/checkout@v4
- name: build observable
run: |
make publish out-dir=./dist;
cleanup:
runs-on: [self-hosted, Linux]
needs: build
steps:
- name: remove build output
run: |
rm -rf dist;
- 결론
- self-hosted runner에서 container를 사용 할 경우 container가 적절한 사용자 권한으로 실행 될 수 있도록 신경 쓸 필요가 있다.
- 2020년에 github action에 issue로 등록되어 있는 오래된 이슈.
하지만 쓰는 사람이 신경써야 할 부분으로 판단 되는지 issue는 계속 Open 상태로 방치되어 있음.
- 2020년에 github action에 issue로 등록되어 있는 오래된 이슈.
- self-hosted runner에서 container를 사용 할 경우 container가 적절한 사용자 권한으로 실행 될 수 있도록 신경 쓸 필요가 있다.