4

我有一个特定的场景,我希望有一个由水平 pod 自动缩放控制的部署。为了在推送新部署时处理 pod 中的数据库迁移,我在这里遵循了 Andrew Lock 的这篇优秀教程。

简而言之,您必须为 Kubernetes定义一个initContainerthat在新 pod 可以运行之前完成一个过程(如运行 db 迁移)。waitsJob

这很好用,但是,我不确定在初始部署后如何处理 HPA,因为如果系统检测到需要Pod在我的节点中添加另一个,initContainer我的部署中定义的需要Job部署和运行,但因为Jobs是一个-off 进程,pod 无法初始化和正常运行(ttlSecondsAfterFinished属性删除了Job反正)。

当我部署我的应用程序时,如何定义initContainer要运行的 an,以便我可以在 a 中推送我的数据库迁移Job,而且还允许 HPA 控制动态添加 aPod而不需要 a initContainer

这是我的deployment样子:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: graphql-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: graphql-pod
  template:
    metadata:
      labels:
        app: graphql-pod
    spec:
      initContainers:
        - name: wait-for-graphql-migration-job
          image: groundnuty/k8s-wait-for:v1.4 # This is an image that waits for a process to complete
          args:
            - job
            - graphql-migration-job # this job is defined next
      containers:
        - name: graphql-container
          image: image(graphql):tag(graphql)

下面Job也部署了

apiVersion: batch/v1
kind: Job
metadata:
  name: graphql-migration-job
spec:
  ttlSecondsAfterFinished: 30
  template:
    spec:
      containers:
      - name: graphql-migration-container
        image: image(graphql):tag(graphql)
        command: ["npm", "run", "migrate:reset"]
      restartPolicy: Never

所以基本上发生的事情是:

  • 我将这两个资源部署到我的节点
  • Job被初始化
  • initContaineron使用名为的图像Pod等待完成Jobgroundnuty/k8s-wait-for:v1.4
  • Job完成
  • initContainer完成
  • Pod初始化
  • (30 TTL 秒后)Job从节点中删除

(大量的交通)

  • HPA 意识到需要另一个 pod
  • initContainer对于 NEW pod 已启动,但由于Job不存在而无法运行
  • ...crashLoopBackOff

希望对处理这种情况的正确方法有任何见解!

4

1 回答 1

4

不幸的是,没有简单的 Kubernetes 功能可以解决您的问题。

我建议扩展您的部署工具/脚本以分离迁移作业和您的部署。在部署过程中,您首先执行迁移作业,然后部署您的部署。如果没有附加作业,HPA 可以很好地扩展您的 pod。

有多种方法可以实现这一目标:

  • 首先有一个 bash 等脚本来执行作业,等待然后更新您的部署
  • 利用 Helm 等更复杂的部署工具,它允许您在工作中添加“预安装挂钩”,以便在部署应用程序时执行它们
于 2021-08-11T08:28:32.683 回答