diff options
author | Piotr <piotr.skoczylas@gmail.com> | 2022-09-22 16:59:12 +0200 |
---|---|---|
committer | Piotr <piotr.skoczylas@gmail.com> | 2022-09-27 16:52:54 +0200 |
commit | 95cb14aff26b1562045ebcebc07978dc897694e7 (patch) | |
tree | 546dac111e0445dcdece292584d0797d6e628422 | |
parent | f51aeb45d497379b6e0a11414d69435e83908efa (diff) | |
download | podman-95cb14aff26b1562045ebcebc07978dc897694e7.tar.gz podman-95cb14aff26b1562045ebcebc07978dc897694e7.tar.bz2 podman-95cb14aff26b1562045ebcebc07978dc897694e7.zip |
fix: liveness check with http probe
Ensure kubernetes default parameters are respected.
Additional curl parameter enforces returning error for HTTP error codes.
Use build-in HealthCheckOnFailureAction instead of killing the container
while executing the probe.
Signed-off-by: Piotr <piotr.skoczylas@gmail.com>
-rw-r--r-- | pkg/specgen/generate/kube/kube.go | 22 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/play_test.go | 59 |
2 files changed, 73 insertions, 8 deletions
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index 7d85fd2f3..b1828736d 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -500,20 +500,22 @@ func setupLivenessProbe(s *specgen.SpecGenerator, containerYAML v1.Container, re probe := containerYAML.LivenessProbe probeHandler := probe.Handler - // append `exit 1` to `cmd` so healthcheck can be marked as `unhealthy`. - // append `kill 1` to `cmd` if appropriate restart policy is configured. - if restartPolicy == "always" || restartPolicy == "onfailure" { - // container will be restarted so we can kill init. - failureCmd = "kill 1" - } - // configure healthcheck on the basis of Handler Actions. switch { case probeHandler.Exec != nil: execString := strings.Join(probeHandler.Exec.Command, " ") commandString = fmt.Sprintf("%s || %s", execString, failureCmd) case probeHandler.HTTPGet != nil: - commandString = fmt.Sprintf("curl %s://%s:%d/%s || %s", probeHandler.HTTPGet.Scheme, probeHandler.HTTPGet.Host, probeHandler.HTTPGet.Port.IntValue(), probeHandler.HTTPGet.Path, failureCmd) + // set defaults as in https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#http-probes + var uriScheme v1.URIScheme = "http" + if probeHandler.HTTPGet.Scheme != "" { + uriScheme = probeHandler.HTTPGet.Scheme + } + host := "localhost" // Kubernetes default is host IP, but with Podman there is only one node + if probeHandler.HTTPGet.Host != "" { + host = probeHandler.HTTPGet.Host + } + commandString = fmt.Sprintf("curl -f %s://%s:%d%s || %s", uriScheme, host, probeHandler.HTTPGet.Port.IntValue(), probeHandler.HTTPGet.Path, failureCmd) case probeHandler.TCPSocket != nil: commandString = fmt.Sprintf("nc -z -v %s %d || %s", probeHandler.TCPSocket.Host, probeHandler.TCPSocket.Port.IntValue(), failureCmd) } @@ -521,6 +523,10 @@ func setupLivenessProbe(s *specgen.SpecGenerator, containerYAML v1.Container, re if err != nil { return err } + // if restart policy is in place, ensure the health check enforces it + if restartPolicy == "always" || restartPolicy == "onfailure" { + s.HealthCheckOnFailureAction = define.HealthCheckOnFailureActionRestart + } return nil } return nil diff --git a/pkg/specgen/generate/kube/play_test.go b/pkg/specgen/generate/kube/play_test.go index ec0dc4bcd..efe2e51b1 100644 --- a/pkg/specgen/generate/kube/play_test.go +++ b/pkg/specgen/generate/kube/play_test.go @@ -11,6 +11,8 @@ import ( v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1" "github.com/containers/podman/v4/pkg/k8s.io/apimachinery/pkg/api/resource" v12 "github.com/containers/podman/v4/pkg/k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/containers/podman/v4/pkg/k8s.io/apimachinery/pkg/util/intstr" + "github.com/containers/podman/v4/pkg/specgen" "github.com/docker/docker/pkg/system" "github.com/stretchr/testify/assert" ) @@ -858,3 +860,60 @@ var ( }, } ) + +func TestHttpLivenessProbe(t *testing.T) { + tests := []struct { + name string + specGenerator specgen.SpecGenerator + container v1.Container + restartPolicy string + succeed bool + expectedURL string + }{ + { + "HttpLivenessProbeUrlSetCorrectly", + specgen.SpecGenerator{}, + v1.Container{ + LivenessProbe: &v1.Probe{ + Handler: v1.Handler{ + HTTPGet: &v1.HTTPGetAction{ + Scheme: "http", + Host: "127.0.0.1", + Port: intstr.FromInt(8080), + Path: "/health", + }, + }, + }, + }, + "always", + true, + "http://127.0.0.1:8080/health", + }, + { + "HttpLivenessProbeUrlUsesDefaults", + specgen.SpecGenerator{}, + v1.Container{ + LivenessProbe: &v1.Probe{ + Handler: v1.Handler{ + HTTPGet: &v1.HTTPGetAction{ + Port: intstr.FromInt(80), + Path: "/", + }, + }, + }, + }, + "always", + true, + "http://localhost:80/", + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := setupLivenessProbe(&test.specGenerator, test.container, test.restartPolicy) + assert.Equal(t, err == nil, test.succeed) + assert.Contains(t, test.specGenerator.ContainerHealthCheckConfig.HealthConfig.Test, test.expectedURL) + }) + } +} |