Accelerating local verification on a Kubernetes cluster
July 2, 2026 · View on GitHub
Purpose
This page describes the fast local-iteration loop for working on Radius control-plane images — build, push, and redeploy a single component against a running Kubernetes cluster instead of re-running the full functional suite. It is for contributors iterating on a resource provider (for example the applications RP) who want to validate a change on a real cluster quickly. For the full set of test tiers and when to run each, start at the test matrix overview; for the end-to-end suite, see running functional tests.
This loop applies when you only need to update a control-plane image. If you change the deployment or environment, re-run rad init (or the install steps below) instead.
Prerequisites
-
A Kubernetes cluster and a working local dev environment.
-
A container registry your cluster can pull from (for example Azure Container Registry or
ghcr.io). -
The
DOCKER_REGISTRYenvironment variable set to that registry:export DOCKER_REGISTRY=ghcr.io/your-registry -
A login to the registry with anonymous pull enabled. The login must be refreshed periodically (about every 3 hours) because it logs out frequently:
az acr login -n <registry> az acr update --name <registry> --anonymous-pull-enabled
Steps
1. Build and push the initial images
Build and push every Radius image (applications-rp, ucpd, and the others required to run Radius):
make docker-build && make docker-push
2. Install Radius on the cluster
go run ./cmd/rad/main.go install kubernetes --chart deploy/Chart --set global.imageRegistry=ghcr.io/your-registry --set global.imageTag=latest
go run ./cmd/rad/main.go workspace create kubernetes
go run ./cmd/rad/main.go group create radius-rg
go run ./cmd/rad/main.go switch radius-rg
go run ./cmd/rad/main.go env create radius-rg --kubernetes-namespace default
go run ./cmd/rad/main.go env switch radius-rg
If your registry requires authentication, create a Kubernetes secret and pass it with imagePullSecrets:
kubectl create secret docker-registry regcred \
--docker-server=ghcr.io/your-registry \
--docker-username=<username> \
--docker-password=<password> \
-n radius-system
go run ./cmd/rad/main.go install kubernetes --chart deploy/Chart \
--set global.imageRegistry=ghcr.io/your-registry \
--set global.imageTag=latest \
--set 'global.imagePullSecrets[0].name=regcred'
3. (Optional) Configure Azure resources
The steps above do not let Radius talk to Azure resources. To enable that, run steps 1–2 and then create a service principal:
az ad sp create-for-rbac --role Owner --scope /subscriptions/<subscriptionId>/resourceGroups/<resourcegroupname>
The command prints appId, displayName, password, and tenant. Use those values to register the credential:
go run ./cmd/rad/main.go env update radius-rg --azure-subscription-id <subscriptionId> --azure-resource-group <resourcegroupName>
go run ./cmd/rad/main.go credential register azure sp --client-id <appId> --client-secret <pwd> --tenant-id <tenantId>
4. Deploy and iterate
Deploy a Bicep file to the cluster:
go run ./cmd/rad/main.go deploy <bicep>
Redeploy a single resource provider
Once Radius is installed, iterate on a single component — for example the applications resource provider — without reinstalling:
make docker-build-applications-rp && make docker-push-applications-rp && kubectl delete pod -l control-plane=applications-rp
This builds and pushes the applications-rp image and deletes its running pod. Because the deployment uses the latest tag, Kubernetes re-pulls the image on restart, so the pod comes back with your newly pushed build.
Redeploy the environment
Re-deploying an environment is a bit clunky today. Tear it down and deploy Radius again:
go run ./cmd/rad/main.go env delete <envname>
go run ./cmd/rad/main.go uninstall kubernetes
go run ./cmd/rad/main.go workspace delete
Alternatively, delete and recreate the Kubernetes cluster.
Verification
- After
kubectl delete pod -l control-plane=applications-rp, the pod restarts and reportsRunningwith the freshly pushed image (kubectl get pods -n radius-system). go run ./cmd/rad/main.go deploy <bicep>completes and deploys your file to the cluster.
Troubleshooting
- Push or pull is rejected after a while. The registry login expires roughly every 3 hours; re-run
az acr login -n <registry>. - The cluster cannot pull your images. Confirm anonymous pull is enabled (
az acr update --name <registry> --anonymous-pull-enabled) or that theregcredimagePullSecretssecret is set. - The pod restarts with the old image. Make sure the image tag is
latestso Kubernetes re-pulls on restart, and that the push succeeded before you deleted the pod.
💡 Tip: switch your default namespace to
radius-systemwithkubectl config set-context --current --namespace=radius-system.