crictl can import images but slow
This commit is contained in:
28
README.md
28
README.md
@@ -5,17 +5,16 @@ Kubernetes image for Mono Gateway Development Kit
|
||||
https://docs.mono.si/gateway-development-kit/getting-started
|
||||
|
||||
## DISCLAIMER
|
||||
I leverage ChatGPT heavily for this. I also tested them thoroughly enough that until I am confident that's what we need.
|
||||
USE AT YOUR OWN RISKS. I leverage ChatGPT heavily for this. I am testing them all by myself right now.
|
||||
|
||||
### The device's dts files are located at here
|
||||
https://github.com/we-are-mono/OpenWRT-ASK/tree/mono-25.12.0-rc3/target/linux/layerscape/files/arch/arm64/boot/dts/freescale
|
||||
* We need both `mono-gateway-dk-sdk.dts` and `mono-gateway-dk.dts` since the sdk one includes the non-sdk one.
|
||||
* The actual dts being used is the `mono-gateway-dk-sdk.dts`
|
||||
|
||||
|
||||
## Build
|
||||
|
||||
To avoid frequent downloading on rebuild. Find the latest packages and update build.env
|
||||
Find the latest package versions and update build.env
|
||||
* [kernel](https://github.com/nxp-qoriq/linux/archive/refs/tags/)
|
||||
* [busybox](https://github.com/mirror/busybox/archive/refs/tags/)
|
||||
* [CRI-O](https://github.com/cri-o/cri-o/releases)
|
||||
@@ -23,12 +22,15 @@ To avoid frequent downloading on rebuild. Find the latest packages and update bu
|
||||
|
||||
Then run
|
||||
```
|
||||
make download-packages
|
||||
make release
|
||||
```
|
||||
|
||||
### Making sub stages
|
||||
```bash
|
||||
make itb # for out/board.itb (contains the kernel and the initramfs)
|
||||
make release # WORK IN PROGRESS
|
||||
make build-base # The image the builds kernel and everything
|
||||
make kernel # Builds our kernel from NXP
|
||||
make initramfs
|
||||
make itb # Builds out/board.itb (contains the kernel and the initramfs)
|
||||
```
|
||||
|
||||
## Architecture
|
||||
@@ -66,7 +68,9 @@ setenv serverip 10.0.0.129
|
||||
tftp 0x80000000 board.itb
|
||||
```
|
||||
|
||||
## USB
|
||||
## USB Flashing
|
||||
1. Copy board.itb into an SDCard
|
||||
2. Copy `[RELEASE_NAME].img.gz` into an SDCard
|
||||
```
|
||||
usb start
|
||||
usb tree
|
||||
@@ -77,3 +81,13 @@ fatload usb 0 0x80000000 board.itb
|
||||
setenv bootargs "console=ttyS0,115200 earlycon=uart8250,mmio,0x21c0500 root=/dev/ram0 rootwait rw"
|
||||
bootm 0x80000000
|
||||
```
|
||||
|
||||
3. Inside initramfs
|
||||
```
|
||||
mount /dev/sda /mnt
|
||||
gunzip -c /mnt/[RELEASE_IMAGE].img.gz | dd of=/dev/mmcblk0
|
||||
reboot -f
|
||||
```
|
||||
|
||||
4. If it boots, create the A/B deployment scheme
|
||||
- (WORK IN PROGRESS)
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
/preload-k8s-images.sh || exit 1
|
||||
|
||||
REGISTRY_DATA_DIR="${KUBE_IMG_CACHE}/registry-data/${ARCH}/${KUBE_VERSION}"
|
||||
|
||||
mkdir -p "${ROOTFS}/var/lib/registry"
|
||||
|
||||
echo "Copying registry data into rootfs..."
|
||||
cp -a "${REGISTRY_DATA_DIR}/." "${ROOTFS}/var/lib/registry/"
|
||||
|
||||
mkdir -p "$ROOTFS/var/cache/apk"
|
||||
mkdir -p "$ROOTFS/var/cache/k8s-images"
|
||||
mkdir -p "$ROOTFS/build"
|
||||
mount --bind /var/cache/apk "$ROOTFS/var/cache/apk"
|
||||
mount --bind /var/cache/k8s-images "$ROOTFS/var/cache/k8s-images"
|
||||
mount --bind /dev "$ROOTFS/dev"
|
||||
mount --bind /proc "$ROOTFS/proc"
|
||||
mount --bind /sys "$ROOTFS/sys"
|
||||
@@ -11,6 +22,7 @@ mount --bind /run "$ROOTFS/run"
|
||||
cp /usr/bin/qemu-aarch64-static "$ROOTFS/usr/bin/"
|
||||
cp /etc/resolv.conf "$ROOTFS/etc/resolv.conf"
|
||||
cp /build/crio.tar.gz "$ROOTFS/build/"
|
||||
cp /build/registry.tar.gz "$ROOTFS/build/"
|
||||
cp -r /build/rootfs/* "$ROOTFS/"
|
||||
|
||||
chroot "$ROOTFS" /bin/sh -c "ln -s /var/cache/apk /etc/apk/cache"
|
||||
@@ -21,6 +33,7 @@ chroot "$ROOTFS" /bin/bash /install-packages.sh || exit 1
|
||||
rm "$ROOTFS/install-packages.sh"
|
||||
|
||||
umount "$ROOTFS/var/cache/apk"
|
||||
umount "$ROOTFS/var/cache/k8s-images"
|
||||
umount "$ROOTFS/dev"
|
||||
umount "$ROOTFS/proc"
|
||||
umount "$ROOTFS/sys"
|
||||
@@ -28,11 +41,13 @@ umount "$ROOTFS/run"
|
||||
|
||||
rm -r "$ROOTFS/build"
|
||||
|
||||
/merge-rootfs.sh "/build/rootfs-extra" "$ROOTFS"
|
||||
|
||||
### Begin making full disk image for the device
|
||||
echo "=========================== RootFS "$( du -sh "$ROOTFS/" )
|
||||
|
||||
IMG=output.img
|
||||
SIZE=1024MB
|
||||
SIZE=1536MB
|
||||
|
||||
dd if=/dev/zero of="$IMG" bs=1 count=0 seek=$SIZE
|
||||
|
||||
|
||||
@@ -10,11 +10,20 @@ rc-update add devfs sysinit
|
||||
rc-update add procfs sysinit
|
||||
rc-update add sysfs sysinit
|
||||
rc-update add loopback boot
|
||||
rc-update add hostname boot
|
||||
rc-update add localmount boot
|
||||
rc-update add fancontrol default
|
||||
echo "ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100 -n -l /bin/sh" >> "/etc/inittab"
|
||||
echo '[ -x /bin/bash ] && exec /bin/bash -l' >> "/root/.profile"
|
||||
echo "export PATH=\"/usr/local/bin:$PATH\"" >> "/etc/profile.d/settings.sh"
|
||||
|
||||
# We need this to ship k8s components. (coredns, kube-apiserver, etc)
|
||||
echo "##################################################### Install Local Registry"
|
||||
mkdir -p /usr/local/bin
|
||||
|
||||
apk add skopeo
|
||||
|
||||
tar zxf registry.tar.gz
|
||||
mv registry /usr/local/bin/registry
|
||||
/usr/local/bin/registry --version
|
||||
|
||||
echo "##################################################### Installing CRI-O"
|
||||
|
||||
@@ -30,6 +39,9 @@ if [ $? -ne 0 ]; then
|
||||
exit $?
|
||||
fi
|
||||
|
||||
mv /etc/cni/net.d/10-crio-bridge.conflist.disabled \
|
||||
/etc/cni/net.d/10-crio-bridge.conflist
|
||||
|
||||
echo "--------------"
|
||||
sed -i "s/default_runtime = \"crun\"/\0\ncgroup_manager = \"cgroupfs\"/g" /etc/crio/crio.conf.d/10-crio.conf
|
||||
grep cgroup_manager /etc/crio/crio.conf.d/10-crio.conf || exit 1
|
||||
|
||||
194
alpine/merge-rootfs.sh
Executable file
194
alpine/merge-rootfs.sh
Executable file
@@ -0,0 +1,194 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Usage:
|
||||
# export HOSTNAME=mybox
|
||||
# ./merge-rootfs.sh rootfs-extra /out/rootfs
|
||||
#
|
||||
# Naming rules:
|
||||
# foo -> normal file
|
||||
# foo.tmpl -> render with envsubst, then normal handling
|
||||
# foo.override -> replace target directly
|
||||
# foo.tmpl.override -> render with envsubst, then replace target directly
|
||||
#
|
||||
# Default handling:
|
||||
# etc/* -> merge missing lines
|
||||
# opt/scripts/* -> replace
|
||||
# everything else -> copy only if missing
|
||||
|
||||
SRC_ROOT="${1:?source rootfs path required}"
|
||||
DST_ROOT="${2:?target rootfs path required}"
|
||||
|
||||
if [[ ! -d "$SRC_ROOT" ]]; then
|
||||
echo "Source rootfs does not exist or is not a directory: $SRC_ROOT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -d "$DST_ROOT" ]]; then
|
||||
echo "Target rootfs does not exist or is not a directory: $DST_ROOT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v envsubst >/dev/null 2>&1; then
|
||||
echo "envsubst not found. Install gettext or gettext-envsubst." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
append_missing_lines() {
|
||||
local src="$1"
|
||||
local dst="$2"
|
||||
local changed=1
|
||||
local line
|
||||
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
if ! grep -Fqx -- "$line" "$dst"; then
|
||||
printf '%s\n' "$line" >> "$dst"
|
||||
changed=0
|
||||
fi
|
||||
done < "$src"
|
||||
|
||||
return "$changed"
|
||||
}
|
||||
|
||||
check_template_vars() {
|
||||
local src="$1"
|
||||
local missing=0
|
||||
local vars var
|
||||
|
||||
vars="$(
|
||||
grep -oE '\$\{[A-Za-z_][A-Za-z0-9_]*\}|\$[A-Za-z_][A-Za-z0-9_]*' "$src" \
|
||||
| sed -E 's/^\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?$/\1/' \
|
||||
| sort -u || true
|
||||
)"
|
||||
|
||||
while IFS= read -r var; do
|
||||
[[ -z "$var" ]] && continue
|
||||
if [[ -z "${!var+x}" ]]; then
|
||||
echo "Missing required env var: $var (used in $src)" >&2
|
||||
missing=1
|
||||
fi
|
||||
done <<< "$vars"
|
||||
|
||||
[[ "$missing" -eq 0 ]]
|
||||
}
|
||||
|
||||
render_template() {
|
||||
local src="$1"
|
||||
local out="$2"
|
||||
|
||||
mkdir -p "$(dirname "$out")"
|
||||
check_template_vars "$src"
|
||||
envsubst < "$src" > "$out"
|
||||
}
|
||||
|
||||
replace_file() {
|
||||
local src="$1"
|
||||
local dst="$2"
|
||||
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
cp -a "$src" "$dst"
|
||||
echo "Replaced file: $dst"
|
||||
}
|
||||
|
||||
merge_or_copy_file() {
|
||||
local src="$1"
|
||||
local dst="$2"
|
||||
local rel="$3"
|
||||
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
|
||||
# scripts: replace
|
||||
if [[ "$rel" == opt/scripts/* ]]; then
|
||||
cp -a "$src" "$dst"
|
||||
echo "Replaced script: $dst"
|
||||
return
|
||||
fi
|
||||
|
||||
# /etc: merge missing lines
|
||||
if [[ "$rel" == etc/* ]]; then
|
||||
if [[ ! -e "$dst" ]]; then
|
||||
cp -a "$src" "$dst"
|
||||
echo "Copied new config: $dst"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ ! -f "$dst" ]]; then
|
||||
echo "Skipping existing non-regular path: $dst" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
if append_missing_lines "$src" "$dst"; then
|
||||
echo "Appended missing lines: $dst"
|
||||
else
|
||||
echo "No changes needed: $dst"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
# default: copy only if missing
|
||||
if [[ ! -e "$dst" ]]; then
|
||||
cp -a "$src" "$dst"
|
||||
echo "Copied new file: $dst"
|
||||
else
|
||||
echo "Skipped existing file: $dst"
|
||||
fi
|
||||
}
|
||||
|
||||
find "$SRC_ROOT" -mindepth 1 | while IFS= read -r src_path; do
|
||||
rel_path="${src_path#"$SRC_ROOT"/}"
|
||||
|
||||
if [[ -d "$src_path" ]]; then
|
||||
mkdir -p "$DST_ROOT/$rel_path"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ -L "$src_path" ]]; then
|
||||
dst_path="$DST_ROOT/$rel_path"
|
||||
if [[ -e "$dst_path" || -L "$dst_path" ]]; then
|
||||
echo "Symlink exists, skipping: $dst_path"
|
||||
else
|
||||
mkdir -p "$(dirname "$dst_path")"
|
||||
ln -s "$(readlink "$src_path")" "$dst_path"
|
||||
echo "Created symlink: $dst_path"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ ! -f "$src_path" ]]; then
|
||||
echo "Skipping unsupported file type: $src_path" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
src_for_merge="$src_path"
|
||||
rel_for_target="$rel_path"
|
||||
mode="default"
|
||||
|
||||
if [[ "$rel_for_target" == *.tmpl.override ]]; then
|
||||
mode="override"
|
||||
rel_for_target="${rel_for_target%.tmpl.override}"
|
||||
rendered="$TMP_DIR/$rel_for_target"
|
||||
render_template "$src_path" "$rendered"
|
||||
src_for_merge="$rendered"
|
||||
|
||||
elif [[ "$rel_for_target" == *.override ]]; then
|
||||
mode="override"
|
||||
rel_for_target="${rel_for_target%.override}"
|
||||
|
||||
elif [[ "$rel_for_target" == *.tmpl ]]; then
|
||||
rel_for_target="${rel_for_target%.tmpl}"
|
||||
rendered="$TMP_DIR/$rel_for_target"
|
||||
render_template "$src_path" "$rendered"
|
||||
src_for_merge="$rendered"
|
||||
fi
|
||||
|
||||
dst_path="$DST_ROOT/$rel_for_target"
|
||||
|
||||
if [[ "$mode" == "override" ]]; then
|
||||
replace_file "$src_for_merge" "$dst_path"
|
||||
else
|
||||
merge_or_copy_file "$src_for_merge" "$dst_path" "$rel_for_target"
|
||||
fi
|
||||
done
|
||||
106
alpine/preload-k8s-images.sh
Executable file
106
alpine/preload-k8s-images.sh
Executable file
@@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
: "${KUBE_IMG_CACHE:?KUBE_IMG_CACHE is required}"
|
||||
: "${KUBE_VERSION:?KUBE_VERSION is required}"
|
||||
: "${ARCH:?ARCH is required}"
|
||||
|
||||
OS=linux
|
||||
REGISTRY_PORT=5000
|
||||
|
||||
# Keep everything version/arch scoped so caches do not get mixed.
|
||||
ARCHIVE_DIR="${KUBE_IMG_CACHE}/archives/${ARCH}/${KUBE_VERSION}"
|
||||
REGISTRY_DATA_DIR="${KUBE_IMG_CACHE}/registry-data/${ARCH}/${KUBE_VERSION}"
|
||||
REGISTRY_TAR="${KUBE_IMG_CACHE}/registry.tar"
|
||||
REGISTRY_IMAGE="docker.io/library/registry:2"
|
||||
|
||||
if podman image exists "${REGISTRY_IMAGE}"; then
|
||||
echo "Registry image already present: ${REGISTRY_IMAGE}"
|
||||
|
||||
elif [ -f "${REGISTRY_TAR}" ]; then
|
||||
echo "Loading registry image from cache: ${REGISTRY_TAR}"
|
||||
podman load -i "${REGISTRY_TAR}"
|
||||
|
||||
else
|
||||
echo "Cache miss → pulling and saving registry image"
|
||||
|
||||
podman pull "${REGISTRY_IMAGE}"
|
||||
podman save -o "${REGISTRY_TAR}" "${REGISTRY_IMAGE}"
|
||||
fi
|
||||
|
||||
mkdir -p "${ARCHIVE_DIR}"
|
||||
rm -rf "${REGISTRY_DATA_DIR}"
|
||||
mkdir -p "${REGISTRY_DATA_DIR}"
|
||||
|
||||
echo "============================================================"
|
||||
echo "Preparing Kubernetes image cache"
|
||||
echo " KUBE_VERSION = ${KUBE_VERSION}"
|
||||
echo " ARCH = ${ARCH}"
|
||||
echo " ARCHIVE_DIR = ${ARCHIVE_DIR}"
|
||||
echo " REGISTRY_DATA_DIR = ${REGISTRY_DATA_DIR}"
|
||||
echo "============================================================"
|
||||
|
||||
# Start a temporary local registry backed by REGISTRY_DATA_DIR.
|
||||
# We use host network here to avoid messing with nested networking.
|
||||
podman rm -f temp-registry >/dev/null 2>&1 || true
|
||||
|
||||
podman run -d \
|
||||
--name temp-registry \
|
||||
--network host \
|
||||
--cgroups=disabled \
|
||||
-v "${REGISTRY_DATA_DIR}:/var/lib/registry" \
|
||||
docker.io/library/registry:2
|
||||
|
||||
cleanup() {
|
||||
podman rm -f temp-registry >/dev/null 2>&1 || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Wait for registry to answer.
|
||||
for _ in $(seq 1 30); do
|
||||
if curl -fsS "http://127.0.0.1:${REGISTRY_PORT}/v2/" >/dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if ! curl -fsS "http://127.0.0.1:${REGISTRY_PORT}/v2/" >/dev/null; then
|
||||
echo "Temporary registry did not start"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Cache and seed all kubeadm-required images.
|
||||
while read -r img; do
|
||||
[ -n "$img" ] || continue
|
||||
|
||||
safe_name=$(printf '%s' "$img" | sed 's#/#_#g; s#:#__#g')
|
||||
archive="${ARCHIVE_DIR}/${safe_name}.tar"
|
||||
ref="${img#registry.k8s.io/}"
|
||||
|
||||
if [ ! -f "$archive" ]; then
|
||||
echo "Caching: $img"
|
||||
skopeo copy \
|
||||
--override-os "${OS}" \
|
||||
--override-arch "${ARCH}" \
|
||||
"docker://$img" \
|
||||
"oci-archive:$archive"
|
||||
else
|
||||
echo "Cache hit: $img"
|
||||
fi
|
||||
|
||||
if skopeo inspect --tls-verify=false "docker://127.0.0.1:${REGISTRY_PORT}/${ref}" >/dev/null 2>&1; then
|
||||
echo "Registry hit: 127.0.0.1:${REGISTRY_PORT}/${ref}"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Seeding registry: $ref"
|
||||
skopeo copy \
|
||||
--dest-tls-verify=false \
|
||||
"oci-archive:$archive" \
|
||||
"docker://127.0.0.1:${REGISTRY_PORT}/${ref}"
|
||||
done < <(qemu-aarch64-static "$ROOTFS/usr/local/bin/kubeadm" config images list --kubernetes-version "${KUBE_VERSION}")
|
||||
|
||||
echo
|
||||
echo "Done."
|
||||
echo "Archives: ${ARCHIVE_DIR}"
|
||||
echo "Registry data: ${REGISTRY_DATA_DIR}"
|
||||
1
alpine/rootfs-extra/etc/fstab
Normal file
1
alpine/rootfs-extra/etc/fstab
Normal file
@@ -0,0 +1 @@
|
||||
none /sys/fs/cgroup cgroup2 defaults 0 0
|
||||
1
alpine/rootfs-extra/etc/hostname.tmpl.override
Normal file
1
alpine/rootfs-extra/etc/hostname.tmpl.override
Normal file
@@ -0,0 +1 @@
|
||||
${ALPINE_HOSTNAME}
|
||||
2
alpine/rootfs-extra/etc/inittab
Normal file
2
alpine/rootfs-extra/etc/inittab
Normal file
@@ -0,0 +1,2 @@
|
||||
# Dev only
|
||||
ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100 -n -l /bin/bash
|
||||
56
alpine/rootfs-extra/opt/scripts/load-images.sh
Executable file
56
alpine/rootfs-extra/opt/scripts/load-images.sh
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
KUBE_VERSION="${KUBE_VERSION:-v1.35.3}"
|
||||
REGISTRY_ADDR="${REGISTRY_ADDR:-127.0.0.1:5000}"
|
||||
|
||||
mkdir -p /opt/registry
|
||||
cat >/opt/registry/config.yml <<EOF
|
||||
version: 0.1
|
||||
log:
|
||||
level: info
|
||||
storage:
|
||||
filesystem:
|
||||
rootdirectory: /var/lib/registry
|
||||
http:
|
||||
addr: ${REGISTRY_ADDR}
|
||||
EOF
|
||||
|
||||
cat >/opt/crictl.yaml <<'EOF'
|
||||
runtime-endpoint: unix:///var/run/crio/crio.sock
|
||||
image-endpoint: unix:///var/run/crio/crio.sock
|
||||
timeout: 10
|
||||
debug: false
|
||||
EOF
|
||||
|
||||
registry serve /opt/registry/config.yml >/var/log/registry.log 2>&1 &
|
||||
REG_PID=$!
|
||||
|
||||
cleanup() {
|
||||
kill "$REG_PID" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
for _ in $(seq 1 30); do
|
||||
if curl -fsS "http://${REGISTRY_ADDR}/v2/_catalog" >/dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
curl -fsS "http://${REGISTRY_ADDR}/v2/_catalog" >/dev/null
|
||||
|
||||
for img in $(kubeadm config images list --kubernetes-version "${KUBE_VERSION}"); do
|
||||
name="${img#registry.k8s.io/}"
|
||||
echo "Importing ${img} from ${REGISTRY_ADDR}/${name}"
|
||||
skopeo copy --src-tls-verify=false \
|
||||
"docker://${REGISTRY_ADDR}/${name}" \
|
||||
"containers-storage:${img}"
|
||||
done
|
||||
|
||||
echo "Imported images now visible to CRI-O:"
|
||||
crictl images
|
||||
|
||||
kill "$REG_PID" 2>/dev/null || true
|
||||
wait "$REG_PID" 2>/dev/null || true
|
||||
trap - EXIT INT TERM
|
||||
@@ -6,6 +6,10 @@ TAG=dev
|
||||
# The Linux kernel, from NXP
|
||||
NXP_VERSION=lf-6.18.2-1.0.0
|
||||
CRIO_VERSION=cri-o.arm64.v1.35.1
|
||||
KUBE_VERSION=v1.35.3
|
||||
|
||||
# Local registry for exporting k8s images
|
||||
REGISTRY_VERSION=2.8.3
|
||||
|
||||
# Mono's tutorial said fsl-ls1046a-rdb.dtb but our shipped board is not that one
|
||||
# We need fsl-ls1046a-rdb-sdk.dtb here
|
||||
@@ -23,3 +27,6 @@ BUSYBOX_VERSION=1_36_1
|
||||
## Alpine Linux
|
||||
ALPINE_VER=3.23.3
|
||||
ALPINE_ARCH=aarch64
|
||||
|
||||
# Only applies to new installations
|
||||
ALPINE_HOSTNAME=monok8s-hostname
|
||||
|
||||
@@ -6,12 +6,14 @@ FROM --platform=$BUILDPLATFORM ${DOCKER_IMAGE_ROOT}/build-base:${TAG} AS build-b
|
||||
ARG ALPINE_ARCH
|
||||
ARG ALPINE_VER
|
||||
ARG CRIO_VERSION
|
||||
ARG REGISTRY_VERSION
|
||||
ARG DEVICE_TREE_TARGET
|
||||
|
||||
RUN mkdir -p "/out/rootfs"
|
||||
|
||||
COPY packages/alpine-minirootfs-${ALPINE_VER}-${ALPINE_ARCH}.tar.gz ./alpine.tar.gz
|
||||
COPY packages/${CRIO_VERSION}.tar.gz ./crio.tar.gz
|
||||
COPY packages/registry-${REGISTRY_VERSION}.tar.gz ./registry.tar.gz
|
||||
COPY out/board.itb ./
|
||||
COPY out/rootfs ./rootfs
|
||||
COPY out/${DEVICE_TREE_TARGET}.dtb ./
|
||||
@@ -19,5 +21,9 @@ COPY out/Image.gz ./
|
||||
|
||||
RUN tar -xf alpine.tar.gz -C "/out/rootfs"
|
||||
|
||||
COPY alpine/etc ./rootfs/etc
|
||||
RUN mkdir -p /out/rootfs/usr/local/bin/
|
||||
COPY packages/kubernetes/* /out/rootfs/usr/local/bin/
|
||||
RUN chmod +x /out/rootfs/usr/local/bin/*
|
||||
|
||||
COPY alpine/rootfs-extra ./rootfs-extra
|
||||
COPY alpine/*.sh /
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM --platform=$BUILDPLATFORM debian:bookworm-slim AS kernel-build
|
||||
FROM --platform=$BUILDPLATFORM debian:trixie-slim AS kernel-build
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
@@ -10,11 +10,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
bison \
|
||||
build-essential \
|
||||
cpio \
|
||||
ca-certificates \
|
||||
curl \
|
||||
dosfstools \
|
||||
file \
|
||||
fdisk \
|
||||
fuse-overlayfs \
|
||||
gdisk \
|
||||
e2fsprogs \
|
||||
flex \
|
||||
git \
|
||||
gettext-base \
|
||||
@@ -27,6 +30,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
perl \
|
||||
python3 \
|
||||
qemu-user-static \
|
||||
podman \
|
||||
skopeo \
|
||||
rsync \
|
||||
tar \
|
||||
udev \
|
||||
|
||||
@@ -19,7 +19,9 @@ RUN tar -xf busybox-${BUSYBOX_VERSION}.tar.gz && mv "busybox-${BUSYBOX_VERSION}"
|
||||
WORKDIR /build/busybox
|
||||
|
||||
RUN make ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} defconfig \
|
||||
&& sed -i 's/^# CONFIG_STATIC is not set/CONFIG_STATIC=y/' .config
|
||||
&& sed -i \
|
||||
-e 's/^# CONFIG_STATIC is not set/CONFIG_STATIC=y/' \
|
||||
-e 's/^CONFIG_TC=.*/# CONFIG_TC is not set/' .config
|
||||
RUN make CROSS_COMPILE=${CROSS_COMPILE} -j"$(nproc)"
|
||||
RUN make CROSS_COMPILE=${CROSS_COMPILE} CONFIG_PREFIX=/out/initramfs install
|
||||
|
||||
|
||||
36
makefile
36
makefile
@@ -10,6 +10,12 @@ BUSYBOX_TAR := $(PACKAGES_DIR)/busybox-$(BUSYBOX_VERSION).tar.gz
|
||||
ALPINE_TAR := $(PACKAGES_DIR)/alpine-minirootfs-$(ALPINE_VER)-$(ALPINE_ARCH).tar.gz
|
||||
NXP_TAR := $(PACKAGES_DIR)/$(NXP_VERSION).tar.gz
|
||||
CRIO_TAR := $(PACKAGES_DIR)/$(CRIO_VERSION).tar.gz
|
||||
REGISTRY_TAR := $(PACKAGES_DIR)/registry-$(REGISTRY_VERSION).tar.gz
|
||||
|
||||
# Kubernetes components
|
||||
KUBELET_BIN := $(PACKAGES_DIR)/kubernetes/kubelet
|
||||
KUBEADM_BIN := $(PACKAGES_DIR)/kubernetes/kubeadm
|
||||
KUBECTL_BIN := $(PACKAGES_DIR)/kubernetes/kubectl
|
||||
|
||||
BOARD_ITB := $(OUT_DIR)/board.itb
|
||||
INITRAMFS := $(OUT_DIR)/initramfs.cpio.gz
|
||||
@@ -62,6 +68,10 @@ RELEASE_DEPS := \
|
||||
$(BOARD_ITB) \
|
||||
$(ALPINE_TAR) \
|
||||
$(CRIO_TAR) \
|
||||
$(KUBELET_BIN) \
|
||||
$(KUBEADM_BIN) \
|
||||
$(KUBECTL_BIN) \
|
||||
$(REGISTRY_TAR) \
|
||||
docker/alpine.Dockerfile \
|
||||
$(ALPINE_SRCS) \
|
||||
build.env \
|
||||
@@ -71,11 +81,23 @@ RELEASE_DEPS := \
|
||||
|
||||
$(PACKAGES_DIR):
|
||||
mkdir -p $@
|
||||
mkdir -p $@/kubernetes
|
||||
|
||||
$(OUT_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
# ---- Package downloads -------------------------------------------------------
|
||||
$(KUBELET_BIN): | $(PACKAGES_DIR)
|
||||
curl -L -o $@ "https://dl.k8s.io/$(KUBE_VERSION)/bin/linux/$(ARCH)/kubelet"
|
||||
|
||||
$(KUBEADM_BIN): | $(PACKAGES_DIR)
|
||||
curl -L -o $@ "https://dl.k8s.io/$(KUBE_VERSION)/bin/linux/$(ARCH)/kubeadm"
|
||||
|
||||
$(KUBECTL_BIN): | $(PACKAGES_DIR)
|
||||
curl -L -o $@ "https://dl.k8s.io/$(KUBE_VERSION)/bin/linux/$(ARCH)/kubectl"
|
||||
|
||||
$(KUBEADM_BIN): | $(PACKAGES_DIR)
|
||||
curl -L -o $@ "https://dl.k8s.io/$(KUBE_VERSION)/bin/linux/$(ARCH)/kubeadm"
|
||||
|
||||
$(BUSYBOX_TAR): | $(PACKAGES_DIR)
|
||||
curl -L -o $@ "https://github.com/mirror/busybox/archive/refs/tags/$(BUSYBOX_VERSION).tar.gz"
|
||||
@@ -83,6 +105,9 @@ $(BUSYBOX_TAR): | $(PACKAGES_DIR)
|
||||
$(ALPINE_TAR): | $(PACKAGES_DIR)
|
||||
curl -L -o $@ "https://dl-cdn.alpinelinux.org/alpine/v$(ALPINE_SERIES)/releases/$(ALPINE_ARCH)/alpine-minirootfs-$(ALPINE_VER)-$(ALPINE_ARCH).tar.gz"
|
||||
|
||||
$(REGISTRY_TAR): | $(PACKAGES_DIR)
|
||||
curl -L -o $@ "https://github.com/distribution/distribution/releases/download/v$(REGISTRY_VERSION)/registry_$(REGISTRY_VERSION)_linux_$(ARCH).tar.gz"
|
||||
|
||||
$(NXP_TAR): | $(PACKAGES_DIR)
|
||||
curl -L -o $@ "https://github.com/nxp-qoriq/linux/archive/refs/tags/$(NXP_VERSION).tar.gz"
|
||||
|
||||
@@ -139,16 +164,22 @@ $(RELEASE_IMAGE): $(RELEASE_DEPS) | $(OUT_DIR)
|
||||
--build-arg ALPINE_ARCH=$(ALPINE_ARCH) \
|
||||
--build-arg ALPINE_VER=$(ALPINE_VER) \
|
||||
--build-arg CRIO_VERSION=$(CRIO_VERSION) \
|
||||
--build-arg REGISTRY_VERSION=$(REGISTRY_VERSION) \
|
||||
--build-arg DEVICE_TREE_TARGET=$(DEVICE_TREE_TARGET) \
|
||||
-t $(DOCKER_IMAGE_ROOT)/buildenv-alpine:$(TAG) .
|
||||
|
||||
@cid=$$(docker create \
|
||||
--privileged \
|
||||
-v /cache/k8s-images:/var/cache/k8s-images \
|
||||
-v /cache/apk:/var/cache/apk \
|
||||
--device=/dev/loop0:/dev/loop0 \
|
||||
-e ROOTFS=/out/rootfs \
|
||||
-e RELEASE_IMAGE=$(RELEASE_IMAGE) \
|
||||
-e DEVICE_TREE_TARGET=$(DEVICE_TREE_TARGET) \
|
||||
-e KUBE_IMG_CACHE=/var/cache/k8s-images \
|
||||
-e KUBE_VERSION=$(KUBE_VERSION) \
|
||||
-e ALPINE_HOSTNAME=$(ALPINE_HOSTNAME) \
|
||||
-e ARCH=$(ARCH) \
|
||||
$(DOCKER_IMAGE_ROOT)/buildenv-alpine:$(TAG) \
|
||||
bash -lc '/build-rootfs.sh'); \
|
||||
docker start -a $$cid; \
|
||||
@@ -175,6 +206,9 @@ clean:
|
||||
$(RELEASE_IMAGE)
|
||||
|
||||
distclean: clean
|
||||
rm -rf $(OUT_DIR) $(PACKAGES_DIR)
|
||||
rm -rf $(OUT_DIR)
|
||||
|
||||
pkgclean:
|
||||
rm -rf $(PACKAGES_DIR)
|
||||
|
||||
.PHONY: release kernel initramfs itb build-base clean distclean
|
||||
|
||||
Reference in New Issue
Block a user