QubitProducts / bamboo

HAProxy auto configuration and auto service discovery for Mesos Marathon
Apache License 2.0
794 stars 214 forks source link

Additional marathon data for template generation #126

Closed dkesler closed 8 years ago

dkesler commented 9 years ago

Just offering this up because we've found this data useful for generating our haproxy config files and thought it might be useful to others. This adds three pieces of data available in the templates:

Task.Alive: This lets the template avoid putting a service into rotation until it passes marathon's health checks. While we have haproxy also performing health checks, we were still getting errors on application deployment because haproxy assumes servers are health by default and won't pull them out of rotation until they fail health checks

App.Labels: Marathon's labels for the app

App.SplitId: App.Id or EscapedId are the entire application name including application groups. We're doing some stuff based on the application groups in our haproxy template, so we wanted to be able to access the parts of the path rather than the entire app id. (I.e. if you had an app in marathon called '/foo/bar', App.Id would be '/foo/bar' while App.SplitId would be ['foo', 'bar'])

j1n6 commented 9 years ago

Do you mind partially sharing some examples of how new template data is used? I would like to add it to the documentation, if people do need it there are examples they could follow.

dkesler commented 9 years ago

Sample haproxy config template that uses all three features. (This is a stripped down and modified version of what we're doing which is more complex).

This is done assuming that applications exist in an application group in marathon: e.g. /application-group/application-name. It does subdomain based discovery of the form application-name.<base domain> where the base domain may differ from application to application and thus is captured by a label. (Theoretically it could be stored in environment variables, but it seems better to use marathon's provided metadata rather than pollute the environment variables of the container). Lastly, we need the split id since we only want application-name for discovery purposes rather than application-group

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
        max-spread-checks 2000

        # Default SSL material locations                                                                                                                                                                                                                                                  
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        option  redispatch
        timeout connect 5000
        timeout client  50000
        timeout server  50000

        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

frontend http-in
        bind *:80
        {{ range $app := .Apps }}
        acl {{ $app.EscapedId }}-aclrule-host hdr(host) -i {{ index $app.SplitId 2 }}.{{ $app.Labels.SERVICE_DOMAIN }}
        use_backend {{ $app.EscapedId }}-cluster if {{ $app.EscapedId }}-aclrule-host
        {{ end }}

        stats enable
        # CHANGE: Your stats credentials                                                                                                                                                                                                                                                  
        stats auth admin:admin
        stats uri /haproxy_stats

{{ range $app := .Apps }}
backend {{ $app.EscapedId }}-cluster {{ if $app.HealthCheckPath }}
        option httpchk GET {{ $app.HealthCheckPath }}
        http-check expect rstring .*
        {{ end }}
        balance roundrobin
        option httpclose
        option forwardfor
        {{ range $task := $app.Tasks }}
        {{ if $task.Alive }}
        server {{ $app.EscapedId}}-{{ $task.Host }}-{{ $task.Port }} {{ $task.Host }}:{{ $task.Port }} {{ if $app.HealthCheckPath }} check inter 2000 {{ end }}
        {{ end }}
        {{ end }}
{{ end }}
SEJeff commented 8 years ago

@dkesler Can you rebase this to merge with the latest? I'd be interested in checking this out and it seems like a useful feature.

timoreimann commented 8 years ago

I wonder why this never got merged. We'd like to see the Alive variable become available too.

There's the somewhat related PR #138 where at least label integration took place already. Not so sure about the alive flag though: I couldn't easily tell by looking at the code. Maybe someone can shed some light.

In case part of this PR's functionality is still missing in Bamboo, I'd love to see the branch getting rebased onto the latest master and receive short-term approval by the project maintainers. @dkesler / @activars, what are your thoughts on this?

Thanks!

rhoml commented 8 years ago

This is a great feature I'd like to see it get merged.

lclarkmichalek commented 8 years ago

Gonna need a rebase. I personally don't see the value in the Alive flag, but if someone rebases this/submits a PR, I'll happily merge. I'll even more happily merge if it has tests ;)

j1n6 commented 8 years ago

There's a bit of value in this change. Then healthcheck information can be centrally managed by Marathon. Marathon provides a little complex checks than HAProxy or Nginx or any alternatives.

Depends how you want to deploy the proxies, some basic routing check is necessary.

KidkArolis commented 8 years ago

Cleaning up PRs. Feel free to reopen if still relevant.

rhoml commented 8 years ago

This is much needed specially when you version service deployments

j1n6 commented 8 years ago

Could you rebase the PR?

j1n6 commented 8 years ago

@dkesler can you rebase? I will test and merge the PR.

dkesler commented 8 years ago

I had issues getting the existing to cleanly rebase, so I ended up just creating a separate PR on a different branch:

https://github.com/QubitProducts/bamboo/pull/216