Ctrl K
ComunidadGuías…

Dockerfile

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# syntax=docker/dockerfile:1.28

# Unified multi-target Dockerfile for all pillar-csi components.
#
# Targets:
#   controller — CSI controller (distroless, no runtime deps)
#   agent      — pillar-agent gRPC server (alpine + ZFS + LVM2 + NFS server)
#   node       — CSI node plugin (alpine + mount/NFS utils + e2fsprogs + xfsprogs)
#
# Usage:
#   docker buildx bake                  # build all 3 images
#   docker buildx bake controller       # build controller only
#   docker build --target=agent .       # build agent only
#
# Security posture (all targets):
#   - Non-root default user: UID/GID 65532 ("nonroot" convention)
#   - Statically-linked Go binary (CGO_ENABLED=0), -trimpath
#   - Versions pinned; update SHA digests when bumping
#
# See docker-bake.hcl for the build matrix and CI integration.

# ── Builder stage ─────────────────────────────────────────────────────────────
FROM --platform=$BUILDPLATFORM golang:1.27.3-alpine3.24 AS builder

WORKDIR /workspace

# Download dependencies first to maximise build-cache hits on source changes.
COPY go.mod go.sum ./
RUN go mod download

COPY . .
ARG TARGETOS
ARG TARGETARCH
# TARGETVARIANT is set by buildx for sub-architecture levels (e.g. "v3" for
# linux/amd64/v3, "v7" for linux/arm/v7, "v8.2" for linux/arm64/v8.2).  Empty
# for the architecture default (linux/amd64, linux/arm64).
ARG TARGETVARIANT

# Build all binaries under cmd/ in one invocation.  The -o flag with a
# directory target writes each binary (named after its package directory)
# into that directory.  This works with cross-compilation unlike go install
# which rejects GOBIN when GOOS/GOARCH differ from the host.
#
# Map the BuildKit TARGETVARIANT to the matching Go toolchain env var so each
# manifest in the multi-platform image carries a binary tuned for that
# instruction-set level:
#   amd64/v1..v4 → GOAMD64 (Go 1.21+; default v1)
#   arm/v6,v7    → GOARM   (strip the leading 'v')
#   arm64/v8.0..v9.5 → GOARM64 (Go 1.23+; default v8.0)
RUN --mount=type=cache,target=/root/.cache/go-build set -eu; \
    GOAMD64=""; GOARM=""; GOARM64=""; \
    case "$TARGETARCH" in \
      amd64) GOAMD64="${TARGETVARIANT:-v1}" ;; \
      arm)   GOARM="${TARGETVARIANT#v}" ;; \
      arm64) GOARM64="${TARGETVARIANT:-v8.0}" ;; \
    esac; \
    CGO_ENABLED=0 GOOS="${TARGETOS:-linux}" GOARCH="${TARGETARCH}" \
    GOAMD64="$GOAMD64" GOARM="$GOARM" GOARM64="$GOARM64" \
    go build \
      -trimpath \
      -pgo=auto \
      -ldflags="-s -w" \
      -o /workspace/bin/ \
      ./cmd/...

# ── Runtime: controller ───────────────────────────────────────────────────────
# Distroless — no shell, no package manager, minimal attack surface.
FROM gcr.io/distroless/static:nonroot AS controller
COPY --from=builder --link /workspace/bin/controller /usr/bin/manager
USER 65532:65532
ENTRYPOINT ["/usr/bin/manager"]

# ── Runtime: agent ────────────────────────────────────────────────────────────
# Alpine + ZFS + LVM2 + nfs-utils userspace tools. The agent invokes zfs(8),
# zpool(8), lvcreate(8), lvremove(8), rpc.mountd(8) and nfsdcld(8), plus
# exportfs(8) from its relocated /usr/libexec/pillar-csi path (see below).
# NVMe-oF uses configfs directly; NFS uses the host kernel nfsd and a supervised
# userspace NFSv4 client-recovery daemon with private persistent state.
#
# Runtime security (enforced in the DaemonSet manifest):
#   --security-opt=no-new-privileges:true
#   --read-only  (combine with tmpfs mounts for /tmp, /run)
#   --cap-drop ALL --cap-add SYS_ADMIN  (ZFS + configfs need SYS_ADMIN)
FROM alpine:3.24.3 AS agent
RUN set -eux \
    && apk add --no-cache 'zfs~=2.4' lvm2 nfs-utils blkid \
    # OpenZFS libshare runs the hard-coded `/usr/sbin/exportfs -ra` after every
    # zfs create/mount/destroy whenever /usr/sbin/exportfs exists
    # (lib/libshare/os/linux/nfs.c), rewriting /var/lib/nfs/etab from the empty
    # /etc/exports and wiping pillar's export rows. Move exportfs out of that
    # path so libzfs treats NFS sharing as unavailable (a no-op commit) while
    # the agent keeps calling it via its absolute relocated path. The `test`
    # is the build-time guard: this is the final agent layer, apk is removed
    # below, and no later instruction reinstalls nfs-utils.
    && install -d -m 0755 /usr/libexec/pillar-csi \
    && mv /usr/sbin/exportfs /usr/libexec/pillar-csi/exportfs \
    && test ! -e /usr/sbin/exportfs \
    # Configure LVM for container environments where udevd is not running.
    && sed -i 's/obtain_device_list_from_udev = 1/obtain_device_list_from_udev = 0/' /etc/lvm/lvm.conf \
    && sed -i 's/udev_sync = 1/udev_sync = 0/' /etc/lvm/lvm.conf \
    && sed -i 's/udev_rules = 1/udev_rules = 0/' /etc/lvm/lvm.conf \
    && addgroup -g 65532 nonroot \
    && adduser  -u 65532 -G nonroot -s /sbin/nologin -D nonroot \
    # Strip SUID/SGID bits from every file on the root filesystem.
    && (find / -xdev \( -perm -4000 -o -perm -2000 \) -exec chmod a-s {} + 2>/dev/null || true) \
    # Remove package manager (prevents `apk add` at runtime).
    && rm -rf /sbin/apk /etc/apk /lib/apk /usr/share/apk /var/lib/apk \
    # Remove shell (no interactive escape path).
    && rm -f /bin/sh /bin/bash /usr/bin/env
COPY --from=builder --link --chmod=0555 /workspace/bin/agent /usr/bin/pillar-agent
USER 65532:65532
EXPOSE 2049/tcp
EXPOSE 9500
ENTRYPOINT ["/usr/bin/pillar-agent"]

# ── Runtime: node ─────────────────────────────────────────────────────────────
# Alpine + mount utilities (util-linux) + ext4/XFS formatting and resize tools
# (e2fsprogs, xfsprogs).  xfsprogs-extra carries xfs_growfs on Alpine, and the
# mkfs.xfs LTS profiles under /usr/share/xfsprogs/mkfs: the node plugin formats
# XFS with the Linux 5.15 one so every supported node kernel can mount the
# volume.  hack/verify-mkfs-baseline.sh fails the build when the image's mkfs
# would create a filesystem Linux 5.15 cannot mount.
# device-mapper carries dmsetup, which holds the backend device of a local
# attach on the storage node through a linear target.
# nfs-utils supplies mount.nfs for NFSv4.2 stages without host package installs.
#
# Runtime security (enforced in the DaemonSet manifest):
#   --security-opt=no-new-privileges:true
#   --read-only  (combine with tmpfs mounts for /tmp, /run)
#   --cap-drop ALL --cap-add SYS_ADMIN  (mount(8) and NVMe-oF need SYS_ADMIN)
FROM alpine:3.24.3 AS node
RUN --mount=type=bind,source=hack/verify-mkfs-baseline.sh,target=/tmp/verify-mkfs-baseline.sh \
    set -eux \
    && apk add --no-cache \
         'util-linux~=2.42' \
         'e2fsprogs~=1.47' \
         'e2fsprogs-extra~=1.47' \
         'xfsprogs~=7.0' \
         'xfsprogs-extra~=7.0' \
         'device-mapper~=2.03' \
         'quota-tools~=4.11' \
         nfs-utils; \
    # A separate command: the "|| true" below would mask a failure in the chain.
    sh /tmp/verify-mkfs-baseline.sh; \
    addgroup -g 65532 nonroot \
    && adduser  -u 65532 -G nonroot -s /sbin/nologin -D nonroot \
    # Strip SUID/SGID bits from every file on the root filesystem.
    && find / -xdev \( -perm -4000 -o -perm -2000 \) -exec chmod a-s {} + 2>/dev/null || true \
    # Remove package manager (prevents `apk add` at runtime).
    && rm -rf /sbin/apk /etc/apk /lib/apk /usr/share/apk /var/lib/apk \
    # Remove shell (no interactive escape path).
    && rm -f /bin/sh /bin/bash /usr/bin/env
COPY --from=builder --link --chmod=0555 /workspace/bin/node /usr/bin/pillar-node
USER 65532:65532
ENTRYPOINT ["/usr/bin/pillar-node"]