We moved a long‑standing authentication deployment out of the default namespace and kept it reachable without any interruption by converting the original Service into a Kubernetes ExternalName that forwards to the new location. The change matters because any outage of that service would have blocked logins across an entire region, and the pattern shows how to relocate critical workloads safely while respecting existing DNS‑based and ingress traffic paths.
Why a Direct Relocation Is Not Viable
Numerous in‑cluster applications reference the service by its fully qualified DNS name auth-svc.default.svc.cluster.local. Those callers are owned by different teams with independent release cadences, so there is no moment when all of them can be updated simultaneously. The deployment pipeline only supports a single‑namespace target, and the platform’s policy engine blocks duplicate ingress definitions across namespaces. Attempting to delete the old Service first would create a gap for internal callers, while creating a new Service first would violate the ingress duplication rule. The constraints force a solution that works within a single‑namespace deployment flow and avoids coordinated code changes.
Using an ExternalName Service as a Forwarding Address
The core insight is that the original Service does not need to point at pods after the workload is moved. By redefining it as an ExternalName Service, Kubernetes returns a CNAME‑style DNS response that resolves to the new Service’s name in its new namespace, for example:
apiVersion: v1 kind: Service metadata: name: auth-svc namespace: default spec: type: ExternalName externalName: auth-svc.authentication.svc.cluster.local
All existing internal traffic continues to query the same DNS name, but the resolution now points to the new deployment. No client code changes are required, and the behavior mirrors postal forwarding: the old address remains valid while the actual workload lives elsewhere.
Resolving the Ingress Conflict
External traffic reaches the service through an ingress resource, which cannot be duplicated across namespaces due to the OPA policy that forbids identical rules. The migration introduced a temporary policy exception by annotating the target namespace to bypass the duplicate‑ingress check. This allowed the new ingress to be created alongside the old one for a short overlap period. During that window, metrics confirmed that requests were being served by the new deployment. Once verification was complete, the legacy ingress was removed and the exception annotation was allowed to expire, restoring the policy’s original enforcement.
Related CloudNinjas coverage: hands-on guides.
What This Means For Practitioners
Practitioners should consider the following steps when relocating a critical service:
- Deploy the workload to its target namespace before altering any routing objects.
- Replace the original Service with an
ExternalNamethat points to the new Service’s DNS name. - Validate traffic flow through both internal DNS and external ingress paths before scaling down the old pods.
- If platform policies block duplicate ingress, use a scoped, time‑limited exception rather than disabling the rule globally.
- Keep the original pods scaled to zero for a rollback window, then clean up once confidence is established.
By treating the Service object as a mutable forwarding layer, teams can decouple the migration timeline from consumer release cycles, maintain zero‑downtime availability, and stay compliant with existing policy constraints.

