|
| 1 | +# syntax=docker/dockerfile:1 |
| 2 | +# |
| 3 | +# MicroShift in a privileged container for CI. |
| 4 | +# |
| 5 | +# This image bundles upstream MicroShift on top of CentOS Stream 9 and |
| 6 | +# runs systemd as PID 1. Intended to be launched with: |
| 7 | +# |
| 8 | +# docker run -d --privileged --cgroupns=host \ |
| 9 | +# -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ |
| 10 | +# -v /lib/modules:/lib/modules:ro \ |
| 11 | +# --tmpfs /run --tmpfs /tmp \ |
| 12 | +# -p 6443:6443 -p 80:80 -p 443:443 \ |
| 13 | +# microshift-ci:local |
| 14 | +# |
| 15 | +# See .github/microshift-ci/start.sh for the host-side wrapper used in CI. |
| 16 | +# |
| 17 | +# Notes from Spike A runs 1–7 (2026-04-29): |
| 18 | +# - The `@redhat-et/microshift` Copr is dead (last build 2021). |
| 19 | +# - The `@microshift/` Copr group on Fedora Copr is empty (no projects, |
| 20 | +# no builds), so any `@microshift/microshift-X.Y` reference fails at |
| 21 | +# `dnf copr enable`. |
| 22 | +# - The verified working RPM source is the official OpenShift mirror |
| 23 | +# at `mirror.openshift.com`, which serves the same MicroShift bits |
| 24 | +# Red Hat ships under subscription, on two anonymous yum repos. |
| 25 | +# No GPG keys are published alongside, so `gpgcheck=0` is required. |
| 26 | +# - Reproducibility: pin to a specific RC tag (e.g. `4.18.0-rc.10`), |
| 27 | +# NOT the moving `latest-4.18` symlink. |
| 28 | +# - microshift shells out to `/bin/hostname` at startup; the package |
| 29 | +# must be installed explicitly because it is not in the minimal |
| 30 | +# base nor pulled transitively by any microshift-* dep. |
| 31 | +# - cri-o reads `/etc/crio/openshift-pull-secret` to authenticate to |
| 32 | +# `quay.io/openshift-release-dev/ocp-v4.0-art-dev`. The path is |
| 33 | +# bind-mounted from the runner by `start.sh`; without it the |
| 34 | +# OVN/DNS/router pods fail to pull and the node never goes Ready. |
| 35 | +# - Docker's default `private` mount propagation on `/` blocks the |
| 36 | +# `rshared` bind mounts that OVN-Kubernetes (and other openshift-* |
| 37 | +# system pods) need. We wrap /sbin/init with entrypoint.sh which |
| 38 | +# runs `mount --make-rshared /` first. |
| 39 | +# - The runner's Docker mounts `/run` as tmpfs with `noexec`. cri-o |
| 40 | +# validates a CNI config by exec'ing the plugin binary; OVN drops |
| 41 | +# `/run/cni/bin/ovn-k8s-cni-overlay` there, the exec returns |
| 42 | +# EACCES, and cri-o falls back to crio-bridge + loopback (node |
| 43 | +# never goes Ready). entrypoint.sh remounts /run with `exec` to |
| 44 | +# fix this. |
| 45 | + |
| 46 | +ARG BASE_IMAGE=quay.io/centos/centos:stream9 |
| 47 | +# MicroShift release tag to pin (e.g. 4.18.0-rc.10). Browse |
| 48 | +# https://mirror.openshift.com/pub/openshift-v4/x86_64/microshift/ocp/ |
| 49 | +# for available RC directories. There are no GA dirs in the public |
| 50 | +# mirror; only `*-rc.*` and (in `…/ocp-dev-preview/…`) `*-ec.*`. |
| 51 | +ARG MICROSHIFT_RELEASE=4.18.0-rc.10 |
| 52 | +# Minor line corresponding to MICROSHIFT_RELEASE. Used both in the local |
| 53 | +# repo `[id]` and in the dependencies-repo URL. |
| 54 | +ARG MICROSHIFT_LINE=4.18 |
| 55 | + |
| 56 | +FROM ${BASE_IMAGE} |
| 57 | + |
| 58 | +ARG MICROSHIFT_RELEASE |
| 59 | +ARG MICROSHIFT_LINE |
| 60 | + |
| 61 | +# Base packages: systemd as PID 1, plus userspace required by |
| 62 | +# microshift's startup checks. |
| 63 | +# |
| 64 | +# - `hostname` is mandatory (Spike A run 3 lesson): microshift shells |
| 65 | +# out to /bin/hostname during config defaulting; without it the |
| 66 | +# daemon dies in <1 s. The package is NOT in CentOS Stream 9's |
| 67 | +# minimal base image and is NOT pulled transitively by any |
| 68 | +# microshift-* dep. |
| 69 | +# - `iputils`, `iproute`, `procps-ng` are listed explicitly even |
| 70 | +# though they happen to be pulled by microshift-networking today. |
| 71 | +# Same class of silent breakage as `hostname` if a future minor |
| 72 | +# changes its deps; cheap to defend against. |
| 73 | +RUN dnf -y install \ |
| 74 | + systemd \ |
| 75 | + ca-certificates \ |
| 76 | + hostname \ |
| 77 | + iputils \ |
| 78 | + iproute \ |
| 79 | + procps-ng && \ |
| 80 | + dnf clean all |
| 81 | + |
| 82 | +# Mask units that are not relevant inside a container and tend to fail |
| 83 | +# noisily, polluting `journalctl` output. Validated working in |
| 84 | +# Spike A runs 1–7. |
| 85 | +RUN systemctl mask \ |
| 86 | + systemd-firstboot.service \ |
| 87 | + systemd-udevd.service \ |
| 88 | + systemd-udev-trigger.service \ |
| 89 | + systemd-hwdb-update.service \ |
| 90 | + systemd-tmpfiles-setup.service \ |
| 91 | + systemd-tmpfiles-setup-dev.service \ |
| 92 | + systemd-tmpfiles-clean.service \ |
| 93 | + systemd-tmpfiles-clean.timer \ |
| 94 | + getty.target \ |
| 95 | + getty@.service \ |
| 96 | + console-getty.service |
| 97 | + |
| 98 | +# Configure the two anonymous mirror.openshift.com yum repos that ship |
| 99 | +# MicroShift and its dependencies (cri-o, openshift-clients, openvswitch3, |
| 100 | +# etc.). Shell-level `:=` defaults guard against an empty `--build-arg` |
| 101 | +# from the workflow (defense in depth — with literal mirror URLs an |
| 102 | +# empty value would surface as a 404, but pinning is too important to |
| 103 | +# rely on that alone). |
| 104 | +RUN : "${MICROSHIFT_RELEASE:=4.18.0-rc.10}" && \ |
| 105 | + : "${MICROSHIFT_LINE:=4.18}" && \ |
| 106 | + cat > /etc/yum.repos.d/microshift.repo <<EOF |
| 107 | +[microshift-${MICROSHIFT_LINE}] |
| 108 | +name=MicroShift ${MICROSHIFT_LINE} |
| 109 | +baseurl=https://mirror.openshift.com/pub/openshift-v4/x86_64/microshift/ocp/${MICROSHIFT_RELEASE}/el9/os/ |
| 110 | +enabled=1 |
| 111 | +gpgcheck=0 |
| 112 | + |
| 113 | +[microshift-${MICROSHIFT_LINE}-deps] |
| 114 | +name=MicroShift ${MICROSHIFT_LINE} Dependencies |
| 115 | +baseurl=https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rpms/${MICROSHIFT_LINE}-el9-beta/ |
| 116 | +enabled=1 |
| 117 | +gpgcheck=0 |
| 118 | +EOF |
| 119 | + |
| 120 | +# Install MicroShift, CRI-O, and the openshift-clients package (oc CLI). |
| 121 | +# `skopeo` is bundled in the same dependencies repo and is required by |
| 122 | +# Spike C's registry-free image hand-off (`docker save | skopeo copy |
| 123 | +# docker-archive:- containers-storage:...`). |
| 124 | +RUN dnf -y install \ |
| 125 | + cri-o cri-tools \ |
| 126 | + microshift microshift-networking microshift-greenboot \ |
| 127 | + microshift-release-info microshift-selinux \ |
| 128 | + openshift-clients \ |
| 129 | + skopeo && \ |
| 130 | + dnf clean all |
| 131 | + |
| 132 | +# Enable services so they start under PID-1 systemd. |
| 133 | +RUN systemctl enable crio.service microshift.service |
| 134 | + |
| 135 | +ENV KUBECONFIG=/var/lib/microshift/resources/kubeadmin/kubeconfig |
| 136 | + |
| 137 | +# systemd uses SIGRTMIN+3 for clean container shutdown. |
| 138 | +STOPSIGNAL SIGRTMIN+3 |
| 139 | + |
| 140 | +EXPOSE 6443 80 443 |
| 141 | + |
| 142 | +# Wrap /sbin/init in entrypoint.sh which makes two filesystem fixes |
| 143 | +# that MUST happen before any nested container runs: |
| 144 | +# - `mount --make-rshared /` for OVN-Kubernetes rshared bind mounts |
| 145 | +# (Spike A run 5 lesson) |
| 146 | +# - `mount -o remount,exec /run` so cri-o can exec the OVN CNI |
| 147 | +# plugin binary (Spike A run 7 lesson) |
| 148 | +COPY entrypoint.sh /usr/local/bin/entrypoint.sh |
| 149 | +RUN chmod +x /usr/local/bin/entrypoint.sh |
| 150 | +CMD ["/usr/local/bin/entrypoint.sh"] |
0 commit comments