-
Notifications
You must be signed in to change notification settings - Fork 255
feat(telegraf): Add distroless container based on scratch base-image #892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
skartikey
merged 1 commit into
influxdata:master
from
victor-gama:victor-gama/addTelegrafDistroless
Sep 17, 2026
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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,90 @@ | ||
| # Telegraf on scratch: the static (CGO_ENABLED=0) binary plus only the runtime | ||
| # files it needs: no shell, package manager, or OS userland. The alpine stage | ||
| # GPG-verifies the release and assembles the exact final image tree under | ||
| # /rootfs; the scratch stage is a single COPY of it. | ||
|
|
||
| ARG TELEGRAF_VERSION=1.39.1 | ||
|
|
||
| FROM alpine:3.23 AS fetch | ||
| ARG TELEGRAF_VERSION | ||
|
|
||
| RUN set -eux; \ | ||
| case "$(apk --print-arch)" in \ | ||
| x86_64) ARCH='amd64';; \ | ||
| aarch64) ARCH='arm64';; \ | ||
| *) echo "Unsupported architecture: $(apk --print-arch)" >&2; exit 1;; \ | ||
| esac; \ | ||
| apk add --no-cache ca-certificates tzdata wget gnupg tar; \ | ||
| update-ca-certificates; \ | ||
| mkdir -p ~/.gnupg; echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf; \ | ||
| gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 24C975CBA61A024EE1B631787C3D57159FC2F927; \ | ||
| base="telegraf-${TELEGRAF_VERSION}_linux_${ARCH}.tar.gz"; \ | ||
| wget --no-verbose "https://dl.influxdata.com/telegraf/releases/${base}"; \ | ||
| wget --no-verbose "https://dl.influxdata.com/telegraf/releases/${base}.asc"; \ | ||
| gpg --batch --verify "${base}.asc" "${base}"; \ | ||
| mkdir -p /src /rootfs/usr/bin /rootfs/etc/telegraf /rootfs/etc/ssl/certs /rootfs/usr/share; \ | ||
| tar -C /src -xzf "${base}"; \ | ||
| # Copy from the explicit `telegraf-<v>/` prefix: release tar roots vary (some | ||
| # add a leading ./), which makes a fixed --strip-components unreliable. | ||
| src="/src/telegraf-${TELEGRAF_VERSION}"; \ | ||
| cp -a "${src}/usr/bin/telegraf" /rootfs/usr/bin/telegraf; \ | ||
| cp -a "${src}/etc/telegraf/telegraf.conf" /rootfs/etc/telegraf/telegraf.conf; \ | ||
| cp -a "${src}/etc/telegraf/telegraf.d" /rootfs/etc/telegraf/telegraf.d; \ | ||
| cp /etc/ssl/certs/ca-certificates.crt /rootfs/etc/ssl/certs/ca-certificates.crt; \ | ||
| cp -a /usr/share/zoneinfo /rootfs/usr/share/zoneinfo; \ | ||
| # Resolve hostnames via /etc/hosts before DNS. | ||
| printf 'hosts: files dns\n' > /rootfs/etc/nsswitch.conf; \ | ||
| # Lets pure-Go os/user (CGO_ENABLED=0) map uid 65532 to a name; without it | ||
| # lookups like procstat's user tag fail silently. USER below sets the identity. | ||
| # We name the account "telegraf" (matching the alpine image) but keep the uid | ||
| # 65532 (the distroless "nonroot" uid), NOT 65534/nobody: 65534 is the | ||
| # kernel overflow uid, the id that unmapped user-namespace ids and NFS root-squash | ||
| # collapse to, so running as it would make telegraf indistinguishable from a | ||
| # failed-to-map process to security/monitoring tooling. 65532 sits outside that. | ||
| # overflow uid default 65534: https://www.kernel.org/doc/html/latest/admin-guide/sysctl/kernel.html | ||
| # unmapped userns id -> overflow: https://man7.org/linux/man-pages/man7/user_namespaces.7.html | ||
| # distroless nonroot = 65532: https://github.com/GoogleContainerTools/distroless/blob/main/common/variables.bzl | ||
| # (nobody is kept in the map so 65534-owned files still resolve; we just never run as it.) | ||
| printf 'root:x:0:0:root:/root:/sbin/nologin\nnobody:x:65534:65534:nobody:/nonexistent:/sbin/nologin\ntelegraf:x:65532:65532:telegraf:/home/telegraf:/sbin/nologin\n' > /rootfs/etc/passwd; \ | ||
| printf 'root:x:0:\nnobody:x:65534:\ntelegraf:x:65532:\n' > /rootfs/etc/group; \ | ||
| # /tmp is 1777 (world-writable + sticky) so a container running under an | ||
| # arbitrary uid (e.g. the random uid OpenShift's default SCC assigns) gets a | ||
| # writable /tmp, not just uid 65532. BuildKit, which official-images publishes | ||
| # with, preserves this mode through COPY; buildah does too. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [question] An earlier revision said buildah doesn't keep mode bits through COPY, and now this line and line 77 say it does. Did you test that with buildah, or was it just reworded? If it wasn't tested, I'd only mention BuildKit here. |
||
| # /home/telegraf stays 65532-owned; telegraf needs no writable HOME. | ||
| # Numeric id in chown, not "telegraf": the alpine stage's /etc/passwd has no | ||
| # telegraf user, so a BusyBox name lookup would fail ("unknown user/group") and | ||
| # abort under set -eux; a numeric id skips the lookup. | ||
| # https://github.com/vda-linux/busybox_mirror/blob/ec0c5cc142f1f9ea57235df5d093fbe180ad9c7d/libpwdgrp/uidgid_get.c#L77-L80 | ||
| mkdir -p /rootfs/home/telegraf /rootfs/tmp; \ | ||
| chown 65532:65532 /rootfs/home/telegraf /rootfs/tmp; \ | ||
| chmod 1777 /rootfs/tmp | ||
|
|
||
| FROM scratch | ||
|
|
||
| ARG TELEGRAF_VERSION | ||
| ENV TELEGRAF_VERSION=${TELEGRAF_VERSION} | ||
| LABEL org.opencontainers.image.title="telegraf" \ | ||
| org.opencontainers.image.description="Distroless Telegraf: static binary on scratch (no shell, no OS userland, non-root)" \ | ||
| org.opencontainers.image.version="${TELEGRAF_VERSION}" \ | ||
| org.opencontainers.image.source="https://github.com/influxdata/influxdata-docker" \ | ||
| org.opencontainers.image.base.name="scratch" \ | ||
| org.opencontainers.image.vendor="InfluxData Inc." \ | ||
| org.opencontainers.image.licenses="MIT" | ||
|
|
||
| # The whole rootfs was staged and GPG-verified in the fetch stage; one COPY | ||
| # brings it over. Ownership (incl. the 65532-owned /home/telegraf and /tmp) is | ||
| # preserved by docker, podman, and buildah alike. | ||
| COPY --from=fetch /rootfs/ / | ||
|
|
||
| ENV HOME=/home/telegraf | ||
|
|
||
| # Numeric, not a name: with runAsNonRoot=true the kubelet reads the image's USER | ||
| # field directly (never its /etc/passwd), so a named user fails admission | ||
| # ("cannot verify user is non-root"). 65532 is the distroless "nonroot" uid, | ||
| # which we name "telegraf" in the image's /etc/passwd. | ||
| # https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/kuberuntime/security_context_others.go#L50 | ||
| USER 65532:65532 | ||
|
|
||
| ENTRYPOINT ["/usr/bin/telegraf"] | ||
|
skartikey marked this conversation as resolved.
|
||
| CMD ["--config", "/etc/telegraf/telegraf.conf", "--config-directory", "/etc/telegraf/telegraf.d"] | ||
This file contains hidden or 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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.