diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index e42d3d2..8fe0407 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -470,11 +470,12 @@ installer). ### 8e. Build Pods never start: executor images and air-gapped installs The build Job runs Kaniko and Trivy from external registries by default -(`gcr.io/kaniko-project/executor:latest`, `aquasec/trivy:latest`). On a box whose -build namespace cannot reach those registries (the egress policy allows only -DNS, the internal registry and `--package-cidr` mirrors — and an air-gapped box -has no route at all), the Pods sit in `ImagePullBackOff`/`ErrImagePull` and the -build stays `building` until its deadline. Point the overrides at images **in +(`gcr.io/kaniko-project/executor:latest`, `aquasec/trivy:latest`). The kubelet +pulls those images over the node's own network, so the build namespace's egress +policy does not apply to the pull; what blocks it is a node without a route to +those registries (an air-gapped box, a firewall, a rate-limited Docker Hub). +The Pods then sit in `ImagePullBackOff`/`ErrImagePull` and the build stays +`building` until its deadline. Point the overrides at images **in the internal registry** — the one pull source that survives an image GC (a bare node-containerd import does not: kubelet's image GC collects unused images under disk pressure, and an air-gapped box then has nothing to restore them from) — diff --git a/internal/config/config.go b/internal/config/config.go index 5a2c3b5..3aefd66 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -149,14 +149,12 @@ type RegistryConfig struct { BuildNamespace string `toml:"build_namespace"` // KanikoImage / TrivyImage / BuildCPULimit / BuildMemLimit override the // build subsystem's compiled-in defaults (gcr.io/kaniko-project/executor and - // aquasec/trivy, 2 CPU / 4Gi per build container). The defaults assume the - // build namespace can reach those registries; on an air-gapped or mirrored - // install there IS no such reach (the build egress policy allows only DNS, - // the internal registry and explicit package mirrors), so the operator must - // point these at whatever their box can actually pull — typically images - // mirrored into the in-cluster registry (docs/troubleshooting.md §8e); a - // bare node-containerd import does not survive an image GC, there is no pull - // source for it. Empty keeps the default. + // aquasec/trivy, 2 CPU / 4Gi per build container). The kubelet pulls the + // executor images over the node's network, so the defaults need a node that + // can reach those registries; an air-gapped or mirrored install points these + // at images mirrored into the in-cluster registry (docs/troubleshooting.md + // §8e). A bare node-containerd import does not survive an image GC, there is + // no pull source for it. Empty keeps the default. KanikoImage string `toml:"kaniko_image"` TrivyImage string `toml:"trivy_image"` BuildCPULimit string `toml:"build_cpu_limit"` diff --git a/internal/submit/blobstore.go b/internal/submit/blobstore.go index 3841aa2..406bf5c 100644 --- a/internal/submit/blobstore.go +++ b/internal/submit/blobstore.go @@ -32,16 +32,13 @@ var idRE = regexp.MustCompile(`^[a-z0-9][a-z0-9-]{0,127}$`) // Manager.Blobs nil so the upload endpoint returns 503 rather than pretending to // accept a file it cannot persist. // -// Base MUST equal the Manager's ContextStore so the blob lands exactly where -// deriveContextRef points Kaniko's --context; cmd/felis wires both from the one +// Base MUST equal the Manager's ContextStore; cmd/felis wires both from the one // config field (registry.user_uploads_context). // -// INTEGRATION-ONLY seam (out of scope of the upload transport): persisting the -// blob is end-to-end only once the same uploads PVC is mounted into the Kaniko -// build Pod and Kaniko is told to read a local context (build/jobspec.go passes -// the ref straight into --context). The transport here makes the file durable at -// the derived location; wiring that path into the sandboxed build Job is a -// separate deployment integration, exactly like the restore executor's PVC mount. +// The build Pod never mounts this PVC. With Manager.ContextBaseURL set (every +// installed API) the derived context ref is the internal face's +// /api/v1/internal/submissions/{id}/context route, which streams the blob out +// of this store to the build Job's `felis fetch-context` step. type LocalContextStore struct { // Base is the directory (uploads PVC mount) submission contexts are written // under. Each submission gets its own {Base}/{id}/ subdirectory.