Skip to content

Commit

Permalink
Merge pull request #7 from nginxinc/add-health-endpoints
Browse files Browse the repository at this point in the history
Add basic probe checks
  • Loading branch information
ciroque authored Feb 13, 2023
2 parents bcd06b8 + cbf3832 commit 6655ec4
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cmd/nginx-k8s-edge-controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"github.com/nginxinc/kubernetes-nginx-ingress/internal/config"
"github.com/nginxinc/kubernetes-nginx-ingress/internal/observation"
"github.com/nginxinc/kubernetes-nginx-ingress/internal/probation"
"github.com/nginxinc/kubernetes-nginx-ingress/internal/synchronization"
"github.com/sirupsen/logrus"
"k8s.io/client-go/kubernetes"
Expand Down Expand Up @@ -68,6 +69,9 @@ func run() error {
go handler.Run(ctx.Done())
go synchronizer.Run(ctx.Done())

probeServer := probation.NewHealthServer()
probeServer.Start()

err = watcher.Watch()
if err != nil {
return fmt.Errorf(`error occurred watching for events: %w`, err)
Expand Down
16 changes: 16 additions & 0 deletions deployment/nkl-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,20 @@ spec:
value: "http://10.1.1.4:9000/api"
image: ciroque/nginx-k8s-edge-controller:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 51031
protocol: TCP
livenessProbe:
httpGet:
path: /livez
port: http
initialDelaySeconds: 5
periodSeconds: 2
readinessProbe:
httpGet:
path: /readyz
port: http
initialDelaySeconds: 5
periodSeconds: 2
serviceAccountName: nginx-k8s-edge-controller
30 changes: 30 additions & 0 deletions internal/probation/check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2023 f5 Inc. All rights reserved.
// Use of this source code is governed by the Apache
// license that can be found in the LICENSE file.

package probation

type Check interface {
Check() bool
}

type LiveCheck struct {
}

type ReadyCheck struct {
}

type StartupCheck struct {
}

func (l *LiveCheck) Check() bool {
return true
}

func (r *ReadyCheck) Check() bool {
return true
}

func (s *StartupCheck) Check() bool {
return true
}
9 changes: 9 additions & 0 deletions internal/probation/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2023 f5 Inc. All rights reserved.
// Use of this source code is governed by the Apache
// license that can be found in the LICENSE file.

/*
Package probation includes support for Kubernetes health and wellness checks.
*/

package probation
87 changes: 87 additions & 0 deletions internal/probation/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright 2023 f5 Inc. All rights reserved.
// Use of this source code is governed by the Apache
// license that can be found in the LICENSE file.

package probation

import (
"fmt"
"github.com/sirupsen/logrus"
"net/http"
)

const (
Ok = "OK"
ServiceNotAvailable = "Service Not Available"
ListenPort = 51031
)

type HealthServer struct {
httpServer *http.Server
LiveCheck LiveCheck
ReadyCheck ReadyCheck
StartupCheck StartupCheck
}

func NewHealthServer() *HealthServer {
return &HealthServer{
LiveCheck: LiveCheck{},
ReadyCheck: ReadyCheck{},
StartupCheck: StartupCheck{},
}
}

func (hs *HealthServer) Start() {
logrus.Debugf("Starting probe listener on port %d", ListenPort)

address := fmt.Sprintf(":%d", ListenPort)

mux := http.NewServeMux()
mux.HandleFunc("/livez", hs.HandleLive)
mux.HandleFunc("/readyz", hs.HandleReady)
mux.HandleFunc("/startupz", hs.HandleStartup)
hs.httpServer = &http.Server{Addr: address, Handler: mux}

go func() {
if err := hs.httpServer.ListenAndServe(); err != nil {
logrus.Errorf("unable to start probe listener on %s: %v", hs.httpServer.Addr, err)
}
}()

logrus.Info("Started probe listener on", hs.httpServer.Addr)
}

func (hs *HealthServer) Stop() {
if err := hs.httpServer.Close(); err != nil {
logrus.Errorf("unable to stop probe listener on %s: %v", hs.httpServer.Addr, err)
}
}

func (hs *HealthServer) HandleLive(writer http.ResponseWriter, request *http.Request) {
handleProbe(writer, request, &hs.LiveCheck)
}

func (hs *HealthServer) HandleReady(writer http.ResponseWriter, request *http.Request) {
handleProbe(writer, request, &hs.ReadyCheck)
}

func (hs *HealthServer) HandleStartup(writer http.ResponseWriter, request *http.Request) {
handleProbe(writer, request, &hs.StartupCheck)
}

func handleProbe(writer http.ResponseWriter, _ *http.Request, check Check) {
if check.Check() {
writer.WriteHeader(http.StatusOK)

if _, err := fmt.Fprint(writer, Ok); err != nil {
logrus.Error(err)
}

} else {
writer.WriteHeader(http.StatusServiceUnavailable)

if _, err := fmt.Fprint(writer, ServiceNotAvailable); err != nil {
logrus.Error(err)
}
}
}

0 comments on commit 6655ec4

Please sign in to comment.