这是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响应请求?
答案 0 :(得分:2)
您正在使用NodePort公开服务,因此没有反向代理,但您直接连接到Pod。首先,这是一个不错的选择。 (稍后您可能要使用Ingress)
您看到的是只有一个Pod可以处理您的请求。您希望每个请求都负载均衡到不同的容器。并且您的假设是正确的,但是负载平衡不是在HTTP请求层上发生,而是在TCP层上发生。
因此,当您拥有持久的TCP连接并重新使用它时,将不会遇到预期的负载平衡。由于建立TCP连接的延迟相当昂贵,通常通常会进行优化以避免重复打开新的TCP连接:HTTP保持活动。
默认情况下,大多数框架和客户端中都启用了“保持活动”,Go也是如此。
尝试resource "azurerm_resource_group" "test" {
name = "resourceGroup1"
location = "West US 2"
}
resource "azurerm_eventhub_namespace" "test" {
name = "acceptanceTestEventHubNamespace"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
sku = "Standard"
capacity = 1
kafka_enabled = false
tags = {
environment = "Production"
}
}
resource "azurerm_eventhub" "test" {
name = "acceptanceTestEventHub"
namespace_name = "${azurerm_eventhub_namespace.test.name}"
resource_group_name = "${azurerm_resource_group.test.name}"
partition_count = 2
message_retention = 1
}
resource "azurerm_eventgrid_topic" "test" {
name = "my-eventgrid-topic"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
tags = {
environment = "Production"
}
}
resource "azurerm_eventgrid_domain" "test" {
name = "my-eventgrid-domain"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
input_schema = "eventgridschema"
input_mapping_fields= {
topic = "my-eventgrid-topic"
}
tags = {
environment = "Production"
}
}
resource "azurerm_eventgrid_event_subscription" "default" {
name = "defaultEventSubscription"
scope = "${azurerm_resource_group.default.id}"
event_delivery_schema = "EventGridSchema"
topic_name = "my-eventgrid-topic"
eventhub_endpoint {
storage_account_id = "${azurerm_eventhub.test.id}"
}
}
,看看是否可以解决您的问题。 (建议仅用于测试!)
您还可以使用多个不同的客户端,例如从命令行使用curl或在Postman中禁用keep-alive。
答案 1 :(得分:2)
感谢@Thomas的深刻见解!我尝试使用请求标头,它解决了负载平衡问题,即所有请求仅命中一个副本,而对于演示或测试,能够将请求分发到所有副本非常有用
来自文档:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection 连接:保持活动状态 连接:关闭
此请求始终点击同一广告连播
curl -H "Connection: keep-alive" http://your-service:port/path
但是,使用close
,请求平衡到了所有广告连播
curl -H "Connection: close" http://your-service:port/path
答案 2 :(得分:0)
在Kubernetes集群中,发送到k8s服务的请求由kube-proxy路由。
自Kubernetes v1.2起,默认的kube-proxy
模式为Iptalbles
,它可以在服务和后端Pod之间实现更快的数据包解析。后端Pod之间的负载平衡是通过iptables rules
直接完成的。
也许您没有生成一个Pod无法处理的足够负载,这就是为什么您从kube-proxy
被路由到同一Pod的原因。
您还可以看到有关实现自定义iptalbes-rule
的问题的答案: