簡體   English   中英

只有 1 個 pod 處理 Kubernetes 集群中的所有請求

[英]Only 1 pod handles all requests in Kubernetes cluster

這是 minikube Kubernetes 的清單文件,用於部署和服務:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deployment
spec:
  selector:
    matchLabels:
      app: hello
  replicas: 3
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello
        image: hello_hello
        imagePullPolicy: Never
        ports:
        - containerPort: 4001
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: hello
spec:
  selector:
    app: hello
  ports:
  - port: 4001
    nodePort: 30036
    protocol: TCP
  type: NodePort

還有一個用 Golang 編寫的簡單 HTTP 服務器

package main
import (
    http "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })

    server := &http.Server{
        Addr:    ":4001",
        Handler: r,
    }

    server.ListenAndServe()
}

當我向IP:30036/ping發出多個請求然后打開 pod 的日志時,我可以看到 3 個 pod 中只有 1 個處理所有請求。 如何讓其他 Pod 響應請求?

您正在使用 NodePort 公開服務,因此沒有反向代理,但您直接連接到您的 Pod。 這是一個不錯的選擇。 (稍后您可能想要使用 Ingress)

您看到的是只有一個 Pod 處理您的請求。 您希望每個請求都負載平衡到不同的 pod。 而且您的假設是正確的,但是負載平衡不會發生在 HTTP 請求層上,而是發生在 TCP 層上。

因此,當您擁有持久的 TCP 連接並重新使用它時,您將不會體驗到預期的負載平衡。 由於建立 TCP 連接在延遲方面相當昂貴,因此通常會進行優化以避免重復打開新的 TCP 連接:HTTP keep-alive。

在大多數框架和客戶端中默認啟用保持活動,Go 也是如此。 嘗試s.SetKeepAlivesEnabled(false)看看是否能解決您的問題。 (僅推薦用於測試!)

您還可以使用多個不同的客戶端,從命令行使用 curl 或在 Postman 中禁用 keep-alive。

感謝@Thomas 的深刻見解,我嘗試使用請求 header 並解決了所有請求僅命中單個副本的負載平衡問題,而對於演示或測試,能夠將請求分發到所有副本很有用

來自文檔:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection連接:保持活動連接:關閉

這個請求總是命中同一個 pod

curl -H "Connection: keep-alive" http://your-service:port/path

但是,使用close ,請求平衡到所有 pod

curl -H "Connection: close" http://your-service:port/path

在 Kubernetes 集群中,發送到 k8s 服務的請求由kube-proxy路由。

自 Kubernetes v1.2 起,默認的kube-proxy模式為Iptalbles ,它允許在服務和后端 Pod 之間更快地解析數據包。 后端 Pod 之間的負載平衡直接通過iptables rules完成。

也許你沒有產生足夠的負載,一個 pod 無法處理,這就是為什么你從kube-proxy路由到同一個 pod。

您還可以查看實現自定義iptalbes-rule的此問題的答案:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM