Loading docs/troubleshooting.md +6 −5 Changes for docs/troubleshooting.md: 6 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -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) — Loading internal/config/config.go +6 −8 Changes for internal/config/config.go: 6 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -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"` Loading internal/submit/blobstore.go +5 −8 Changes for internal/submit/blobstore.go: 5 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -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. Loading Loading
docs/troubleshooting.md +6 −5 Changes for docs/troubleshooting.md: 6 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -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) — Loading
internal/config/config.go +6 −8 Changes for internal/config/config.go: 6 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -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"` Loading
internal/submit/blobstore.go +5 −8 Changes for internal/submit/blobstore.go: 5 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -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. Loading