【问题标题】:Graceful scaledown of stateful apps in KubernetesKubernetes 中有状态应用程序的优雅缩减
【发布时间】:2020-10-27 07:20:33
【问题描述】:

我在 Kubernetes 集群中部署了一个有状态的应用程序。现在的挑战是我如何以优雅的方式缩减集群,以便每个 pod 在终止时(在缩减期间)完成它的待处理任务,然后优雅地关闭。该场景类似于下面解释的场景,但在我的情况下,终止的 pod 将有很少的飞行任务需要处理。

https://medium.com/@marko.luksa/graceful-scaledown-of-stateful-apps-in-kubernetes-2205fc556ba91

我们是否有来自 kubernetes api 的官方功能支持。

Kubernetes version: v1.11.0

Host OS: linux/amd64

CRI version: Docker 1.13.1

更新:

可能的解决方案 - 在执行 statefulset 缩减时,终止 pod(s) 的 preStop 挂钩将向队列发送消息通知,其中包含相应的元数据详细信息。待完成的任务。之后使用 K8 Job 完成任务。如果从 K8 的角度来看同样是推荐的方法,请发表评论。

提前致谢!

问候, 巴鲁

【问题讨论】:

  • 这在StatefulSet documentation 中至少有简短的讨论:pod-n 不会开始终止,直到 pod-n+1 完全停止。到目前为止你有什么,什么没用?
  • 亲爱的大卫,这一点已经理解,我的具体问题是 pod 在终止时如何完成它们的待处理任务。例如:- 使用 3 个副本的 statefulset 集群,而我缩减到 2 个副本,我的 pod-3 在终止时如何确保所有待处理的任务(标记到 pod-3)都已完成。
  • Termination of Pods 是另一个关键文档链接。您的服务获得 SIGTERM 并且(默认情况下)有 30 秒完成;完成待处理的任务并结束进程,或者获得 SIGKILL 并强制终止。
  • preStop 钩子是我尝试过的,但预测终止GracePeriodSeconds 是一个挑战,因为我不知道待处理任务完成所需的确切时间(因为它可能会不时变化)。跨度>

标签: kubernetes kubernetes-pod kubernetes-statefulset


【解决方案1】:

只有在进行中的作业完成后,您的 pod 才会缩小。您可以在部署清单中使用prestop 属性另外配置生命周期,这将优雅地停止您的应用程序。这是要遵循的最佳实践之一。详细解释和语法请参考this。

更新答案

这是我尝试在本地部署并尝试生成负载以提高 cpu 利用率并触发 hpa 的 yaml。

部署.yaml

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: default
  name: whoami
  labels:
    app: whoami
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: containous/whoami
          resources:
            requests:
              cpu: 30m
            limits:
              cpu: 40m
          ports:
            - name: web
              containerPort: 80
          lifecycle:
            preStop:
              exec:
                command:
                  - /bin/sh
                  - echo "Starting Sleep"; date; sleep 600; echo "Pod will be terminated now"
---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: whoami
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: whoami
  minReplicas: 1
  maxReplicas: 3
  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 40
#    - type: Resource
#      resource:
#        name: memory
#        targetAverageUtilization: 10
---
apiVersion: v1
kind: Service
metadata:
  name: whoami-service
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
      name: http
  selector:
    app: whoami

部署 pod 后,执行以下命令将生成负载。

kubectl run -i --tty load-generator --image=busybox /bin/sh

while true; do wget -q -O- http://whoami-service.default.svc.cluster.local; done

创建副本后,我停止了加载,Pod 在 600 秒后终止。这种情况对我有用。我相信这也是 statefulset 的类似情况。希望这会有所帮助。

【讨论】:

  • 亲爱的 Vamshi,我的场景就像......当我缩小到 2 个副本时,我的 3 个副本的 statefulset 集群如何在我的 pod-3 终止时确保所有待处理的任务(已标记到 pod-3) 已完成。 preStop 钩子是我尝试过的,但预测终止GracePeriodSeconds 是一个挑战,因为我不知道待处理任务完成所需的确切时间。
  • 我们可以通过在本地机器上创建一个沙箱来得出结论,在该机器上为您的 pod 分配一个任务,我们可以尝试手动缩减并验证该作业是否正常完成。示例:尝试运行一个休眠 300 秒并将回显消息写入文件的 shell 脚本。如果您需要任何详细信息,请告诉我。
  • 另外,在prestop属性中,如果配置了,我们需要提供service stop命令。现在,这将为您的应用程序提供优先权,以优雅地管理应用程序集群上的作业并停止服务。
  • 所以我们在这里是说,如果 preStop 钩子配置了应用程序/服务停止命令,那么 SIGKILL(强制终止)将不会优先(即使在 terminateGracePeriodSeconds 结束之后)。
  • 对,就是这样理解。当然,为了获得完全的可观察性,我们需要绝对尝试测试场景以绝对确定。
猜你喜欢
  • 2020-07-09
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
  • 1970-01-01
  • 2013-07-21
相关资源
最近更新 更多