Skip to content

Commit

Permalink
Implement server health check
Browse files Browse the repository at this point in the history
  • Loading branch information
diptadas committed Nov 8, 2017
1 parent 7b2461d commit 81a01a3
Show file tree
Hide file tree
Showing 9 changed files with 403 additions and 15 deletions.
5 changes: 5 additions & 0 deletions apis/voyager/v1beta1/annotations.go
Expand Up @@ -235,6 +235,11 @@ const (
// http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#7.3.3-src_conn_cur
// https://www.haproxy.com/blog/use-a-load-balancer-as-a-first-row-of-defense-against-ddos/
LimitConnection = IngressKey + "/limit-connection"

// https://github.com/appscode/voyager/issues/683
// https://www.haproxy.com/documentation/aloha/7-0/haproxy/healthchecks/
CheckHealth = EngressKey + "/" + "check"
CheckHealthPort = EngressKey + "/" + "check-port"
)

const (
Expand Down
4 changes: 2 additions & 2 deletions hack/docker/voyager/templates/default-backend.cfg
Expand Up @@ -23,13 +23,13 @@ backend {{ .DefaultBackend.Name }}
{{- range $e := .DefaultBackend.Endpoints }}
{{- if $e.ExternalName }}
{{- if $e.UseDNSResolver }}
server {{ $e.Name }} {{ $e.ExternalName }}:{{ $e.Port -}} {{ if $e.DNSResolver }} {{ if $e.CheckHealth }} check {{ end }} resolvers {{ $e.DNSResolver }} resolve-prefer ipv4 {{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}}
server {{ $e.Name }} {{ $e.ExternalName }}:{{ $e.Port -}} {{ if $e.DNSResolver }} {{ if $e.CheckHealth }} check {{- if $e.CheckHealthPort }} port {{ $e.CheckHealthPort }} {{- end }} {{- end }} resolvers {{ $e.DNSResolver }} resolve-prefer ipv4 {{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}}
{{- else if not $.DefaultBackend.BackendRules }}
acl https ssl_fc
http-request redirect location https://{{$e.ExternalName}}:{{ $e.Port }} code 301 if https
http-request redirect location http://{{$e.ExternalName}}:{{ $e.Port }} code 301 unless https
{{ end -}}
{{- else }}
server {{ $e.Name }} {{ $e.IP }}:{{ $e.Port -}} {{ if $e.MaxConnections }} maxconn {{ $e.MaxConnections }} {{ end -}} {{ if $e.Weight }} weight {{ $e.Weight }}{{ end -}} {{ if $.DefaultBackend.Sticky }} cookie {{ $e.Name }}{{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}}
server {{ $e.Name }} {{ $e.IP }}:{{ $e.Port -}} {{ if $e.MaxConnections }} maxconn {{ $e.MaxConnections }} {{ end -}} {{ if $e.Weight }} weight {{ $e.Weight }}{{ end -}} {{ if $.DefaultBackend.Sticky }} cookie {{ $e.Name }}{{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}} {{ if $e.CheckHealth }} check {{- if $e.CheckHealthPort }} port {{ $e.CheckHealthPort }} {{- end }} {{- end }}
{{ end -}}
{{ end -}}
4 changes: 2 additions & 2 deletions hack/docker/voyager/templates/http-backend.cfg
Expand Up @@ -25,12 +25,12 @@ backend {{ $path.Backend.Name }}
{{- range $index, $e := $path.Backend.Endpoints }}
{{- if $e.ExternalName }}
{{- if $e.UseDNSResolver }}
server {{ $e.Name }} {{ $e.ExternalName }}:{{ $e.Port -}} {{ if $e.DNSResolver }} {{ if $e.CheckHealth }} check {{ end }} resolvers {{ $e.DNSResolver }} resolve-prefer ipv4 {{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}}
server {{ $e.Name }} {{ $e.ExternalName }}:{{ $e.Port -}} {{ if $e.DNSResolver }} {{ if $e.CheckHealth }} check {{- if $e.CheckHealthPort }} port {{ $e.CheckHealthPort }} {{- end }} {{- end }} resolvers {{ $e.DNSResolver }} resolve-prefer ipv4 {{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}}
{{- else if not $path.Backend.BackendRules }}
http-request redirect location {{ if $.OffloadSSL }}https://{{ else }}http://{{ end }}{{$e.ExternalName}}:{{ $e.Port }} code 301
{{- end }}
{{- else }}
server {{ $e.Name }} {{ $e.IP }}:{{ $e.Port -}} {{ if $e.MaxConnections }} maxconn {{ $e.MaxConnections }} {{ end -}} {{ if $e.Weight }} weight {{ $e.Weight }} {{ end -}} {{ if $path.Backend.Sticky }} cookie {{ backend_hash $e.Name $index $path.Backend.StickyCookieHash }} {{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}}
server {{ $e.Name }} {{ $e.IP }}:{{ $e.Port -}} {{ if $e.MaxConnections }} maxconn {{ $e.MaxConnections }} {{ end -}} {{ if $e.Weight }} weight {{ $e.Weight }} {{ end -}} {{ if $path.Backend.Sticky }} cookie {{ backend_hash $e.Name $index $path.Backend.StickyCookieHash }} {{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}} {{ if $e.CheckHealth }} check {{- if $e.CheckHealthPort }} port {{ $e.CheckHealthPort }} {{- end }} {{- end }}
{{ end -}}
{{ end }}
{{ end -}}
Expand Down
4 changes: 2 additions & 2 deletions hack/docker/voyager/templates/tcp-backend.cfg
Expand Up @@ -12,8 +12,8 @@ backend {{ .Backend.Name }}

{{- range $e := .Backend.Endpoints }}
{{- if $e.ExternalName }}
server {{ $e.Name }} {{ $e.ExternalName }}:{{ $e.Port -}} {{ if $e.DNSResolver }} {{ if $e.CheckHealth }} check{{ end }} resolvers {{ $e.DNSResolver }} resolve-prefer ipv4{{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}}
server {{ $e.Name }} {{ $e.ExternalName }}:{{ $e.Port -}} {{ if $e.DNSResolver }} {{ if $e.CheckHealth }} check {{- if $e.CheckHealthPort }} port {{ $e.CheckHealthPort }} {{- end }} {{- end }} resolvers {{ $e.DNSResolver }} resolve-prefer ipv4{{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}}
{{- else }}
server {{ $e.Name }} {{ $e.IP }}:{{ $e.Port -}} {{ if $e.MaxConnections }} maxconn {{ $e.MaxConnections }} {{ end -}} {{ if $e.Weight }} weight {{ $e.Weight }}{{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}}
server {{ $e.Name }} {{ $e.IP }}:{{ $e.Port -}} {{ if $e.MaxConnections }} maxconn {{ $e.MaxConnections }} {{ end -}} {{ if $e.Weight }} weight {{ $e.Weight }}{{ end -}} {{ if $e.TLSOption }} {{ $e.TLSOption }} {{ end -}} {{ if $e.CheckHealth }} check {{- if $e.CheckHealthPort }} port {{ $e.CheckHealthPort }} {{- end }} {{- end }}
{{ end -}}
{{ end -}}
64 changes: 64 additions & 0 deletions pkg/haproxy/template_test.go
Expand Up @@ -679,3 +679,67 @@ func TestTLSAuth(t *testing.T) {
}
}
}

func TestHealthCheck(t *testing.T) {
si := &SharedInfo{
DefaultBackend: &Backend{
Name: "default",
Endpoints: []*Endpoint{
{Name: "aaa", IP: "10.244.2.1", Port: "2323"},
{Name: "bbb", IP: "10.244.2.1", Port: "2323", CheckHealth: true},
{Name: "ccc", IP: "10.244.2.1", Port: "2323", CheckHealth: true, CheckHealthPort: "5050"},
{Name: "ddd", IP: "10.244.2.1", Port: "2323", ExternalName: "name", DNSResolver: "one", UseDNSResolver: true, CheckHealth: true, CheckHealthPort: "5050"},
},
},
}
testParsedConfig := TemplateData{
SharedInfo: si,
HTTPService: []*HTTPService{
{
SharedInfo: si,
FrontendName: "one",
Port: 80,
FrontendRules: []string{},
Paths: []*HTTPPath{
{
Path: "/elijah",
Backend: Backend{
Name: "elijah",
Endpoints: []*Endpoint{
{Name: "aaa", IP: "10.244.2.1", Port: "2323"},
{Name: "bbb", IP: "10.244.2.1", Port: "2323", CheckHealth: true},
{Name: "ccc", IP: "10.244.2.1", Port: "2323", CheckHealth: true, CheckHealthPort: "5050"},
{Name: "ddd", IP: "10.244.2.1", Port: "2323", ExternalName: "name", DNSResolver: "one", UseDNSResolver: true, CheckHealth: true, CheckHealthPort: "5050"},
},
},
},
},
},
},
TCPService: []*TCPService{
{
SharedInfo: si,
FrontendName: "stefan",
Port: "333",
FrontendRules: []string{},
Backend: Backend{
Name: "stefan",
Endpoints: []*Endpoint{
{Name: "aaa", IP: "10.244.2.1", Port: "2323"},
{Name: "bbb", IP: "10.244.2.1", Port: "2323", CheckHealth: true},
{Name: "ccc", IP: "10.244.2.1", Port: "2323", CheckHealth: true, CheckHealthPort: "5050"},
{Name: "ddd", IP: "10.244.2.1", Port: "2323", ExternalName: "name", DNSResolver: "one", UseDNSResolver: true, CheckHealth: true, CheckHealthPort: "5050"},
},
},
},
},
}
err := LoadTemplates(runtime.GOPath()+"/src/github.com/appscode/voyager/hack/docker/voyager/templates/*.cfg", "")
if assert.Nil(t, err) {
config, err := RenderConfig(testParsedConfig)
assert.Nil(t, err)
if testing.Verbose() {
fmt.Println(err, "\n", config)
}
}
}
19 changes: 10 additions & 9 deletions pkg/haproxy/types.go
Expand Up @@ -127,15 +127,16 @@ func (be *Backend) canonicalize() {
}

type Endpoint struct {
Name string
IP string
Port string
Weight int
MaxConnections int
ExternalName string
UseDNSResolver bool
DNSResolver string
CheckHealth bool
Name string
IP string
Port string
Weight int
MaxConnections int
ExternalName string
UseDNSResolver bool
DNSResolver string
CheckHealth bool
CheckHealthPort string

TLSOption string
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/ingress/parser.go
Expand Up @@ -143,6 +143,10 @@ func (c *controller) getEndpoints(svc *core.Service, servicePort *core.ServicePo

if svc.Annotations != nil {
ep.TLSOption = svc.Annotations[api.BackendTLSOptions]
if svc.Annotations[api.CheckHealth] == "true" {
ep.CheckHealth = true
ep.CheckHealthPort = svc.Annotations[api.CheckHealthPort]
}
}

eps = append(eps, ep)
Expand Down

0 comments on commit 81a01a3

Please sign in to comment.