-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #137 from bitdeps/dennybaa/podman-5x
feat: migrate to bitdeps/podman-static 5.x version
- Loading branch information
Showing
12 changed files
with
377 additions
and
291 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,179 @@ | ||
# actions-runner | ||
GitHub actions runner and images | ||
|
||
GitHub Actions runner and images based on Podman. | ||
|
||
## Podman 5.x | ||
|
||
The Bitdeps Actions Runner uses a statically built version of Podman, which differs from the official Microsoft runner and offers unique features. Unlike the official runner, this version provides: | ||
|
||
- **Rootless execution** on Kubernetes with minimal capabilities (only SETUID and SETGID are used). | ||
- **No need for Buildx** — efficient multi-architecture builds are supported out of the box. | ||
- **Container-only job execution** — this runner is designed exclusively for container jobs. | ||
- **Pre-configured tools**: | ||
- A Docker compatibility wrapper for remote Podman execution inside any job container. | ||
- GitHub CLI tool. | ||
- Pre-configured Google Artifacts Registry credential helper. | ||
|
||
### Known Limitations | ||
|
||
Rootless execution in cloud environments like GKE has some limitations. For instance, port mapping and DNS for service containers do not work as expected. Podman relies on the CNI plugin, and [Netavark](https://www.redhat.com/en/blog/podman-new-network-stack) does not function well in cloud environments. Despite this, the overall user experience remains smooth. | ||
|
||
## Using Podman Actions | ||
|
||
Since this runner does not use Buildx or Docker, Podman-native actions are used instead. Here are some examples: | ||
|
||
```yaml | ||
jobs: | ||
build: | ||
runs-on: myrunner | ||
|
||
permissions: | ||
contents: read | ||
packages: write | ||
|
||
## Container jobs are only allowed! | ||
container: | ||
image: images/alpine:latest | ||
|
||
steps: | ||
- name: Build Image | ||
id: build-image | ||
uses: redhat-actions/buildah-build@v2 | ||
with: | ||
image: myorg/repo | ||
context: . | ||
tags: latest | ||
build-args: "" | ||
containerfiles: Containerfile | ||
|
||
- name: Push to Artifact Registry | ||
uses: redhat-actions/push-to-registry@v2 | ||
with: | ||
image: myorg/repo | ||
tags: latest | ||
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ github.token }} | ||
``` | ||
For more information: | ||
* [buildah-build GitHub Action](https://github.com/redhat-actions/buildah-build) | ||
* [push-to-registry GitHub Action](https://github.com/redhat-actions/push-to-registry) | ||
## Deploying on Kubernetes | ||
The standard method for deploying self-hosted runners in Kubernetes is using [actions-runner-controller](https://github.com/actions/actions-runner-controller). For detailed setup, refer to the [official documentation](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners-with-actions-runner-controller/deploying-runner-scale-sets-with-actions-runner-controller#runner-scale-set). | ||
Further configuration details are provided below. | ||
### Fuse Device Plugin | ||
With the Fuse device plugin, pods no longer need to run in privileged mode to access `/dev/fuse`. The DaemonSet below injects the fuse device into pods running on matched nodes. [Learn more](https://github.com/kubernetes-learning-group/fuse-device-plugin/blob/master/README_EN.md). | ||
|
||
```yaml | ||
apiVersion: apps/v1 | ||
kind: DaemonSet | ||
spec: | ||
template: | ||
spec: | ||
hostNetwork: true | ||
nodeSelector: | ||
myorg/gh-runner: "true" | ||
tolerations: | ||
- key: myorg/gh-runner | ||
operator: Exists | ||
effect: NoSchedule | ||
containers: | ||
- image: soolaugust/fuse-device-plugin:v1.0 | ||
name: fuse-device-plugin-ctr | ||
securityContext: | ||
allowPrivilegeEscalation: false | ||
capabilities: | ||
drop: ["ALL"] | ||
volumeMounts: | ||
- name: device-plugin | ||
mountPath: /var/lib/kubelet/device-plugins | ||
volumes: | ||
- name: device-plugin | ||
hostPath: | ||
path: /var/lib/kubelet/device-plugins | ||
``` | ||
|
||
### Actions Runner Controller Values | ||
|
||
Refer to the [values.yaml](https://github.com/actions/actions-runner-controller/blob/master/charts/gha-runner-scale-set/values.yaml) for configuration reference. The configuration below highlights important settings, such as the Fuse device plugin, virtual network interface, and AppArmor security profile. | ||
|
||
```yaml | ||
template: | ||
metadata: | ||
annotations: | ||
container.apparmor.security.beta.kubernetes.io/runner: unconfined | ||
cluster-autoscaler.kubernetes.io/safe-to-evict: "true" | ||
spec: | ||
serviceAccountName: scale-set-wi | ||
nodeSelector: | ||
myorg/gh-runner: "true" | ||
tolerations: | ||
- key: myorg/gh-runner | ||
operator: Exists | ||
effect: NoSchedule | ||
containers: | ||
- name: runner | ||
command: | ||
- entrypoint.sh | ||
- /home/runner/run.sh | ||
imagePullPolicy: Always | ||
image: ghcr.io/bitdeps/actions-runner:5.3.1 | ||
securityContext: | ||
runAsUser: 1001 | ||
runAsGroup: 1001 | ||
fsGroup: 1001 | ||
capabilities: | ||
allowPrivilegeEscalation: false | ||
drop: ["ALL"] | ||
add: | ||
- SETUID | ||
- SETGID | ||
resources: | ||
requests: | ||
cpu: 500m | ||
memory: 3350Mi | ||
limits: | ||
github.com/fuse: 1 | ||
cpu: 2 | ||
memory: 3350Mi | ||
volumeMounts: | ||
- mountPath: /home/runner/.local/share/containers | ||
name: podman-local | ||
# Virtual network interfaces mount | ||
- mountPath: /dev/net/tun | ||
name: dev-tun | ||
# Additional registry shortnames for Podman | ||
- name: shortnames | ||
mountPath: "/etc/containers/registries.conf.d/001-shortnames.conf" | ||
subPath: 001-shortnames.conf | ||
readOnly: true | ||
volumes: | ||
- name: podman-local | ||
emptyDir: {} | ||
- name: dev-tun | ||
hostPath: | ||
path: /dev/net/tun | ||
type: CharDevice | ||
- name: shortnames | ||
configMap: | ||
name: scale-set-configs-shortnames | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
## --- Actions Runner Dist | ||
FROM alpine as runner-dist | ||
Check warning on line 2 in runners/Containerfile GitHub Actions / publish / imageThe 'as' keyword should match the case of the 'from' keyword
|
||
# renovate: datasource=github-releases depName=actions/runner | ||
ARG RUNNER_VERSION=2.321.0 | ||
# renovate: datasource=github-releases depName=actions/runner-container-hooks | ||
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.6.2 | ||
# | ||
ARG TARGETARCH="" | ||
ARG TARGETOS="linux" | ||
|
||
# Fetch runner | ||
# ref: https://github.com/actions/runner/blob/main/images/Dockerfile | ||
# | ||
RUN apk add --update curl gzip unzip | ||
WORKDIR /dist | ||
|
||
RUN export RUNNER_ARCH=${TARGETARCH:-$(arch | sed 's/x86_64/amd64/')} \ | ||
&& if [ "$RUNNER_ARCH" = "amd64" ]; then export RUNNER_ARCH=x64 ; fi \ | ||
&& curl -f -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-${TARGETOS}-${RUNNER_ARCH}-${RUNNER_VERSION}.tar.gz \ | ||
&& tar xzf ./runner.tar.gz \ | ||
&& rm runner.tar.gz | ||
|
||
RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \ | ||
&& unzip ./runner-container-hooks.zip -d ./k8s \ | ||
&& rm runner-container-hooks.zip | ||
|
||
COPY gcloud-artifacts-locations /tmp/ | ||
RUN mkdir -p /runner/tools/helpers \ | ||
# create comma separated google docker registries list \ | ||
&& cat /tmp/gcloud-artifacts-locations | sed -ne '/^#/!{ s/$/-docker.pkg.dev/; p}' | sed ':a;N;$!ba;s/\n/,/g' > /runner/tools/helpers/gcr-registries.list | ||
|
||
|
||
|
||
## --- Actions Runner Image | ||
FROM ubuntu:24.04@sha256:80dd3c3b9c6cecb9f1667e9290b3bc61b78c2678c02cbdae5f0fea92cc6734ab | ||
ARG TARGETARCH="${TARGETARCH}" | ||
ARG TARGETOS="${TARGETOS:-linux}" | ||
|
||
# renovate: datasource=github-releases depName=bitdeps/podman-static | ||
ARG PODMAN_VERSION=5.3.1 | ||
# renovate: datasource=github-releases depName=cli/cli | ||
ARG GH_CLI_VERSION=2.65.0 | ||
# renovate: datasource=github-releases depName=GoogleCloudPlatform/docker-credential-gcr | ||
ARG GCR_CREDSHELPER_VERSION=2.1.25 | ||
|
||
# Runner specific environment. RUNNER_TOOLS_BIN is mounted into job containers | ||
# which provides static tools and scripts | ||
ENV RUNNER_TOOL_CACHE=/opt/hostedtoolcache | ||
ENV RUNNER_TOOLS_BIN=/runner/tools/bin | ||
|
||
COPY --from=runner-dist /runner/tools /runner/tools | ||
COPY --chmod=755 container-tools/* $RUNNER_TOOLS_BIN/ | ||
# Copy docker wrapper for podman providing compatibility for actions-runner | ||
COPY --chmod=755 docker-compat.sh /usr/bin/docker | ||
|
||
|
||
# Update and install essentials | ||
RUN apt update -y \ | ||
&& apt install -y --no-install-recommends wget curl ca-certificates git lsb-release unzip uidmap libcap2-bin iptables tini \ | ||
apt-transport-https gnupg \ | ||
&& rm -rf /var/lib/apt/lists/* /var/cache/apt | ||
|
||
# Install static podman | ||
RUN export ARCH=${TARGETARCH:-$(arch | sed 's/x86_64/amd64/')}; \ | ||
curl -sL https://github.com/bitdeps/podman-static/releases/download/v${PODMAN_VERSION}/podman-linux-${ARCH}.tar.gz | tar xzC /tmp \ | ||
&& dist=/tmp/podman-linux-${ARCH} \ | ||
# clean up dist and copy \ | ||
&& rm ${dist}/usr/local/bin/runc && cp -r ${dist}/etc ${dist}/usr / \ | ||
# Link podman as podman-static to runner tools, since jobs podman wrapper uses it \ | ||
&& ln /usr/local/bin/podman $RUNNER_TOOLS_BIN/podman-static \ | ||
# clean up \ | ||
&& rm -rf /tmp/* | ||
|
||
# Create runner user (1001:1001) with subordinate id mappings | ||
RUN useradd -u 1001 -Um -d /home/runner -s /bin/bash runner \ | ||
&& printf "runner:1:1000\nrunner:1002:64535\n" | tee /etc/subuid > /etc/subgid \ | ||
&& mkdir -p /run/user/1001 \ | ||
&& chown runner:runner /run/user/1001 \ | ||
&& chmod a+x /run/user/1001 \ | ||
## Volumes might be passed with nosuid flag, this doesn't work well on debian/ubuntu! \ | ||
## So suid/sgid bits are removed from uid mapping binaries and capabilities are set directly. \ | ||
&& chmod 0755 /usr/bin/newuidmap /usr/bin/newgidmap \ | ||
&& setcap cap_setuid+ep /usr/bin/newuidmap \ | ||
&& setcap cap_setgid+ep /usr/bin/newgidmap | ||
|
||
# Copy actions runner dist | ||
COPY --chown=runner:runner --from=runner-dist /dist /home/runner | ||
|
||
# Setup and links directories | ||
RUN mkdir /opt/hostedtoolcache && chgrp runner /opt/hostedtoolcache \ | ||
&& chmod g+rwx /opt/hostedtoolcache \ | ||
&& mkdir -p /home/runner/.local/bin /home/runner/.local/share/containers \ | ||
&& chown -R runner:runner /home/runner/.local \ | ||
# switch to legacy iptables for better compatibility \ | ||
&& update-alternatives --set iptables /usr/sbin/iptables-legacy | ||
|
||
# Copy runner configuration and env | ||
COPY containers /etc/containers | ||
COPY runner/hooks /runner/hooks | ||
COPY --chown=runner:runner runner/containers.conf /home/runner/.config/containers/ | ||
COPY --chown=runner:runner runner/env /home/runner/.env | ||
COPY --chmod=755 entrypoint.sh /usr/bin | ||
|
||
# Setup environment | ||
ENV PATH="${PATH}:/home/runner/.local/bin:/home/runner/bin:${RUNNER_TOOLS_BIN}" | ||
ENV ImageOS=ubuntu24 | ||
ENV RUNNER_MANUALLY_TRAP_SIG=1 | ||
ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1 | ||
ENV XDG_RUNTIME_DIR=/run/user/1001 | ||
ENV DOCKER_HOST=unix:///run/user/1001/podman/podman.sock | ||
ENV _CONTAINERS_USERNS_CONFIGURED="" | ||
# Force container jobs only mode (i.e. runner does not support jobs without job.<id>.container set)! | ||
ENV ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER=true | ||
# Use the fix to mitigate startup on ubuntu 24.04 | ||
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 | ||
|
||
RUN echo "PATH=${PATH}" > /etc/environment \ | ||
&& echo "ImageOS=${ImageOS}" >> /etc/environment \ | ||
&& echo "DOCKER_HOST=${DOCKER_HOST}" >> /etc/environment \ | ||
&& echo "XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR}" >> /etc/environment | ||
|
||
|
||
# Install static tools | ||
RUN cd /tmp; export ARCH=${TARGETARCH:-$(arch | sed 's/x86_64/amd64/')}; \ | ||
# install static gh cli \ | ||
curl -L https://github.com/cli/cli/releases/download/v${GH_CLI_VERSION}/gh_${GH_CLI_VERSION}_${TARGETOS}_${ARCH}.tar.gz | \ | ||
tar -xz && mv gh_${GH_CLI_VERSION}_${TARGETOS}_${ARCH}/bin/gh $RUNNER_TOOLS_BIN \ | ||
&& rm -rf /tmp/* | ||
|
||
# Install docker credential helper for Google Artifact Registry | ||
RUN export ARCH=${TARGETARCH:-$(arch | sed 's/x86_64/amd64/')}; \ | ||
curl -fsSL "https://github.com/GoogleCloudPlatform/docker-credential-gcr/releases/download/v${GCR_CREDSHELPER_VERSION}/docker-credential-gcr_${TARGETOS}_${ARCH}-${GCR_CREDSHELPER_VERSION}.tar.gz" \ | ||
| tar xz docker-credential-gcr \ | ||
&& chmod +x docker-credential-gcr && mv docker-credential-gcr /usr/local/bin/ | ||
|
||
WORKDIR /home/runner | ||
VOLUME ["/home/runner/.local/share/containers"] | ||
USER runner | ||
|
||
# User specific setup | ||
RUN docker-credential-gcr configure-docker --registries=$(cat /runner/tools/helpers/gcr-registries.list) | ||
|
||
ENTRYPOINT ["tini", "--", "/usr/bin/entrypoint.sh"] |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,8 @@ | ||
# See https://github.com/containers/common/blob/master/pkg/config/containers.conf | ||
# and https://github.com/containers/podman/blob/master/contrib/podmanimage/stable/containers.conf | ||
[containers] | ||
netns="host" | ||
userns="host" | ||
ipcns="host" | ||
utsns="host" | ||
cgroupns="host" | ||
cgroups="disabled" | ||
unmask = "/proc/*" | ||
[engine] | ||
cgroup_manager = "cgroupfs" | ||
events_logger="file" | ||
runtime="crun" | ||
|
||
[network] | ||
network_backend = "cni" |
Oops, something went wrong.