kubenetes的cronjob的定时任务

avatar 2021年9月18日18:01:54 评论 434 次浏览

在kubenetes中,如果对于pod的伸缩,我们可以做到根据cpu或者内存设置一个阀值,如果超过就会自动增加容器,也可以考虑到突然增加并发的情况下,做定时伸缩,比如:一个app,平时的流量比较低,只有在晚上七点,八点,9点,十点的时候流量是平时的四五倍,这种突然增加的流量会导致伸缩不及时服务出现不可用的问题,我们可以使用cronhpa做定时伸缩。那如果是定时任务怎办,在kubenetes中也有定时任务的功能就是cronjob,在调度方面和我们在linux中使用的crontab一样,下面看一下cronjob的模版。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: {{ SVC_NAME }}          #定时任务名称
  namespace: {{ SVC_NS }}       #命名空间名称
  labels:
    app: {{ SVC_NAME }}         #定时任务的标签名称,这里用的是pod名称
    release: {{ SVC_ENV }}      #标签,这里用的是环境变量
spec:
  # 强烈建议设置并发策略,根据调度周期和任务特性进行设置
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 1 #保留成功完成工作的job,默认是3个
  failedJobsHistoryLimit: 2     #保留失败的job,默认是1个 
  startingDeadlineSeconds: 600
  schedule: {{ SVC_CRON }}      #注意,这里是调度时间,如果通过变量传参,需要加双引号
  jobTemplate:
    metadata:
      labels:
        app: {{ SVC_NAME }}      #模版标签
    spec:
      completions: 1                       #标识Job结束所需要成功运行的Pod个数,默认为1
      parallelism:  {{ SVC_REPLICAS }}     #标识并行运行的Pod个数,默认为1
      activeDeadlineSeconds: 20            #job的运行周期,运行20s后会删除job,不过运行状态会是失败不是job结束
      startingDeadlineSeconds: 30          #job启动周期,错过调度时间为失败,不指定没有期限
      template:
        spec:
          containers:
          - name: {{ SVC_NAME }}
            image: image/{{ SVC_NAME }}-{{ SVC_ENV }}:{{ BUILD_NUMBER }}
            imagePullPolicy: IfNotPresent
            name: {{ SVC_NAME }}
            readinessProbe:        #健康检查,可以不加
              httpGet:
                port: {{ SVC_PORT }}
                path: /actuator/info
              initialDelaySeconds: 30
              periodSeconds: 10
              timeoutSeconds: 30
              failureThreshold: 10
            resources:             #pod的配置
              requests:
                cpu: {{ SVC_CPU }}
                memory: {{ SVC_MEM }}Gi
              limits:
                cpu: {{ SVC_CPU }}
                memory: {{ SVC_MEM }}Gi
            env:
              - name: aliyun_logs_log-{{ SVC_NAME }}
                value: stdout
          nodeSelector:
            node: {{ SVC_NODE }}
          imagePullSecrets:
          - name: reach-{{ SVC_ENV }}-image
          restartPolicy: OnFailure     #重启策略,restartPolicy 仅支持 Never 或 OnFailure   
          suspend: true                #字段也是可选的。如果设置为 true,后续所有执行都将被挂起。它对已经开始执行的 Job 不起作用。默认值为 false
          concurrencyPolicy:Forbid    #如何处理被 Cron Job 创建的 Job 的并发执行,Allow(默认):允许并发运行 Job Forbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个 Replace:取消当前正在运行的 Job,用一个新的来替换

这里主要对单个cronjob的yaml文件内容做了一下注解,使用的时候其实没有必要用那么多功能,下面就把我使用的模版贴出来吧,仅供参考,注意定时任务执行完后服务状态应该是终止状态,如果不终止,服务就会一直运行,这个是在程序里配置的,一定要和开发说明白,如果不终止,就代表服务一直运行。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: {{ SVC_NAME }}
  namespace: {{ SVC_NS }}
  labels:
    app: {{ SVC_NAME }}
    release: {{ SVC_ENV }}
spec:
  # 强烈建议设置并发策略,根据调度周期和任务特性进行设置
  concurrencyPolicy: Forbid
  # 强烈建议设置失败任务数,用于排查任务失败根因,以优化任务
  failedJobsHistoryLimit: 1
  successfulJobsHistoryLimit: 3
  # 强烈建议设置错过调度的计算时间
  startingDeadlineSeconds: 600
  schedule: {{ SVC_CRON }}
  jobTemplate:
    metadata:
      labels:
        app: {{ SVC_NAME }}
    spec:
      parallelism:  {{ SVC_REPLICAS }}
      template:
        spec:
          containers:
          - name: {{ SVC_NAME }}
            image: images/{{ SVC_NAME }}-{{ SVC_ENV }}:{{ BUILD_NUMBER }}
            imagePullPolicy: IfNotPresent
            name: {{ SVC_NAME }}
            readinessProbe:
              httpGet:
                port: {{ SVC_PORT }}
                path: /actuator/info
              initialDelaySeconds: 30
              periodSeconds: 10
              timeoutSeconds: 30
              failureThreshold: 10
            resources:
              requests:
                cpu: {{ SVC_CPU }}
                memory: {{ SVC_MEM }}Gi
              limits:
                cpu: {{ SVC_CPU }}
                memory: {{ SVC_MEM }}Gi
            env:
              - name: aliyun_logs_log-{{ SVC_NAME }}
                value: stdout
          nodeSelector:
            node: {{ SVC_NODE }}
          imagePullSecrets:
          - name: reach-{{ SVC_ENV }}-image
          restartPolicy: OnFailure

我的这个模版是运行后会保留运行成功的信息,主要是为了方便检查定时任务的运行结果,如果不保留可以根据上面的配置项做修改,我这里使用的是默认的,所以没有配置。这种配置也不会产生pod报警,如果服务不终止,在配置里增加服务运行周期,会对整个kubenetes产生报警,虽然没有影响但是也不是太规范了。

扩展知识点:

Cronjob的参数详情

spec.startingDeadlineSeconds: 表示统计错过调度次数(100次)的开始时间,默认从最后一次调度时间开始统计错过调度次数(超
过100不再调度)
spec.concurrencyPolicy: 并发调度策略,可选值:{"Allow":"允许并发","Forbid":"不允许","Replace":"调度覆盖"}.
- Allow: 注意:当设置为Allow时,需要考虑到任务执行时间和调度周期,因为可能上个任务没执行成功,下个任务就到执行时间了,如此下来可能会有很多任务都执行积压,造成资源误使用;
- Replace: 当使用Replace遇到上述情况,后个任务会将前一个任务替换掉,如此以来所有的任务可能都不会完整执行;
- Forbid: 则不允许并发调度,也即就调度一次,下一次调度周期再调度,但是可能由于任务执行过长,导致大部分的任务在每一
次调度时间都完美的错过了,此时startingDeadlineSeconds参数也并没有设置,就可能会出现该任务不会再调度,对应到k8s里的事
件可能是Cannot determine if job needs to be started: too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew
spec.schedule: 调度周期,格式为标准的crontab格式[分 时 日 月 周]
spec.failedJobsHistoryLimit: 历史失败的任务数限制(通常可以保留1-2个,用于查看失败详情,以调整调度策略)
spec.successfulJobsHistoryLimit: 历史成功的任务数限制(可以自己决定保留多少个成功任务)
spec.jobTemplate: 标准的pod运行的模板(容器运行时的相关参数)
spec.suspend: 可选参数,如果设置为true,所有后续的任务都会被暂停执行,该参数不适用于已经运行的任务,默认为False

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: