Previously on “As the QubitRenegade turns…”
-
Consul an OpenSource(ish, there’s an enterprise version that has some awesome features) Distributed, Highly Available, Service Discovery, Health Checking, KV Store, that provides federated Multi Datacenter support. (disclaimer: I am in absolutely no way, shape, or form associated with HashiCorp. All opinions are my own and not influenced by schwag. I just happen to think they make a pretty swell product… even if it is written in go ;) )
-
Habitat an OpenSource, Artifact Builder, Artifact and Service Manager, Docker/Kubernetes/Serverless Enabler, sane Docker container builder system, with Distributed Service Discovery and “build once run anywhere (no really)” mentality.
-
Docker is how most people do containers. Just… I’ll post the opinion piece soon. Docker is fine.
Prerequisites
High level Overview
In the last installment, we exported a Core habitat package to a Docker container, then started several instances to build a cluster leveraging Habitat’s service discovery. To follow along you don’t necessarily need all five servers, a single node running in dev mode would be sufficient. We’ll proceed as though you have a full cluster to work with.
Today we’ll explore running Consul in “client” mode.
Justification
Initially, I wanted to have the ability to run core/consul
in either “Client” or “Server” mode. The primary difference is that Consul “Servers” participate in gossip and present a Web UI. Technically the client could present a Web UI. When running other services (Vault, Nomad, etc. which we’ll touch on in a later post), HashiCorp recommends running Consul in client mode locally and not allowing the tools to communicate directly with the consul server.
When discussing Consul, we speak about “Server” and “Client” mode; even though it’s the same binary run with different CLI parameters, “client” and “server” makes a natural demarcation which lends itself to the segregation of packages.
Security
It’s worth noting that Habitat and Consul both have methods of encrypting communication. For the time being this guide is putting that aside, with a note that we will cover it eventually.
Building Consul Client
The Habitat plan source can be found on github
If you want to just run it, skip to Exporting Consul Client below.
Service Config Files
To enable what is essentially “arbitrary” configuration files, we can use the toJson
helper method to turn the default.toml
/user.toml
config into JSON structures. As Handlebars is fairly limited, there is no “else if” clause, we generate correct JSON and allow Consul to complain about the configuration file.
This will allow a minimal configuration such as:
[service]
name = "foo"
[service.checks]
interval = "1s"
Which will generate the JSON:
{
"service": {
"name": "foo",
"checks": [
{
"interval": "1s"
}
]
}
}
(just not pretty formatted)
Exporting Consul Client
The Consul Client package is really designed as a building block for other packages that need to leverage a Consul Client. For demonstrative purposes, we’re just going to run Consul by itself.
Enter Studio
If you’re not in a Linux environment, you’ll need to enter the habitat studio:
$ hab studio enter
Export qubitrenegade/consul-client
Run the hab pkg
command to export qubitrenegade/consul-client
to a docker container.
$ hab pkg export docker qubitrenegade/consul-client
This will create a directory $(pwd)/results
and a file $(pwd)/results/last_docker_export.env
which exports a number of environment variables if sourced. This enables such idioms as docker run -it $name
.
We will specify the origin and package name in examples below.
Run your docker containers:
You will either need to open multiple terminal windows, or replace the -e
with -de
This also assumes you have no more than one (1) running container before starting this process. If you have more than one (1) running container, adjust your IPs accordingly.
Create a service config file and save it as services.json
:
{
"client": {
"enable_script_checks": true
},
"service": {
"name": "simple-service",
"checks": [
{
"name": "is_alive",
"args": ["/bin/bash", ":(){ echo "I'm alive!"; return 200; }; :"],
"interval": "1s"
}
]
}
}
Then start your docker container while importing your settings (adjust peer IPs as necessary):
docker run -e "HAB_CONSUL_CLIENT=$(< services.json)" qubitrenegade/consul-client --peer 172.17.0.4 --bind consul-server:consul.default
Now when visit http://localhost:8500 You should see your service registered!
Examples
A number of service examples are provided in the example directory.
To use any of the examples, you can import the config values as environment variables:
docker run -e "HAB_CONSUL_CLIENT=$(curl https://raw.githubusercontent.com/qubitrenegade/habitat-consul-client/master/example/service-with-no-checks.json)" qubitrenegade/consul-client --peer 172.17.0.4 --bind consul-server:consul.default