• Stars
    star
    168
  • Rank 225,507 (Top 5 %)
  • Language
    Shell
  • License
    Apache License 2.0
  • Created over 9 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Dynamic haproxy configuration using consul

haproxy-consul

Dynamic haproxy configuration using consul packed into a Docker container that weighs 18MB.

Table of Contents

Overview

This project combines Alpine Linux, consul template, and haproxy to create a proxy that forwards traffic to apps registered in Marathon and forwarded with marathon-consul.

How it works

First, you must set up a wildcard dns (using something like CloudFlare or xip.io). This means that if your domain is example.com, any request to a <name>.example.com will resolve to the IP of your haproxy container.

Inside the haproxy container, a header match is used to map <application>.example.com to the service registered in consul under application.

Building

docker build -t haproxy .

Running

Modes

haproxy-consul can run in two different modes: forwarding either consul services (the default) or Marathon apps. This behavior is controlled by the HAPROXY_MODE variable, which should be set to consul or marathon.

Reload configuration

It's possible to reload the HA proxy configuration without restarting the container itself. docker exec -it <container_id> bash reload.sh

consul Configuration

When HAPROXY_MODE is set to consul, haproxy-consul uses consul service names to set subdomains. No other configuration is required.

Marathon Configuration

When HAPROXY_MODE is set to marathon, haproxy-consul assumes that there will be app information in the marathon prefix of the Consul KV store. It was written to work with the information provided by marathon-consul.

By default, haproxy will forward all Marathon-assigned ports. So if you specify that your application should own port 10000 in the "ports" member of the app JSON, haproxy will open port 10000 to direct traffic to your app. This works with auto-assigned ports (ports set to 0), as well. This is all automatic, you don't need to think about it other than to pull the ports from Marathon.

However, if you want HTTP load balancing using the host header, you need a specify the following labels on your app:

{
    "id": "hello-rails",
    "cmd": "cd hello && bundle install && bundle exec unicorn -p $PORT",
    "mem": 100,
    "cpus": 1.0,
    "instances": 1,
    "uris": [
        "http://downloads.mesosphere.com/tutorials/RailsHello.tgz"
    ],
    "env": {
        "RAILS_ENV": "production"
    },
    "ports": [10000],
    "labels": {
        "HAPROXY_HTTP": "true",
        "HTTP_PORT_IDX_0_NAME": "hello_rails",
    }
}

In this example (available at examples/rails.json), the hello-rails application is assigned port 10000. This is different from the service or host port of the app; it is a global value that Marathon tracks. This means that haproxy-consul will forward all TCP traffic to port 10000 to the app workers.

When HAPROXY_HTTP is set to true and HTTP_PORT_IDX_0_NAME is set to a DNS-valid name Haproxy will forward all HTTP traffic with the host header (the name specified plus HAPROXY_DOMAIN) to the app workers. This extends to as many ports as you'd care to give it in the form HTTP_PORT_IDX_{port_number}_NAME.

This particular app results in something like the following haproxy configuration:

global
    maxconn 256
    debug

defaults
    mode tcp
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

# HTTP services
frontend www
    mode http
    bind *:80

    # files ACLs
    acl host_hello_rails hdr(host) -i hello_rails.haproxy.service.consul
    use_backend hello_rails_backend if host_hello_rails

# files backends
backend hello_rails_backend
    mode http
    server 1.2.3.4:49165 # TASK_RUNNING

# TCP services
listen hello-rails_10000
    mode tcp
    bind *:10000
    server task_id 1.2.3.4:41965 # TASK_RUNNING

Usage

If you don't want to configure wildcard dns, you can use xip.io. In this example, we are going to assume that the IP of your server is 180.19.20.21, then all domains in 180.19.20.21.xip.io will forward to your host.

Start the container as follows:

docker run --net=host --name=haproxy -d -e HAPROXY_DOMAIN=180.19.20.21.xip.io asteris/haproxy-consul

If you have wildcard DNS set up for your company (say at *.mycompany.com) use the following:

docker run --net=host --name=haproxy -d -e HAPROXY_DOMAIN=mycompany.com asteris/haproxy-consul

Now that it is set up, connect to an app:

curl -L http://myapp.mycompany.com

Or if you do not have a wildcard DNS:

curl -L http://myapp.180.19.20.21.xip.io

Options

If you want to override the config and template files, mount a volume and set the CONSUL_CONFIG environment variable before launch. In docker this can be accomplished with the -e option:

docker run -v /host/config:/my_config -e CONSUL_CONFIG=/my_config -net=host --name=haproxy -d -e HAPROXY_DOMAIN=mycompany.com asteris/haproxy-consul

If you need to have a root CA added so you can connect to Consul over SSL, mount a directory containing your root CA at /usr/local/share/ca-certificates/.

Configure using the following environment variables:

Variable Description Default
HAPROXY_DOMAIN The domain to match against haproxy.service.consul (for app.haproxy.service.consul).
HAPROXY_MODE forward consul service or Marathon apps consul (marathon also available, as described above)
HAPROXY_USESSL Enable the SSL frontend (see below) false
HAPROXY_STATS Enable Statistics UI on port 1936 (see below) false
HAPROXY_STATS_TITLE Change Statistics Title (see below) false
HAPROXY_STATS_URI Change Statistics URI (see below) false

consul-template variables:

Variable Description Default
CONSUL_TEMPLATE Location of consul-template bin /usr/local/bin/consul-template
CONSUL_CONNECT The consul connection consul.service.consul:8500
CONSUL_CONFIG File/directory for consul-template config /consul-template/config.d
CONSUL_LOGLEVEL Valid values are "debug", "info", "warn", and "err". debug
CONSUL_TOKEN The Consul API token

consul KV variables:

Variable Description Default
service/haproxy/maxconn maximum connections 256
service/haproxy/timeouts/connect connect timeout 5000ms
service/haproxy/timeouts/client client timeout 50000ms
service/haproxy/timeouts/server server timeout 50000ms

SSL Termination

If you wish to configure HAproxy to terminate incoming SSL connections, you must set the environment variable HAPROXY_USESSL=true, and mount your SSL certificate at /haproxy/ssl.crt - this file should contain both the SSL certificate and the private key to use (with no passphrase), in PEM format. You should also include any intermediate certificates in this bundle.

If you do not provide an SSL certificate at container runtime, a self-signed certificate will be generated for the value of *.HAPROXY_DOMAIN.

For example:

docker run -v /etc/ssl/wildcard.example.com.pem:/haproxy/ssl.crt -e HAPROXY_USESSL=true -e HAPROXY_DOMAIN=example.com --net=host --name=haproxy haproxy-consul

You can also force that all incoming connections are redirected to HTTPS, by setting HAPROXY_USESSL=force.

SSL termination is currently only available in 'consul' mode.

License

Released under an Apache 2.0 License. See LICENSE

More Repositories

1

distributive

Unit testing for the cloud
Go
147
star
2

marathon-consul

bridge Marathon information to Consul KV
Go
85
star
3

kubernetes-ansible

Install and configure Google Kubernetes on OpenStack
Ruby
82
star
4

nginx-consul

nginx configured with consul template
Shell
41
star
5

k8sclass

Class Materials for Kubernetes Training.
Python
21
star
6

exhibitor-mesos-framework

Exhibitor on Apache Mesos for reliably running Zookeeper on Mesos
Scala
20
star
7

mantl-api

Mantl API
Go
17
star
8

consulacl

Command line interface to Consul ACL endpoint
Go
17
star
9

mantl-devnet-learninglabs

Self paced interactive Learning Labs for learninglabs.cisco.com
HTML
15
star
10

mantl-universe

The Mantl Universe package repository - install Mesos frameworks on Mantl
11
star
11

consulkv

Command line interface to Consul K/V
10
star
12

docker-consul-template

Alpine Linux + consul-template Docker container. Use as a base for other containers
10
star
13

shipped-demo-cart

Cart microservice for shopping site.
Go
8
star
14

ContainerCF

Container.CF Open Source Home
Shell
6
star
15

vault-rpm

Spec file and sources needed to package vault
Shell
6
star
16

vaquero-docs

Documentation for the Vaquero project
CSS
6
star
17

syslog-service

Go based Syslog service that can run within an infrastructure role on Mesos.
Go
5
star
18

docker-logstash

Ruby
4
star
19

clus-my-hero-app

Shell
3
star
20

Shipped-Learning-Labs

A place for uploading, reviewing, and tracking development of Shipped Learning Labs
HTML
3
star
21

shipped-demo-web

Web site for shopping site demo that connect to all microservices.
HTML
3
star
22

consul-utils-rpm

Command line utilities for Consul
3
star
23

edge-test

Test implementation for containerization of the edge components and their validation results.
Java
3
star
24

shipped-devbox

Shipped developer Vagrant box
Shell
3
star
25

shipped-buildpack-template-spark

Shipped buildpack for Cisco Spark, details on developers API at https://developer.cisco.com/site/spark/
JavaScript
2
star
26

docker-utilities

2
star
27

phoenix

Apache Kafka to S3 backup and restore
2
star
28

vaquero-vagrant

Shell
2
star
29

shipped-walkthru

2
star
30

shipped-mongo-sample-client

Python
1
star
31

shipped-feedback

Feedback and issue tracking for the Cisco Shipped project.
1
star
32

marathon-cli

A golang cli to manage apps and groups in Marathon
Go
1
star
33

PCF-Metapod

Automating installation of Cloud Foundry on Metapod
Ruby
1
star
34

mantl-kibana

Shell
1
star
35

shipped-traefik-simulator

Simulate status code and response time delay for HTTP endpoint.
HTML
1
star
36

shipped-buildpack-template-golang

Go - Template Buildpack
Go
1
star
37

vaquero-examples

1
star
38

aie-burnit

Go
1
star