我们正在开发一个模拟软件,该软件使用kubernetes在多个pod之间部署和扩展。当用户发出模拟请求时,会选择一个开始执行工作并被视为忙碌的pod。当另一个用户发出模拟请求时,它应该被路由到下一个空闲pod。目前,通常会选择一个繁忙的pod(即使有空闲的pod),因为kubernetes不知道哪些pod是忙/空闲的。
是否可以以始终选择空闲pod的方式平衡请求?(假设pod中的每个应用程序实例都公开了一个HTTPendpoint,该endpoint告诉它当前的繁忙/空闲状态)
我认为您可以使用就绪探头:
有时,应用程序暂时无法服务于流量。例如,应用程序可能需要在启动期间加载大型数据或配置文件,或者在启动后依赖于外部服务。在这种情况下,您不想终止应用程序,但也不想向它发送请求。Kubernetes提供了检测和缓解这些情况的就绪探针。一个带有容器的pod报告它们还没有准备好,它不会通过Kubernetes服务接收流量。
您可以使用非200返回代码使应用程序响应探测请求。需要注意的是,在准备就绪探测再次成功之前,不会有新的请求传入。但也有缺点:
上面答案中建议的另一个解决方案是利用无头服务和一些反向代理/负载平衡器,比如HAProxy(我用过)。
所以你可以有一个无头服务或者改变现有的服务,如下图所示。配置clusterIP:None将负责创建无头服务。
apiVersion: v1
kind: Service
metadata:
name: some-service
namespace: dev
labels:
app: <labels here>
spec:
ports:
- port: <port>
targetPort: <tport>
selector:
app: <selectors here>
clusterIP: None
然后您可以像下面这样部署HAProxy
apiVersion: apps/v1
kind: Deployment
metadata:
name: haproxy-headless
namespace: dev
labels:
app: haproxy-headless
spec:
replicas: 1
selector:
matchLabels:
app: haproxy-headless
template:
metadata:
labels:
app: haproxy-headless
spec:
containers:
- name: haproxy-headless
image: haproxy:1.9
ports:
- containerPort: 8888
name: management
- containerPort: 8085
name: http
volumeMounts:
- name: haproxy-config
mountPath: "/usr/local/etc/haproxy/haproxy.cfg"
volumes:
- name: haproxy-config
configMap:
name: haproxy-config
Haproxy的配置图:
apiVersion: v1
kind: ConfigMap
metadata:
name: haproxy-config
namespace: dev
data:
haproxyconfig.cfg: |
defaults
mode tcp
log global
option httplog
retries 5
timeout connect 10s
timeout client 300s
timeout server 300s
resolvers test_resolver
nameserver dns1 <your dns server address>
resolve_retries 30
timeout retry 2s
hold valid 10s
accepted_payload_size 8192
frontend stats
mode http
bind :8888
stats enable
stats uri /
stats refresh 15s
frontend test_fe
bind :8085
timeout client 60s
default_backend test_be
backend test_be
balance leastconn
server-template srv 7 <service-name>.<your namespace>.svc.cluster.local:6311 check resolvers test_resolver
重要的是要了解我们如何配置我们的HAProxy在这里服务器模板被用于使用K8s的DNS进行服务发现,您可以使用平衡leastconn来确保使用最少使用的服务器。
最终,HAProxy需要一项服务
apiVersion: v1
kind: Service
metadata:
name: haproxy-service
namespace: dev
spec:
selector:
app: haproxy-headless
ports:
- name: be
protocol: TCP
port: 6311
targetPort: 8085
- name: mngmnt
protocol: TCP
port: 8888
targetPort: 8888
type: <Type as per requirement>
现在,只要您想访问应用程序,就可以使用上述服务。也许你可以了解一下如何在k8s中使用HAProxy进行负载平衡,它主要做服务发现负载平衡。
也许yaml中显示的一些配置不正确或不匹配,但我希望概念清楚如何实现这一点。