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://servicea.foo.svc.cluster.local/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
metadata:
name: servicea
namespace: foobar
spec:
type: ExternalName
externalName: servicea.foo.svc.cluster.local
Migration plan
With proxy-service in place, here is our migration strategy:
- Re-configure
AppAwith correct URLs for all outbound dependencies - Deploy
AppAintofoonamespace

- Replace
serviceainfoobarnamespace with proxy-service

- Delete
AppApods (and other related Kubernetes resources) fromfoobarnamespace

- Deploy new version of
AppCwith URL pointing toservicaatfoonamespace

- When all applications calling
AppAatfoobarnamespace are re-configured and re-deployed, deleteserviceafromfoobarnamespace

Useful links
With that - thanks for reading :)