| Service Discovery is about helping services find one another. If your application relies on memcached, you need to pass the memcached location to your application somehow. For simple architectures, this may just be a hardcoded localhost:11211. As you scale, it becomes prudent to distribute services across different servers. Your configuration could then become something like "server1.mycompany.com:11211". But what if memcached moves from server1 to server2? You'll need to reconfigure and restart your application. More sophisticated apps will often use a dynamic approach: services are registered with something like ZooKeeper or etcd. When serviceA needs to talk to serviceB, serviceA looks up serviceB's address in the service registry (or a local cache) and makes the request. The good news is that these often include basic health check functionality, so you get a bit of fault tolerance for free. Unfortunately, this requires services to integrate directly with ZooKeeper or etcd, adding undesired complexity. Some architectures therefore choose to use DNS as their service registry. But instead of hardcoding a the DNS address of a single node (like "server1.mycompany.com"), they hit an address associated with the service (serviceB.mycompany.com). This usually means rolling your own system to keep DNS up to date (adding/pruning in context of health state). Consul is a hybrid approach. It allows you to use DNS as a service registry, but operates as its own, distributed DNS server cluster. Think of it like a specialized ZooKeeper cluster that exposes service information via DNS (and HTTP, if you prefer). Back to the memcached case. With Consul, you'd point your app at "memcached.consul:11211". If your memcached server fell over and was replaced, Consul would pick up the change and return the new address. And without any app config changes or restarts. |
From what I can tell, Consul supports two registration mechanisms: Static defined services in /etc/consul.d, and dynamically defined services through the HTTP API.
For the statically-defined case, for any given node, you have to create Puppet (or Chef, or whatever) definitions that populate /etc/consul.d with the stuff that's going to run on that node. For the actual configuration itself, you still want Puppet to be the one to populate it. The question then is what you gain by doing this; if that configuration goes into Puppet, then Puppet is still the main truth where you want to centralize things, so then you have this flow of data:
...compared to the "old" way: In this case, Consul's benefit comes from the fact that it can know which services are alive and not, so that when myapp needs otherapp, it doesn't need a load-balancer to figure that out.The documentation makes a point about Puppet updates being slow and unsynchronized, and it's true that you get into situations where, for example, service A is configured with hosts that aren't up yet, for example. With Consul you can update the config "live"; surely you want to centralize config in Puppet and populate Consul's K/V from Puppet, and then you get the single-point-of-update synchronization missing from Puppet, but you still need to store the truth in Puppet.
So I'm counting two good, but not altogether mind-blowing benefits from using Consul with Puppet, over not using Consul at all. The overlap is looking a lot like two systems vaguely competing for dominance.
I suspect the better use of Consul is in conjunction with something like Docker, where you ditch Puppet altogether (except as a way to update the host OS), and instead build images of apps and services that don't contain any configuration at all, but simply point themselves at Consul. That means that when you bring up a new Docker container, it can start its Consul agent, register its services, and suddenly its contained services are dynamically available to the whole cluster.
The container itself contains no config, no context, just general-purpose application/service code; and Consul doesn't need to be populated through Puppet because in that way, Consul is (in conjunction with some container provisioning system) the application world's Puppet.
That, to me, sounds pretty nice.