magellan is a service for configuring load-balancers to redirect net traffic to given addresses or microservices
that run in the Armada cluster.
Right now it supports only HTTP redirects through HAProxy configuration. It is recommended to run it alongside
main-haproxy service(s) and let magellan configure them.
armada build magellan
armada run magellan
magellan is configured using Hermes.
It reads list of domain --> service/address mappings from all files domains-*.json. They should be in json format
and contain list of json objects like the one below:
{
"badguys.initech.com": {
"protocol": "http",
"service_name": "badguys-finder",
"environment": "production-office"
},
"www.badguys.initech.com": {
"protocol": "http",
"service_name": "badguys-finder",
"environment": "production-office"
},
"dashboard.initech.com": {
"protocol": "http",
"address": "server2.internal-initech.com:8080"
},
"jenkins.initech.com": {
"protocol": "http",
"address": "server3.internal-initech.com:9100",
"header_host": "jenkins.initech.com"
}
}
- Dictionary key - Name of the domain/URL that will be redirected.
- Dictionary value - Information about desired target microservice.
-
protocol- Protocol used by microservice. Currently onlyhttp/httpsis supported. -
service_name,environment,app_id- Name (required), environment (optional) and app_id (optional) of the target microservice.If environment/app_id is not supplied,
magellanwill look only for services with no environment/app_id set. -
address- Address to which the domain will be pointed to. If provided, it will override service_name/environment/app_id. -
header_host- Optional field, for overriding HTTP header "Host", that will be sent to the server. By default, it's the destination address, or the name of the created domain if the destination address is an IP.
-
Here, requests to two domains (badguys.initech.com and www.badguys.initech.com) will be redirected to the main endpoint
of service badguys-finder run with environment production-office.
The third domain - dashboard.initech.com - will be redirected to server2.internal-initech.com:8080, which shows
that we can easily create pretty aliases for non-armada services too.
It can also be used for exposing services available only from internal networks (e.g. internal-initech.com) to
the public - initech.com.
In case you have a set of similar services that differ by environment or app_id you can use wildcards to configure them, e.g.:
{
"translation.%GAME_NAME%.initech.com": {
"protocol":"http",
"app_id": "%GAME_NAME%",
"environment": "production-office",
"service_name": "translation-panel"
}
}
In the above example, when you run a service with armada run translation-panel --env production-office --app_id chess,
it will be available at the address translation.chess.initech.com.
You can use any variable name that match regular expression [A-Za-z_][A-Za-z_\-0-9]+,
just put it between the % characters.
It is also possible to redirect only certain path of the domain, so instead of translation.%GAME_NAME%.initech.com
you can also use something like translation.initech.com/%GAME_NAME%.
Wildcards do not work with address field.
By default magellan will configure all main-haproxy services in its Armada cluster that have the same
environment set.
If you want to change that behaviour you can choose other load balancers by placing file load-balancers.json in the Hermes
configuration directory. It should contain a json array with list of HAProxies to configure. E.g.:
[
{
"type": "main-haproxy",
"env": "production-aws"
},
{
"type": "haproxy",
"ssh": {
"host": "haproxy.initech.com",
"port": 22,
"user": "service",
"ssh_key": "service@haproxy.initech.com.key"
}
}
]
You can ask magellan to configure either main-haproxy Armada service or pure HAProxy instance. In the latter case
providing proper SSH credentials to the server with HAProxy is required.
With magellan you can also restrict access to some domains, allowing the only for defined netmasks.
To do that, add section "restrictions" in load-balancers.json config file. E.g.:
[
{
"type": "main-haproxy",
"env": "production",
"restrictions": [
{
"domain": ".secure.example.com",
"allowed_request_ip": [
"192.168.3.0/24",
"57.58.59.60"
]
},
{
"domain": [".lb.example.com", ".lb2.example.com"],
"allowed_x-forwarded-for": [
"192.168.3.0/24",
"57.58.59.60"
]
}
]
}
]It will restrict access to all hosts ending with ".secure.example.com", and allow access only for source IPs
(src ACL in HAProxy) in allowed_request_ip section: ["192.168.3.0/24", "57.58.59.60"].
When your domain, let's say ".lb.example.com", is behind another load-balancer, e.g. ELB, the source IP received by
HAProxy will be the load-balancer's IP, which may be useless. In that case, use allowed_x-forwarded-for section. It
will match the IPs against the last IP in X-Forwarded-For HTTP header (hdr_ip(X-Forwarded-For) ACL in HAProxy),
which should be the client's IP.
You can also expose some of the domains behind the restricted domain, by adding "allow_all": true to domain
definition. E.g.:
{
"allowed.secure.example.com": {
"protocol": "http",
"service_name": "allowed",
"environment": "production",
"allow_all": true
}
}magellan supports throttling of connections in case when there are too many connections coming from the same IP in
given period. If limit has been reached, main-haproxy, that was configured by magellan, will return HTTP code
429 Too Many Requests.
To enable throttling, add section "throttling" in load-balancers.json config file. E.g.:
[
{
"type": "main-haproxy",
"env": "production",
"throttling": {
"rate": "5s",
"threshold": 10000,
"whitelist_request_ip": [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
]
}
}
]It will throttle connections, when there were more than 10000 requests coming from the same IP, during last 5s, unless client came from whitelisted IP.
If your main-haproxy is behind other load-balancer, you should add whitelist_x-forwarded-for section instead,
similarly as in restrictions.
Additionally you can enable HAProxy html stats (see http://tecadmin.net/how-to-configure-haproxy-statics/). It will be
accessible as another endpoint in main-haproxy, registered in Armada catalog as main-haproxy:stats subservice.
To do that add section "stats" to load-balancer config, e.g.:
[
{
"type": "main-haproxy",
"env": "production-aws",
"stats": {
"enabled": true,
"user": "admin",
"password": "secret"
}
}
]
user and password fields are optional. The default are root / armada.
Magellan provides single HTTP endpoint at its root URL (/).
It returns JSON object with the list of all current mappings it is using to configure HAProxies.
magellan constantly monitors which services are running in the Armada cluster. It tries to reconfigure HAProxies as
soon as possible to reflect any changes in services state. When an instance of the service is stopped
or enters critical state, it is automatically removed from HAProxy configuration.
Some more explanations about using magellan can be found at one of Armada
guides.