Skip to content

Commit 5fd9449

Browse files
armruleonardocefcanovai
authored
feat: add liveness and readiness probe support (#69)
Signed-off-by: Armando Ruocco <[email protected]> Signed-off-by: Leonardo Cecchi <[email protected]> Signed-off-by: Francesco Canovai <[email protected]> Co-authored-by: Leonardo Cecchi <[email protected]> Co-authored-by: Francesco Canovai <[email protected]>
1 parent 9404772 commit 5fd9449

File tree

8 files changed

+127
-0
lines changed

8 files changed

+127
-0
lines changed

cmd/manager/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/spf13/cobra"
1111
ctrl "sigs.k8s.io/controller-runtime"
1212

13+
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cmd/healthcheck"
1314
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cmd/instance"
1415
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cmd/operator"
1516
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cmd/restore"
@@ -32,6 +33,7 @@ func main() {
3233
rootCmd.AddCommand(instance.NewCmd())
3334
rootCmd.AddCommand(operator.NewCmd())
3435
rootCmd.AddCommand(restore.NewCmd())
36+
rootCmd.AddCommand(healthcheck.NewCmd())
3537

3638
if err := rootCmd.ExecuteContext(ctrl.SetupSignalHandler()); err != nil {
3739
if !errors.Is(err, context.Canceled) {

internal/cmd/healthcheck/doc.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package healthcheck contains the logic to execute an healthcheck on the plugin through a command
2+
package healthcheck

internal/cmd/healthcheck/main.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package healthcheck
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path"
7+
8+
"github.com/cloudnative-pg/machinery/pkg/log"
9+
"github.com/spf13/cobra"
10+
"google.golang.org/grpc"
11+
"google.golang.org/grpc/credentials/insecure"
12+
"google.golang.org/grpc/health/grpc_health_v1"
13+
14+
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
15+
)
16+
17+
// NewCmd returns the healthcheck command
18+
func NewCmd() *cobra.Command {
19+
cmd := &cobra.Command{
20+
Use: "healthcheck",
21+
Short: "healthcheck commands",
22+
}
23+
24+
cmd.AddCommand(unixHealthCheck())
25+
26+
return cmd
27+
}
28+
29+
func unixHealthCheck() *cobra.Command {
30+
cmd := &cobra.Command{
31+
Use: "unix",
32+
Short: "executes the health check command on unix:///plugins/barman-cloud.cloudnative-pg.io",
33+
RunE: func(cmd *cobra.Command, _ []string) error {
34+
dialPath := fmt.Sprintf("unix://%s", path.Join("/plugins", metadata.PluginName))
35+
cli, cliErr := grpc.NewClient(dialPath, grpc.WithTransportCredentials(insecure.NewCredentials()))
36+
if cliErr != nil {
37+
log.Error(cliErr, "while building the client")
38+
return cliErr
39+
}
40+
41+
healthCli := grpc_health_v1.NewHealthClient(cli)
42+
res, healthErr := healthCli.Check(
43+
cmd.Context(),
44+
&grpc_health_v1.HealthCheckRequest{},
45+
)
46+
if healthErr != nil {
47+
log.Error(healthErr, "while executing the healthcheck call")
48+
return healthErr
49+
}
50+
51+
if res.Status == grpc_health_v1.HealthCheckResponse_SERVING {
52+
log.Trace("healthcheck response OK")
53+
os.Exit(0)
54+
return nil
55+
}
56+
57+
log.Error(fmt.Errorf("unexpected healthcheck status: %v", res.Status),
58+
"while processing healthcheck response")
59+
60+
// exit code 1 is returned when we exit from the function with an error
61+
switch res.Status {
62+
case grpc_health_v1.HealthCheckResponse_UNKNOWN:
63+
os.Exit(2)
64+
case grpc_health_v1.HealthCheckResponse_NOT_SERVING:
65+
os.Exit(3)
66+
default:
67+
os.Exit(125)
68+
}
69+
70+
return nil
71+
},
72+
}
73+
74+
return cmd
75+
}

internal/cnpgi/common/health.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package common
2+
3+
import (
4+
"context"
5+
6+
"github.com/cloudnative-pg/machinery/pkg/log"
7+
"google.golang.org/grpc"
8+
"google.golang.org/grpc/health/grpc_health_v1"
9+
)
10+
11+
// AddHealthCheck adds a health check service to the gRPC server with the tag 'plugin-barman-cloud'
12+
func AddHealthCheck(server *grpc.Server) {
13+
grpc_health_v1.RegisterHealthServer(server, &healthServer{}) // replaces default registration
14+
}
15+
16+
type healthServer struct {
17+
grpc_health_v1.UnimplementedHealthServer
18+
}
19+
20+
// Check is the response handle for the healthcheck request
21+
func (h healthServer) Check(
22+
ctx context.Context,
23+
_ *grpc_health_v1.HealthCheckRequest,
24+
) (*grpc_health_v1.HealthCheckResponse, error) {
25+
contextLogger := log.FromContext(ctx)
26+
contextLogger.Trace("serving health check response")
27+
return &grpc_health_v1.HealthCheckResponse{Status: grpc_health_v1.HealthCheckResponse_SERVING}, nil
28+
}

internal/cnpgi/instance/start.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func (c *CNPGI) Start(ctx context.Context) error {
4646
ClusterObjectKey: c.ClusterObjectKey,
4747
InstanceName: c.InstanceName,
4848
})
49+
common.AddHealthCheck(server)
4950
return nil
5051
}
5152

internal/cnpgi/operator/lifecycle.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,21 @@ func reconcilePodSpec(
235235
},
236236
}
237237

238+
baseProbe := &corev1.Probe{
239+
FailureThreshold: 3,
240+
ProbeHandler: corev1.ProbeHandler{
241+
Exec: &corev1.ExecAction{
242+
Command: []string{"manager", "healthcheck", "unix"},
243+
},
244+
},
245+
}
246+
238247
// fixed values
239248
sidecarConfig.Name = "plugin-barman-cloud"
240249
sidecarConfig.Image = viper.GetString("sidecar-image")
241250
sidecarConfig.ImagePullPolicy = cluster.Spec.ImagePullPolicy
251+
sidecarConfig.LivenessProbe = baseProbe.DeepCopy()
252+
sidecarConfig.StartupProbe = baseProbe.DeepCopy()
242253

243254
// merge the main container envs if they aren't already set
244255
for _, container := range spec.Containers {

internal/cnpgi/restore/start.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ func (c *CNPGI) Start(ctx context.Context) error {
4949
PgDataPath: c.PGDataPath,
5050
PgWalFolderToSymlink: PgWalVolumePgWalPath,
5151
})
52+
53+
common.AddHealthCheck(server)
54+
5255
return nil
5356
}
5457

kubernetes/deployment.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ spec:
3737
- --server-address=:9090
3838
- --leader-elect
3939
- --log-level=debug
40+
readinessProbe:
41+
tcpSocket:
42+
port: 9090
43+
initialDelaySeconds: 10
44+
periodSeconds: 10
4045
volumeMounts:
4146
- mountPath: /server
4247
name: server

0 commit comments

Comments
 (0)