Skip to content

Add optional rootless BuildKit sidecar to dynamic-rp chart#11882

Draft
willdavsmith wants to merge 3 commits into
mainfrom
feat/containerimages-buildkit-sidecar
Draft

Add optional rootless BuildKit sidecar to dynamic-rp chart#11882
willdavsmith wants to merge 3 commits into
mainfrom
feat/containerimages-buildkit-sidecar

Conversation

@willdavsmith
Copy link
Copy Markdown
Contributor

@willdavsmith willdavsmith commented May 13, 2026

Summary

Adds an optional, rootless BuildKit sidecar to the dynamic-rp Pod, plus a small set of supporting fixes, so in-cluster Terraform recipes can build and push container images without a host Docker socket, a privileged Pod, or per-node host preparation.

The motivating consumer is the new Radius.Compute/containerImages resource type — see companion PR radius-project/resource-types-contrib#151.

What's in this PR

Helm chart (deploy/Chart)

  • buildkitd sidecar container (rootless, listens on Pod loopback TCP) added to the dynamic-rp Pod.
  • buildctl-init init container that copies the buildctl CLI into a shared emptyDir, mounted into the dynamic-rp container's PATH.
  • Registry-credentials volume that mounts an operator-supplied Secret at ~/.docker/config.json inside the dynamic-rp container.
  • New dynamicrp.buildkit.* values surface: enabled (default true), psaMode (restricted/baseline), image, credentialsSecret, and resources limits/requests.
  • RBAC: batch/jobs access (recipe-spawned Jobs).
  • NOTES.txt warnings for misconfigured PSA mode and missing credentials.
  • helm-unittest cases: buildkit sidecar shape (default-on / disabled) and a drift-guard against the pkg/recipes/terraform/install.go path constants.

Pre-mount path fix (latent bug)

The chart's existing Terraform pre-mount init script was writing the binary to a directory the runtime never reads from. Fixed alongside the chart rework.

Observability

pkg/recipes/terraform/install.go::ensureGlobalTerraformBinary now logs an INFO line when no pre-mounted binary is present, naming the expected paths. Helps operators diagnose chart misconfiguration.

Documentation

  • New design doc: eng/design-notes/recipes/2026-04-container-images-resource-type.md.
  • New contributor doc: docs/contributing/contributing-code/contributing-code-writing/buildkit-recipes.md covering the buildkit subsystem and the local-exec recipe pattern.

Coordination

Companion PR: radius-project/resource-types-contrib#151 (resource type + recipe). They should land together; this one is reviewable independently.

Design

Design review for this feature was completed prior to this PR.

Notable details

  • Default enabled: true. The buildkit sidecar runs by default on a fresh install. Operators who don't want it can --set dynamicrp.buildkit.enabled=false.
  • PSA modes. psaMode=restricted requires Kubernetes ≥ 1.30 with UserNamespacesSupport (uses hostUsers: false). Falls back to baseline for older clusters; the chart's NOTES.txt warns when the configured mode is incompatible.
  • credentialsSecret is unset by default. Without it, builds run but pushes fail with unauthorized. NOTES.txt warns.
  • Drift guard. deploy/Chart/tests/helpers_test.yaml asserts the chart still references the same Terraform pre-mount paths the runtime reads from. If you rename one, you'll be told to rename the other.

Testing

  • helm-unittest 74/74 pass (including 3 new tests).
  • go test ./pkg/recipes/terraform/... passes.
  • End-to-end multi-arch build + push validated in a separate demo repository.

Follow-ups

Tracking separately so this PR stays focused:

Adds an optional, rootless BuildKit sidecar to the dynamic-rp Pod that
in-cluster Terraform recipes can drive via the buildctl CLI to build
and push container images. Motivating consumer is the new
Radius.Compute/containerImages resource type in resource-types-contrib.

Chart additions (deploy/Chart):
- buildkitd sidecar container (rootless, no privileged Pod, no host
  Docker socket) with default-on enabled flag, configurable image,
  PSA mode (restricted/baseline), credentialsSecret, and resource
  limits/requests
- buildctl-init init container that mounts the buildctl CLI into the
  dynamic-rp container's PATH
- registry-credentials volume mounting an operator-supplied Secret at
  ~/.docker/config.json
- RBAC: batch/jobs access for recipe-spawned Jobs
- NOTES.txt warnings for misconfigured PSA mode and missing creds
- helm-unittest cases covering buildkit sidecar shape (default-on /
  disabled) and a drift-guard against the install.go path contract

Other changes:
- pkg/recipes/terraform/install.go: log INFO when no pre-mounted
  Terraform binary is present, naming the expected paths
- Fixes a path-mismatch bug in the chart's Terraform pre-mount init
  script (was writing to a directory the runtime never reads from)
- New contributor doc covering the buildkit subsystem and the
  local-exec recipe pattern
- Design doc copied to eng/design-notes/recipes/

Coordinates with resource-types-contrib PR for the resource type and
recipe.
Copilot AI review requested due to automatic review settings May 13, 2026 22:38
@willdavsmith willdavsmith requested review from a team as code owners May 13, 2026 22:38
@github-actions
Copy link
Copy Markdown

This PR requires exactly 1 of the following labels: pr:standard, pr:important.
Currently applied labels: .

Label descriptions:

  • pr:important - Major features, breaking changes, deprecations, or other high-impact changes that need special attention during release.
  • pr:standard - Ongoing maintenance, minor improvements, documentation updates, and routine development work.

@willdavsmith, please add the appropriate label to this PR before merging.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 13, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the deploy/Chart dynamic-rp deployment to optionally run a rootless BuildKit sidecar (default on) and adds supporting documentation/tests, enabling in-cluster image build/push scenarios without relying on a host Docker socket.

Changes:

  • Add dynamicrp.buildkit.* values and wire a buildkitd sidecar + buildctl-init init container into the dynamic-rp Deployment.
  • Fix Terraform pre-mount pathing in the chart and add a drift-guard helm-unittest to keep chart/runtime paths aligned.
  • Add operator-facing NOTES warnings plus new design/contributor docs for the subsystem.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/recipes/terraform/install.go Logs an INFO message when no pre-mounted Terraform binary is present (to aid diagnosis).
eng/design-notes/recipes/2026-04-container-images-resource-type.md Adds a design note for the containerImages resource type and how BuildKit is used.
docs/contributing/contributing-code/contributing-code-writing/buildkit-recipes.md Documents the chart’s BuildKit sidecar and the recipe authoring pattern it enables.
deploy/Chart/values.yaml Introduces the dynamicrp.buildkit values surface (enabled/psaMode/image/credentials/resources).
deploy/Chart/tests/helpers_test.yaml Adds helm-unittest coverage for BuildKit enable/disable and Terraform-path drift guard.
deploy/Chart/templates/NOTES.txt Adds install-time warnings for incompatible PSA mode / missing registry credentials.
deploy/Chart/templates/dynamic-rp/rbac.yaml Grants dynamic-rp RBAC permissions for batch Jobs.
deploy/Chart/templates/dynamic-rp/deployment.yaml Implements the terraform pre-mount fix and adds BuildKit containers/env/volumes.

@@ -185,6 +258,62 @@ spec:
{{- if .Values.dynamicrp.resources }}
resources:{{ toYaml .Values.rp.resources | nindent 10 }}
┌─────────────────────────────────────────────────────────────┐
│ dynamic-rp Pod │
│ │
│ buildkit-init ──► copies rootlesskit/buildkit data dir │
Comment on lines +304 to +310
* **Provider**: `kreuzwerker/docker` ≥ 3.0. The provider speaks
BuildKit gRPC natively; it does not need a Docker CLI on the
recipe runner.
* **Endpoint**: configured via the `DOCKER_HOST` environment
variable, which dynamic-rp sets to
`unix:///run/buildkit/buildkit.sock` for recipe execution. The
recipe itself does not encode the endpoint.
runAsNonRoot: true
runAsUser: 65532
{{- end }}
{{- end }}
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 13, 2026

Unit Tests

    2 files  ± 0    422 suites  ±0   6m 49s ⏱️ -32s
5 127 tests +12  5 125 ✅ +12  2 💤 ±0  0 ❌ ±0 
6 156 runs  +12  6 154 ✅ +12  2 💤 ±0  0 ❌ ±0 

Results for commit 9d6ddfa. ± Comparison against base commit 024faba.

♻️ This comment has been updated with latest results.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 51.72%. Comparing base (024faba) to head (9d6ddfa).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #11882      +/-   ##
==========================================
+ Coverage   51.69%   51.72%   +0.03%     
==========================================
  Files         725      726       +1     
  Lines       45595    45611      +16     
==========================================
+ Hits        23570    23594      +24     
+ Misses      19799    19793       -6     
+ Partials     2226     2224       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The containerImages recipe now reads registry credentials from a
per-resource Radius.Security/secrets resource via the kubernetes_secret_v1
data source, matching the mysql pattern. The chart no longer needs to
mount a Docker config.json — drop dynamicrp.buildkit.credentialsSecret
value, volume, and volumeMount. Update fsGroup comment to reflect the
buildctl binary mount (TCP, no socket sharing). Rewrite NOTES.txt to
point platform engineers at the recipe-registration flow. Add a helm
unittest covering the buildctl-init init container when terraform is
disabled. Spelling list additions for new tech terms.
The previous default of `restricted` requires Kubernetes 1.30+ with
the UserNamespacesSupport feature gate, which is not available out of
the box on kind, k3d, Docker Desktop, or older managed clusters. This
forced almost every operator trying out the BuildKit sidecar to
immediately discover the failure mode and reinstall with
--set dynamicrp.buildkit.psaMode=baseline.

Flip the default so `rad install kubernetes` is a one-liner on every
supported Kubernetes version. Operators who enforce PSA restricted
cluster-wide and run a recent enough kernel can opt into the stricter
sidecar profile with --set dynamicrp.buildkit.psaMode=restricted; the
existing NOTES.txt preflight surfaces a clear remediation if it's
selected on an incompatible cluster.

Also update the NOTES.txt registry-credentials hint to reflect the
PE-owned dockerconfigjson Secret model rather than the developer-owned
Radius.Security/secrets language.
@radius-functional-tests
Copy link
Copy Markdown

radius-functional-tests Bot commented May 15, 2026

Radius functional test overview

🔍 Go to test action run

Click here to see the test run details
Name Value
Repository radius-project/radius
Commit ref 9d6ddfa
Unique ID func976f012841
Image tag pr-func976f012841
  • gotestsum 1.13.0
  • KinD: v0.29.0
  • Dapr: 1.14.4
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.3.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-func976f012841
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-func976f012841
  • dynamic-rp test image location: ghcr.io/radius-project/dev/dynamic-rp:pr-func976f012841
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func976f012841
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func976f012841
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting corerp-cloud functional tests...
⌛ Starting ucp-cloud functional tests...
✅ ucp-cloud functional tests succeeded
✅ corerp-cloud functional tests succeeded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants