Search code examples
dockerdevopsdocker-swarm

Best way to handle Canary deployments with Docker Swarm


One best-practice for microservice deployments is "Canary Deployments" (to deploy a new version of an app alongside an existing one and to get your API gateway/proxy to send a small amount of traffic to the new version until you are happy it is stable, at which point you eventually increase it to 100% and delete the old service version.)

In order to do this in Docker Swarm, it seems to me that I would need to use the version number in the name of the service to allow this side-by-side deployment e.g. myapp_1_0_0 and myapp_1_0_1

The only problem with this seems to be that this will affect dns lookups both between services and also between proxy/gateway and service, which would mean that there might be a lot of complexity/api calls etc. to ensure settings are updated correctly to avoid downtime. It would be nicer to have a single dns name like myapp so that everything always looks for myapp and a proxy routes accordingly.

Is the only way around this to do a lot of work in the proxy and then get all the services to use the proxy for dns lookups and then stick with the versioned names? I looked at Envoy so would it make most sense to use something like that in front of the Swarm? Is there a document that anyone knows about that describes this setup?


Solution

  • As there is no native way to achieve canary in docker-swarm, I tried a custom approach with envoy and Envoy-Pilot.

    Here is the step by steps to flow: https://github.com/dineshba/docker-swarm-canary

    This approach will introduce:

    • 1 envoy proxy container per application (as envoy is lightweight, should not be much overhead)
    • Very small latency as all network will go via envoy proxy (delay(approx): 0.004 seconds (4ms))

    Hope this gives you idea of how canary can be achieved in docker-swarm