gpt4 book ai didi

docker - 在 Kubernetes 推出期间在 HTTP 服务器上测试正常关闭

转载 作者:行者123 更新时间:2023-12-01 20:27:29 25 4
gpt4 key购买 nike

我遵循了一些关于如何设置 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/deployment.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


kubernetes/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: myapp
name: myapp
spec:
ports:
- port: 8080
protocol: TCP
selector:
app: myapp
sessionAffinity: None
type: NodePort

此设置中是否缺少某些内容?根据 rollingUpdate策略,应该至少有五个正在运行的 Pod 来处理传入的请求,但是 abapr_socket_recv: Connection reset by peer (54) 退出错误。我也尝试添加就绪/活跃度探测器,但没有运气。我怀疑这里也不需要它们。

最佳答案

为了在不停机的情况下工作,您需要让 Pod 停止接收新连接,同时允许 Pod 优雅地完成处理当前连接。这意味着 pod 需要运行,但尚未准备好,因此不会向其发送新请求。

您的服务将使用您配置的标签选择器(我假设 app: myapp)匹配所有 pod,并将使用任何处于就绪状态的 pod 作为可能的后端。只要 Pod 通过 readinessProbe,它就会被标记为就绪。由于您没有配置探针,因此只要 pod 正在运行,它的状态就会默认为就绪。

只需一个 readinessProbe配置将有很大帮助,但不会提供 100% 的正常运行时间,这将需要在您的代码中进行一些调整,以导致 readinessProbe 失败(因此不会发送新请求),同时容器正常完成当前连接。

编辑:根据@Thomas Jungblut 提到的,消除网络服务器错误的很大一部分是应用程序如何处理 SIGTERM。当 pod 处于终止状态时,它将不再通过服务接收请求。在此阶段,您的网络服务器需要配置为正常完成和终止连接,而不是突然停止并终止请求。

请注意,这是在应用程序本身中配置的,而不是 k8s 设置。只要网络服务器优雅地排空连接并且您的 pod 规范包含足够长的 gracefulTerminationPeriod 以允许网络服务器排空,您应该基本上看不到任何错误。尽管这仍然不能保证 100% 的正常运行时间,尤其是在使用 ab 轰炸服务时。

关于docker - 在 Kubernetes 推出期间在 HTTP 服务器上测试正常关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58751354/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com