Chris Evich f1423ae0b2 Merge branch 'fix_volumes' into 'main'
Fix volume mounts

See merge request qontainers/pipglr!14
2022-12-06 08:15:33 +00:00
2022-11-10 10:36:16 -05:00
2022-12-06 03:07:40 -05:00
2022-12-06 02:18:27 -05:00

Overview

This container image is built daily from this Containerfile, and made available as:

  • registry.gitlab.com/qontainers/pipglr:latest

-or-

  • registry.gitlab.com/qontainers/pipglr:<version>

It's purpose is to provide an easy method to execute a GitLab runner, to service CI/CD jobs for groups and/or repositories on gitlab.com. It comes pre-configured to utilize the gitlab-runner app to execute within a rootless podman container, nested inside a rootless podman container.

This is intended to provide additional layers of security for the host, when running potentially arbitrary CI/CD code. Though, the ultimate responsibility still rests with the end-user to review the setup and configuration relative to their own security situation/environment.

Operation

This image supports podman container runlabel, or if your version lacks this feature, Several labels are set on the image to support easy registration and execution of a runner container using a special bash command. See the examples below for more information.

[Volume setup]

Since podman inside the container runs as user podman, the volumes used by it need to be pre-created with ownership information. While, we're at it, might as well add the performance-improving noatime, option as well.

$ VOLOPTS="o=uid=1000,gid=1000,noatime"; \
  for VOLUME in pipglr-podman-root pipglr-config pipglr-podman-cache; do \
    podman volume create --opt $VOLOPTS $VOLUME || true ; \
    VOLPTH=$(podman unshare podman volume mount $VOLUME)
    podman unshare chown -c -R 1000:1000 $VOLPTH && \
    podman unshare chmod -c 02770 $VOLPTH && \
    podman unshare podman volume unmount $VOLUME ; \
  done

If you get podman system service startup permission-denied errors, or errors from gitlab-runner, unable to connect to the podman socket, this is likely the cause. You can fix it after-the-fact using the same commands above.

Runner registration

Each time the registration command is run, a new runner is added into the configuration. If however, you simply need to update/modify the configuration, please edit the config.toml file directly after mounting (default) pipglr-runner-config (/home/podman/.gitlab-runner/) volume. For modern versions of podman, registration can be performed with the following commands:

$ IMAGE="registry.gitlab.com/qontainers/pipglr:latest"
$ echo '<actual registration token>' | podman secret create REGISTRATION_TOKEN -
$ podman container runlabel register $IMAGE

Where <actual registration token> is the value obtained from the "runners" settings page of a gitlab group or project. When you're finished registering as many runners as you want, the secret is no-longer needed and may be removed:

$ podman secret rm REGISTRATION_TOKEN
Note

Some versions of podman don't support the container runlabel sub-command. If this is the case, you may simulate it with the following command (in addition to the other example commands above):

$ eval $(podman inspect --format=json $IMAGE | jq -r .[].Labels.register)

Runner Startup

With one or more runners successfully registered and configured, the GitLab runner container may be launched with the following commands:

$ podman container runlabel run $IMAGE
Note

As above, if you're missing the container runlabel sub-command, the following may be used instead (assuming $IMAGE remains set):

$ eval $(podman inspect --format=json $IMAGE | jq -r .[].Labels.run)

Runner configuration

You may inspect/modify the gitlab-runner configuration as you see fit, just be sure to use the podman unshare command-wrapper to enter the usernamespace. For example, to display the config:

$ podman unshare cat $(podman unshare podman volume mount pipglr-config)/config.toml

Edit the config with your favorite $EDITOR:

$ podman unshare $EDITOR $(podman unshare podman volume mount pipglr-config)/config.toml

Debugging

The first thing to check is the container output:

$ podman logs --since 0 pipglr

Next, try running pipglr after an export PODMAN_RUNNER_DEBUG=debug to enable debugging on the inner-podman. If more runner detail is needed, you can instead/additionally set export LOG_LEVEL=debug to debug the gitlab-runner itself.

Building

This image may be built simply with:

$ podman build -t registry.gitlab.com/qontainers/pipglr:latest .

This will utilize the latest stable version of podman and the latest stable version of the gitlab runner.

Notes

  • If you wish to use the testing or upstream flavors of the podman base image, simply build with --build-arg FLAVOR=testing (or upstream).

  • Additionally or alternatively, you may specify a specific podman base image tag with --build-arg BASE_TAG=<value>. Where <value> is either latest, the podman image version (e.g. v4, v4.2, v4.2.0, etc.)

Build-args

Several build arguments are available to control the output image:

  • FLAVOR - Choose from 'stable', 'testing', or 'upstream'. These select the podman base-image to utilize - which may affect the podman version, features, and stability. For more information see the podmanimage README.
  • BASE_TAG - When FLAVOR="stable", allows granular choice over the exact podman version. Possible values include, latest, vX, vX.Y, and vX.Y.Z (where, X, Y, and Z represent the podman semantic version numbers). It's also possible to specify an image SHA.
  • CLEAN_INTERVAL - A sleep (command) compatible time-argument that determines how often to clean out podman storage of disused containers and images. Defaults to 24-hours, but should be adjusted based on desired caching-effect versus available storage space and rate of job execution.
  • EXCLUDE_PACKAGES - A space-separated list of RPM packages to prevent their existence in the final image. This is intended as a security measure to limit the attack-surface should a gitlab-runner process escape it's inner-container.
  • RUNNER_VERSION - Allows specifying an exact gitlab runner version. By default the latest is used, assuming the user is building a tagged image anyway. Valid versions may be found on the runner release page.
  • DNFCMD - By default this is set to dnf --setopt=tsflags=nodocs -y. However, if you'd like to volume-mount in /var/cache/dnf then you'll need to use --build-arg DNFCMD="dnf --setopt=tsflags=nodocs -y --setopt keepcache=true" Note: Changing DNFCMD will cause build-time cache cleanup to be disabled.
  • TARGETARCH - Supports inclusion of non-x86_64 gitlab runners. This value is assumed to match the image's architecture. If using the --platform build argument, it will be set automatically.
  • RUNNER_LISTEN_ADDRESS - Disabled by default, setting this to the FQDN and port supports various observability and debugging features of the gitlab runner. For more information see the gitlab runner advanced configuration documentation.
  • PRIVILEGED_RUNNER - Defaults to 'true', may be set 'true' if you're brave. However this may result in the gitlab-runner failing to launch inner-containers. Setting it false will also prevent building container images using the runner.
  • RUNNER_TAGS - Defaults to podman_in_podman, may be set to any comma-separated list (with no spaces!) of tags. These show up in GitLab (not the runner configuration), and determines where jobs are run.
  • RUNNER_UNTAGED - Defaults to true, may be set to false. Allows the runner to service jobs without any tags on them at all.

Environment variables

Nearly every option to every gitlab-runner sub-command may be specified via environment variable. Many important/required options are set in the Containerfile. However it's entirely possible to pass them in via either of the podman container runlabel... container commands. To discover them, simply append --help to the end of the command. For example:

podman container runlabel $IMAGE register --help
Description
No description provided
Readme 221 KiB
Languages
Shell 69.4%
Dockerfile 30.6%