我使用prometheus适配器https://github.com/DirectXMan12/k8s-prometheus-adapter使用自定义指标设置了Kubernetes Horizontal Pod Autoscaler。普罗米修斯(Prometheus)正在监控Rabbitmq,而我正在监视 rabbitmq_queue_messages 指标。队列中的消息由Pod提取,然后进行一些处理,该过程可能持续数小时。
根据队列中消息的数量进行放大和缩小。
问题: 当广告连播完成处理并确认消息后,该数字将降低。队列中的消息数,这将触发自动缩放器终止容器。如果我有multipe pod执行处理,并且其中一个完成了,如果Im没记错,Kubernetes可以终止仍在处理自己消息的Pod。这是不希望的,因为吊舱正在执行的所有处理都将丢失。
有没有办法解决这个问题,或者有另一种方法可以解决这个问题?
这是Autoscaler配置:
kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2beta1
metadata:
name: sample-app-rabbitmq
namespace: monitoring
spec:
scaleTargetRef:
# you created above
apiVersion: apps/v1
kind: Deployment
name: sample-app
minReplicas: 1
maxReplicas: 10
metrics:
- type: Object
object:
target:
kind: Service
name: rabbitmq-cluster
metricName: rabbitmq_queue_messages_ready
targetValue: 5
答案 0 :(得分:0)
您可以考虑使用 preStop挂钩。
根据文档Container States,Define postStart and preStop handlers:
在容器进入Terminated之前,执行preStop挂钩(如果有)。
因此您可以在部署中使用:
lifecycle:
preStop:
exec:
command: ["your script"]
###
更新:
由于一些研究,我想提供更多信息: 有一个有趣的project:
KEDA允许事件驱动的Kubernetes工作负载进行细粒度的自动缩放(包括从零到零)。 KEDA充当Kubernetes Metrics服务器,允许用户使用专用的Kubernetes自定义资源定义来定义自动缩放规则。 KEDA可以在云和边缘上运行,可以与Kubernetes组件(例如Horizontal Pod Autoscaler)进行本地集成,并且没有外部依赖性。
对于主要问题“ Kubernetes可以终止仍在处理其自身消息的Pod”。
根据文档:
“部署是一个高级概念,可管理副本集,并提供Pod的声明式更新以及许多其他有用的功能”
部署由Replicaset支持。按照此控制器代码,存在功能“ getPodsToDelete”。结合使用“ filteredPods ”可得出结果:“ 这可确保我们尽可能早地删除豆荚。”
因此,作为概念证明:
您可以使用初始化容器创建部署。初始化容器应检查队列中是否有消息,并在出现至少一条消息时退出。这将允许主容器启动,接收和处理该消息。在这种情况下,我们将有两种豆荚-那些处理消息并消耗CPU的豆荚,以及那些处于启动状态的豆荚并等待下一条消息。在这种情况下,当HPA决定减少部署中的副本数时,起始容器将首先被删除。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: complete
name: complete
spec:
replicas: 5
revisionHistoryLimit: 10
selector:
matchLabels:
app: complete
template:
metadata:
creationTimestamp: null
labels:
app: complete
spec:
hostname: c1
containers:
- name: complete
command:
- "bash"
args:
- "-c"
- "wa=$(shuf -i 15-30 -n 1)&& echo $wa && sleep $wa"
image: ubuntu
imagePullPolicy: IfNotPresent
resources: {}
initContainers:
- name: wait-for
image: ubuntu
command: ['bash', '-c', 'sleep 30']
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
希望获得帮助。
答案 1 :(得分:0)
Horizontal Pod Autoscaler不适用于长时间运行的任务,因此不太适合。如果您需要为每条消息产生一个长期运行的处理任务,则可以采用以下两种方法之一:
在两种情况下,请确保还启用了Cluster Autoscaler,以便在当前节点不足以处理负载时自动配置新节点。