Should a swarm have more than one stack?

I know that Docker swarm can support more than one stack. However, I am just wondering … is it a good idea to take advantage of that feature?

The way I am doing it right now is I have individual microservice stacks that I independently deploy which seems to work, but something feels off in that the order of the stacks need to be maintained rather than a single docker stack deploy.

Multiple swarms may have dependencies I can see that happening, for example if I wanted a centralized logging for all the services it should go somewhere first. Same with the private Docker registries that would contain the images. In my case I have a “devops swarm” to handle such things. In AWS I just set it up using VPC peering connections to specific ports to accept logging events (e.g. beats, gelf and zipkin).

Hope @bretfisher can chime in on this topic :slight_smile:

Always have seperate stacks. If you need networks to connect them, have the lower level stack (like a proxy stack) hardcode the network name and create it first, then higher level stacks and reference it by name with external: true. is a good example.

1 Like

How do you handle the “stack deployment ordering”. I was thinking that would add “manual” work which I would like to avoid. Especially if I want to replicate the environment later.

I’m not trying to dismiss your suggestion, I’m just trying to see if switching to a single stack approach where the stack is managed in source control and also handled by continuous deployment tooling would have an easier time to set that up.

There is one good reason I can think of to retain multiple stacks though and that’s development. If we had a single stack then that means the developers need the whole stack. However, that may prove to be too much for a development machine,.

Maybe my stacks are just too fine-grained (where each microservice was its own stack). Perhaps I should think if refactoring the stacks to be courser.

Looking into it, I think the stacks comprising of the application should be a comprised of two stacks

  1. application microservices and dependent technologies (i.e. if it needs a DB or Redis that it can rebuild from scratch let it be managed there)

  2. infarstructure services e.g.

    • elastic search
    • kafka
    • RDS
    • NFS/EFS??
    • logstash (forwarder)
    • zipkin (forwarder)
    • traefik

The separation of the two allows the smaller scale services to be deployable on a local machine for development, but the larger ones can be mocked out.

I was thinking of a third stack, but opted not to bother because of the notion of a second swarm that would handle the devops related stuff which logstash and zipkin will forward to a real logstash and zipkin in another swarm for processing.

I think your approach, that of having each microservice as a separate stack, is the correct one. One characteristic of distributed applications is that order of startup should not matter. Application logic itself should handle temporary unavailability, via retries, circuit breakers, events, what have you.

One stack per swarm would be incredibly limiting. And I most definitely do not like the idea of using multiple swarms - that’s a bit extreme.

Lastly, could you elaborate a bit about the infrastructure services, and how they are used by individual microservices?

1 Like

Thanks for vetting my current infrastructure. It’s my first instinct and seemed to have worked. Then again I was the sole developer, we’re up to 3 developers still one ops guy (me) and one trainee.

One of the things I am thinking that may cause issues is that “name clashes” won’t appear until all of them are tied together and that may be in integration environments.

One of the other things that is causing me grief is traefik or any deployment label configured gateways (I built one that works with spring-cloud-gateway) as well because we have to make sure there’s no clashes.