How to use Kubernetes ExternalName Service type to migrate your applications to different namespaces with zero downtime.

Evgeny Borzenin · January 28, 2021

At my current project, we have started restructuring our cluster’s namespaces model. We are moving from one namespace to namespace per team/domain model. One of the challenges that we immediately encountered was that when you move application to a different namespace, you need to change service URLs of all dependent applications and include namespace. Here is an abstracted example:

There are 3 applications AppA, AppB and AppC. All deployed with corresponding Kubernetes services called ServiceA, ServiceB and ServiceC. All 3 applications are deployed to the same namespace called foobar. AppA has inbound dependency from AppC and outbound dependency to AppB.


Since everything is deployed to the same namespace, we use the following URLs to call our services:

  • http://servicea/
  • http://serviceb/
  • http://servicec/

Now, we want to move AppA to the new foo namespace.


Since applications are now deployed to different namespaces, we need to change and use the following URLs to call services:

  • http://serviceb.foobar.svc.cluster.local/
  • http://servicec.foobar.svc.cluster.local/

Not only that requires changes at all 3 applications, but also may cause a possible down time at AppC during the migration period. In real life, with hundreds of applications migrating to several namespaces, that can cause even longer down time and depending on the dependency graph, can require a lot of deployment orchestration during transition period. Not to mention that it might be that some of the applications can’t be re-configured and re-deployed at the moment. All these factors forced us to think how we can do such a migration with close to zero down time.

Proxy with ExternalName Service type

The solution that we came up with was to introduce a proxy-service at the old namespace with the same name as service being migrated, pointing to the service in the new namespace.


The proxy-service ServiceA is deployed to the foobar namespace and routes traffic to the “real” ServiceA at the foo namespace. Because proxy-service deployed to the same namespace, AppC can still call it by using http://servicea/.

Kubernetes documentation describes services of type ExternalName as Service that maps a Service to a DNS name, not to a typical selector. Here is a proxy-service definition for servicea at foobar namespace:

apiVersion: v1
kind: Service
  name: servicea
  namespace: foobar
  type: ExternalName

Migration plan

With proxy-service in place, here is our migration strategy:

  • Re-configure AppA with correct URLs for all outbound dependencies
  • Deploy AppA into foo namespace


  • Replace servicea in foobar namespace with proxy-service


  • Delete AppA pods (and other related Kubernetes resources) from foobar namespace


  • Deploy new version of AppC with URL pointing to servica at foo namespace


  • When all applications calling AppA at foobar namespace are re-configured and re-deployed, delete servicea from foobar namespace


With that - thanks for reading :)



Visit the Github Issue to comment on this page. The comments will not be displayed directly on that page.