Я следовал некоторым учебникам о том, как настроить HTTP-сервер и протестировать его в локальном кластере Kubernetes (используя minikube
).
Я также реализовал изящное отключение из некоторых найденных примеров и ожидалчто после повторного перезапуска в Kubernetes не будет простоев.
Чтобы убедиться в этом, я начал выполнять нагрузочные тесты (используя Apache Benchmark , запустив ab -n 100000 -c 20 <addr>
) и запустив kubectl rollout restart
во времябенчмаркинг, но ab
останавливается, как только выполняется повторный перезапуск.
Вот моя текущая настройка проекта:
Dockerfile
FROM golang:1.13.4-alpine3.10
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN go build -o main src/main.go
CMD ["/app/main"]
src / main.go
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"github.com/gorilla/mux"
)
func main() {
srv := &http.Server{
Addr: ":8080",
Handler: NewHTTPServer(),
}
idleConnsClosed := make(chan struct{})
go func() {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
<-sigint
// We received an interrupt signal, shut down.
if err := srv.Shutdown(context.Background()); err != nil {
// Error from closing listeners, or context timeout:
log.Printf("HTTP server Shutdown: %v", err)
}
close(idleConnsClosed)
}()
log.Printf("Starting HTTP server")
running = true
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
// Error starting or closing listener:
log.Fatalf("HTTP server ListenAndServe: %v", err)
}
<-idleConnsClosed
}
func NewHTTPServer() http.Handler {
r := mux.NewRouter()
// Ping
r.HandleFunc("/", handler)
return r
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
}
kubernetes / deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myapp
name: myapp
spec:
replicas: 10
selector:
matchLabels:
app: myapp
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 5
type: RollingUpdate
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: dickster/graceful-shutdown-test:latest
imagePullPolicy: Never
ports:
- containerPort: 8080
Чего-то не хватает в этой настройке? Согласно стратегии rollingUpdate
должно быть не менее пяти работающих модулей, которые должны обслуживать входящие запросы, но ab
завершает работу с ошибкой apr_socket_recv: Connection reset by peer (54)
. Я также попытался добавить тесты готовности / живучести, но не повезло. Я подозреваю, что они здесь тоже не нужны.