diff --git a/tools/packaging/kata-monitor/Dockerfile b/tools/packaging/kata-monitor/Dockerfile index d71eaaff3d..f23802396e 100644 --- a/tools/packaging/kata-monitor/Dockerfile +++ b/tools/packaging/kata-monitor/Dockerfile @@ -1,28 +1,74 @@ # Copyright (c) 2020 Eric Ernst +# Copyright (c) 2026 NVIDIA # SPDX-License-Identifier: Apache-2.0 -ARG GO_VERSION -FROM golang:${GO_VERSION}-alpine AS builder +# +# Build context: extracted kata-static shim-v2-go tarball root. +# +# Expected file in context: +# ./opt/kata/bin/kata-monitor +# +# The kata-monitor binary is built inside an Ubuntu (glibc) toolchain +# as part of the shim-v2-go static build, so it is dynamically linked +# against glibc. We assemble its runtime dependencies via `ldd` from +# a glibc base image and copy them into a distroless/static runtime +# image, matching the same pattern used by +# tools/packaging/kata-deploy/Dockerfile. -RUN apk add --no-cache bash curl git make build-base -WORKDIR /go/src/github.com/kata-containers/kata-containers/src/runtime +# Stage 1: discover and copy the glibc libraries the binary needs. +# hadolint ignore=DL3007 +FROM debian:trixie-slim AS runtime-assembler -COPY src/runtime/go.* . -RUN --mount=type=cache,target=/go/pkg/mod \ - --mount=type=cache,target=/root/.cache/go-build \ - go mod download +SHELL ["/bin/bash", "-o", "pipefail", "-c"] -COPY . /go/src/github.com/kata-containers/kata-containers -RUN --mount=type=cache,target=/go/pkg/mod \ - --mount=type=cache,target=/root/.cache/go-build \ - make SKIP_GO_VERSION_CHECK=true monitor +COPY opt/kata/bin/kata-monitor /tmp/kata-monitor -# run tests -RUN --mount=type=cache,target=/go/pkg/mod \ - --mount=type=cache,target=/root/.cache/go-build \ - cd pkg/kata-monitor/ && go test -c -o /tmp/tests -RUN /tmp/tests +RUN \ + set -eux; \ + mkdir -p /output/lib /output/lib64; \ + echo "Libraries needed by kata-monitor on $(uname -m):"; \ + ldd /tmp/kata-monitor || true; \ + # Copy each shared library reported by ldd ("=>" lines). + ldd /tmp/kata-monitor 2>/dev/null | grep "=>" | awk '{print $3}' | sort -u | \ + while read -r lib; do \ + if [ -n "${lib}" ] && [ -f "${lib}" ]; then \ + dest_dir="/output$(dirname "${lib}")"; \ + mkdir -p "${dest_dir}"; \ + cp -Ln "${lib}" "${dest_dir}/" || true; \ + echo " Copied lib: ${lib}"; \ + fi; \ + done; \ + # Copy the dynamic linker too: ldd does not include it in the "=>" + # lines. Cover all four target architectures: + # x86_64 -> /lib64/ld-linux-x86-64.so.2 + # aarch64 -> /lib/ld-linux-aarch64.so.1 + # s390x -> /lib/ld64.so.1 + # ppc64le -> /lib64/ld64.so.2 + for ld in /lib*/ld-linux-*.so.* /lib*/ld64.so.*; do \ + [ -f "${ld}" ] || continue; \ + dest_dir="/output$(dirname "${ld}")"; \ + mkdir -p "${dest_dir}"; \ + cp -Ln "${ld}" "${dest_dir}/" || true; \ + echo " Copied linker: ${ld}"; \ + done + +# Stage 2: final distroless image. +# +# We deliberately track the rolling `latest` tag rather than pinning a +# digest. distroless/static-debian13 publishes no semver tags and is +# rebuilt frequently to pick up base-image CVE fixes, so following +# `latest` keeps the kata-monitor runtime on the newest patched base. +# The image only carries the handful of glibc libraries we copy in plus +# the kata-monitor binary, so the blast radius of an unexpected base +# bump is tiny. hadolint's "pin the version" check is therefore not +# something we want here. +# hadolint ignore=DL3007 +FROM gcr.io/distroless/static-debian13:latest + +COPY --from=runtime-assembler /output/lib/ /lib/ +COPY --from=runtime-assembler /output/lib64/ /lib64/ +COPY opt/kata/bin/kata-monitor /usr/bin/kata-monitor + +EXPOSE 8090 -FROM alpine:3.14 -COPY --from=builder /go/src/github.com/kata-containers/kata-containers/src/runtime/kata-monitor /usr/bin/kata-monitor -CMD ["-h"] ENTRYPOINT ["/usr/bin/kata-monitor"] +CMD ["--help"] diff --git a/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh b/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh new file mode 100755 index 0000000000..30b2257566 --- /dev/null +++ b/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2026 NVIDIA +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -o errexit +set -o nounset +set -o pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +repo_root_dir="$(cd "${script_dir}/../../.." && pwd)" + +image_ref="${1:?image ref is required (e.g. quay.io/org/repo:tag)}" +shim_tarball="${2:?path to kata-static-shim-v2-go.tar.zst is required}" +push_image="${3:-true}" + +case "$(uname -m)" in + x86_64) platform_arch="amd64" ;; + aarch64) platform_arch="arm64" ;; + s390x) platform_arch="s390x" ;; + ppc64le) platform_arch="ppc64le" ;; + *) echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;; +esac + +tmpdir="$(mktemp -d)" +cleanup() { + rm -rf "${tmpdir}" +} +trap cleanup EXIT + +tar --zstd -xf "${shim_tarball}" -C "${tmpdir}" + +if [[ ! -x "${tmpdir}/opt/kata/bin/kata-monitor" ]]; then + echo "kata-monitor binary not found in ${shim_tarball}" >&2 + exit 1 +fi + +push_flag=() +if [[ "${push_image}" == "true" ]]; then + push_flag+=(--push) +fi + +docker buildx build \ + --platform "linux/${platform_arch}" \ + --provenance false --sbom false \ + -f "${repo_root_dir}/tools/packaging/kata-monitor/Dockerfile" \ + --tag "${image_ref}" \ + "${push_flag[@]}" \ + "${tmpdir}"