diff --git a/examples/liveness/http-liveness.yaml b/examples/liveness/http-liveness.yaml new file mode 100644 index 00000000000..7a9d6ad160f --- /dev/null +++ b/examples/liveness/http-liveness.yaml @@ -0,0 +1,19 @@ +apiVersion: v1beta1 +desiredState: + manifest: + containers: + - image: kubernetes/liveness + name: liveness + livenessProbe: + httpGet: + path: "/healthz" + port: 8080 + initialDelaySeconds: 15 + command: + - /server + id: liveness-http + version: v1beta1 +id: liveness-http +kind: Pod +labels: + test: liveness diff --git a/examples/liveness/image/Dockerfile b/examples/liveness/image/Dockerfile new file mode 100644 index 00000000000..d057ecd309e --- /dev/null +++ b/examples/liveness/image/Dockerfile @@ -0,0 +1,4 @@ +FROM scratch + +ADD server /server + diff --git a/examples/liveness/image/Makefile b/examples/liveness/image/Makefile new file mode 100644 index 00000000000..5ec1723646d --- /dev/null +++ b/examples/liveness/image/Makefile @@ -0,0 +1,13 @@ +all: push + +server: server.go + CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags '-w' ./server.go + +container: server + docker build -t kubernetes/liveness . + +push: container + docker push kubernetes/liveness + +clean: + rm -f server diff --git a/examples/liveness/image/server.go b/examples/liveness/image/server.go new file mode 100644 index 00000000000..88b935577da --- /dev/null +++ b/examples/liveness/image/server.go @@ -0,0 +1,46 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// A simple server that is alive for 10 seconds, then reports unhealthy for +// the rest of its (hopefully) short existence. +package main + +import ( + "fmt" + "log" + "net/http" + "time" +) + +func main() { + started := time.Now() + http.HandleFunc("/started", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + data := (time.Now().Sub(started)).String() + w.Write([]byte(data)) + }) + http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { + duration := time.Now().Sub(started) + if duration.Seconds() > 10 { + w.WriteHeader(500) + w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds()))) + } else { + w.WriteHeader(200) + w.Write([]byte("ok")) + } + }) + log.Fatal(http.ListenAndServe(":8080", nil)) +} diff --git a/hack/e2e-suite/liveness.sh b/hack/e2e-suite/liveness.sh new file mode 100755 index 00000000000..638def84021 --- /dev/null +++ b/hack/e2e-suite/liveness.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +# Copyright 2014 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Launches a container and verifies it can be reached. Assumes that +# we're being called by hack/e2e-test.sh (we use some env vars it sets up). + +set -o errexit +set -o nounset +set -o pipefail + +KUBE_ROOT=$(dirname "${BASH_SOURCE}")/../.. +source "${KUBE_ROOT}/cluster/kube-env.sh" +source "${KUBE_ROOT}/cluster/$KUBERNETES_PROVIDER/util.sh" + +function teardown() { + echo "Cleaning up test artifacts" + ${KUBECFG} delete pods/liveness-http +} + +function waitForRunning() { + pod_id_list=$($KUBECFG '-template={{range.items}}{{.id}} {{end}}' -l test=liveness list pods) + # Pod turn up on a clean cluster can take a while for the docker image pull. + all_running=0 + for i in $(seq 1 24); do + echo "Waiting for pod to come up." + sleep 5 + all_running=1 + for id in $pod_id_list; do + current_status=$($KUBECFG -template '{{.currentState.status}}' get pods/$id) || true + if [[ "$current_status" != "Running" ]]; then + all_running=0 + break + fi + done + if [[ "${all_running}" == 1 ]]; then + break + fi + done + if [[ "${all_running}" == 0 ]]; then + echo "Pods did not come up in time" + exit 1 + fi +} + +trap "teardown" EXIT + +${KUBECFG} -c ${KUBE_ROOT}/examples/liveness/http-liveness.yaml create pods +waitForRunning + +before=$(${KUBECFG} '-template={{.currentState.info.liveness.restartCount}}' get pods/liveness-http) + +echo "Waiting for restarts." +for i in $(seq 1 24); do + sleep 10 + after=$(${KUBECFG} '-template={{.currentState.info.liveness.restartCount}}' get pods/liveness-http) + echo "Restarts: ${after} > ${before}" + if [[ "${after}" > "${before} ]]; then + break + fi +done + +if [[ "${before}" < "${after}" ]]; then + exit 0 +fi + +echo "Unexpected absence of failures." +echo "Restarts before: ${before}." +echo "Restarts after: ${after}" +exit 1