![](/img/trans.png)
[英]Dynamic URL that forwards all requests to dedicated Pod in 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.