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
AppC. All deployed with corresponding Kubernetes services called
All 3 applications are deployed to the same namespace called
AppA has inbound dependency from
AppC and outbound dependency to
Since everything is deployed to the same namespace, we use the following URLs to call our services:
Now, we want to move
AppA to the new
Since applications are now deployed to different namespaces, we need to change and use the following URLs to call services:
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.
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
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
apiVersion: v1 kind: Service metadata: name: servicea namespace: foobar spec: type: ExternalName externalName: servicea.foo.svc.cluster.local
With proxy-service in place, here is our migration strategy:
AppAwith correct URLs for all outbound dependencies
foobarnamespace with proxy-service
AppApods (and other related Kubernetes resources) from
- Deploy new version of
AppCwith URL pointing to
- When all applications calling
foobarnamespace are re-configured and re-deployed, delete
With that - thanks for reading :)