马盖先 發表於 2023-6-2 16:42:00

Kubernetes(k8s)定时任务:CronJob

<p></p><div class="toc"><div class="toc-container-header">目录</div><ul><li>一.系统环境</li><li>二.前言</li><li>三.Kubernetes CronJob简介</li><li>四.kubernetes CronJob和Linux crontab对比</li><li>五.CronJob表达式语法</li><li>六.创建CronJob定时任务</li><li>七.创建具有超时时间的CronJob定时任务</li><li>八.总结</li></ul></div><p></p>
<h1 id="一系统环境">一.系统环境</h1>
<p>本文主要基于Kubernetes1.21.9和Linux操作系统CentOS7.4。</p>
<table>
<thead>
<tr>
<th>服务器版本</th>
<th>docker软件版本</th>
<th>Kubernetes(k8s)集群版本</th>
<th>CPU架构</th>
</tr>
</thead>
<tbody>
<tr>
<td>CentOS Linux release 7.4.1708 (Core)</td>
<td>Docker version 20.10.12</td>
<td>v1.21.9</td>
<td>x86_64</td>
</tr>
</tbody>
</table>
<p>Kubernetes集群架构:k8scloude1作为master节点,k8scloude2,k8scloude3作为worker节点。</p>
<table>
<thead>
<tr>
<th>服务器</th>
<th>操作系统版本</th>
<th>CPU架构</th>
<th>进程</th>
<th>功能描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>k8scloude1/192.168.110.130</td>
<td>CentOS Linux release 7.4.1708 (Core)</td>
<td>x86_64</td>
<td>docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico</td>
<td>k8s master节点</td>
</tr>
<tr>
<td>k8scloude2/192.168.110.129</td>
<td>CentOS Linux release 7.4.1708 (Core)</td>
<td>x86_64</td>
<td>docker,kubelet,kube-proxy,calico</td>
<td>k8s worker节点</td>
</tr>
<tr>
<td>k8scloude3/192.168.110.128</td>
<td>CentOS Linux release 7.4.1708 (Core)</td>
<td>x86_64</td>
<td>docker,kubelet,kube-proxy,calico</td>
<td>k8s worker节点</td>
</tr>
</tbody>
</table>
<h1 id="二前言">二.前言</h1>
<p>在现代的云原生应用中,定时任务是一个非常重要的组成部分。Kubernetes提供了一种称为CronJob的机制,可以让我们方便地定义和管理定时任务。本文将介绍Kubernetes CronJob的基础知识以及如何使用它来运行定时任务。</p>
<p>使用CronJob定时任务的<strong>前提</strong>是已经有一套可以正常运行的Kubernetes集群,关于Kubernetes(k8s)集群的安装部署,可以查看博客《Centos7 安装部署Kubernetes(k8s)集群》https://www.cnblogs.com/renshengdezheli/p/16686769.html。</p>
<h1 id="三kubernetes-cronjob简介">三.Kubernetes CronJob简介</h1>
<p>CronJob是Kubernetes中的一种控制器(其他控制器,比如deployment,DaemonSet ,ReplicationController,ReplicaSet ),用于在指定时间间隔内运行一个或多个Pod。类似于Linux下的cron工具,可以帮助我们周期性地执行任务。Kubernetes CronJob使用Cron表达式来指定任务运行时间,这使得它非常灵活且易于使用。</p>
<p>除了CronJob定时任务,kubernetes还存在一次性任务job,详情请查看博客《Kubernetes(k8s)一次性任务:Job》https://www.cnblogs.com/renshengdezheli/p/17450685.html。</p>
<h1 id="四kubernetes-cronjob和linux-crontab对比">四.kubernetes CronJob和Linux crontab对比</h1>
<p>熟悉Linux系统的对crontab定时任务应该不陌生,下面看看kubernetes CronJob和Linux crontab两者差异。</p>
<p>Linux 下的 crontab 和 Kubernetes 下的 CronJob 都是用于执行周期性任务的工具,但它们在实现方式和使用方式上有以下几点不同:</p>
<ol>
<li>调度精度:Linux 下的 crontab 支持分钟级别的调度,而 Kubernetes 下的 CronJob 可以支持到秒级别的调度。</li>
<li>状态管理:Linux 下的 crontab 只能通过查看日志等方式来了解任务的运行情况,而 Kubernetes 下的 CronJob 可以通过 kubectl 工具查看任务的运行状态,并且可以对任务进行修改和删除等操作。</li>
<li>并发控制:Linux 下的 crontab 没有内置的并发控制机制,如果同一个任务同时被多次触发,可能会导致资源抢占。而 Kubernetes 下的 CronJob 可以通过 <code>.spec.concurrencyPolicy</code> 字段指定任务的并发策略,从而避免资源抢占的问题。</li>
<li>环境隔离:Linux 下的 crontab 所有任务都运行在同一个环境中,容易出现依赖冲突等问题。而 Kubernetes 下的 CronJob 可以定义多个 Pod 来运行不同的任务,从而实现了任务之间的环境隔离。</li>
<li>缩放性:Linux 下的 crontab 通常只能运行在单台服务器上,无法进行水平扩展。而 Kubernetes 下的 CronJob 可以运行在多节点的集群上,并且可以通过水平扩展来提高任务的并发度和可用性。</li>
</ol>
<p>综上所述,Linux 下的 crontab 和 Kubernetes 下的 CronJob 在功能和使用方式上都有不同,具体使用哪种工具取决于具体的需求和场景。</p>
<h1 id="五cronjob表达式语法">五.CronJob表达式语法</h1>
<p>cronjob类似于Linux 的crontab, cronjob简写为cj,查看cronjob任务。</p>
<pre><code class="language-shell"># kubectl get cj
No resources found in job namespace.

# kubectl get cronjob
No resources found in job namespace.
</code></pre>
<p>查看创建cronjob的帮助</p>
<pre><code class="language-yaml"># kubectl create cj --help
Create a cronjob with the specified name.

Aliases:
cronjob, cj

Examples:
# Create a cronjob
kubectl create cronjob my-job --image=busybox --schedule="*/1 * * * *"

# Create a cronjob with command
kubectl create cronjob my-job --image=busybox --schedule="*/1 * * * *" -- date
......
Usage:
kubectl create cronjob NAME --image=image --schedule='0/5 * * * ?' --

Use "kubectl options" for a list of global command-line options (applies to all commands).
</code></pre>
<p>CronJob表达式由五个字段组成,分别代表分钟、小时、日、月、周几。每个字段可以是以下任何值:</p>
<ul>
<li>单个数字:例如5表示第5分钟或5月份。</li>
<li>逗号分隔的数字列表:例如5,15,25表示第5、15和25分钟。</li>
<li>连续的数字范围:例如10-15表示从第10分钟到第15分钟。</li>
<li>星号(*):表示匹配该字段的所有值。例如在分钟字段上使用星号表示每分钟执行任务。</li>
<li>斜杠(/):表示步长值。例如在分钟字段上使用"*/3"表示每隔3分钟执行一次任务。</li>
</ul>
<p>CronJob表达式示例:</p>
<ul>
<li>每小时执行:0 * * * *</li>
<li>每天晚上10点执行:0 22 * * *</li>
<li>每周一早上6点执行:0 6 * * 1</li>
<li>每2分钟运行一次任务 : */2 * * * *</li>
</ul>
<h1 id="六创建cronjob定时任务">六.创建CronJob定时任务</h1>
<p>生成cronjob的yaml文件,--schedule="*/1 * * * *" 表示每分钟执行一次,执行的命令为:-- sh -c "date;sleep 10"打印当前日期和休眠10秒钟。</p>
<pre><code class="language-yaml"># kubectl create cronjob my-cronjob --image=busybox --schedule="*/1 * * * *" --dry-run=client -o yaml -- sh -c "date;sleep 10" &gt;cronjob.yaml

# cat cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
creationTimestamp: null
name: my-cronjob
spec:
jobTemplate:
    metadata:
      creationTimestamp: null
      name: my-cronjob
    spec:
      template:
      metadata:
          creationTimestamp: null
      spec:
          containers:
          - command:
            - sh
            - -c
            - date;sleep 10
            image: busybox
            name: my-cronjob
            resources: {}
          restartPolicy: OnFailure
schedule: '*/1 * * * *'
status: {}
</code></pre>
<p>修改yaml文件,功能为:创建一个 名为my-cronjob的Kubernetes CronJob定时任务,使用 busybox 镜像作为容器镜像,执行每分钟一次的定时任务,任务是<code>date;sleep 10</code>打印当前日期和休眠10秒钟。</p>
<p>schedule:*/1 * * * *:表示每分钟执行一次作业。</p>
<p>restartPolicy: OnFailure:在容器执行失败时重新启动容器。</p>
<pre><code class="language-yaml"># vim cronjob.yaml

# cat cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
creationTimestamp: null
name: my-cronjob
spec:
jobTemplate:
    metadata:
      creationTimestamp: null
      name: my-cronjob
    spec:
      template:
      metadata:
          creationTimestamp: null
      spec:
          #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
          terminationGracePeriodSeconds: 0
          containers:
          - command:
            - sh
            - -c
            - date;sleep 10
            image: busybox
            #imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像
            imagePullPolicy: IfNotPresent
            name: my-cronjob
            resources: {}
          #restartPolicy: OnFailure:在容器执行失败时重新启动容器。
          restartPolicy: OnFailure
#表示每分钟执行一次作业。      
schedule: '*/1 * * * *'
status: {}
</code></pre>
<p>创建cronjob并查看</p>
<pre><code class="language-shell"># kubectl apply -f cronjob.yaml
cronjob.batch/my-cronjob created

# kubectl get cj
NAME         SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
my-cronjob   */1 * * * *   False   0      &lt;none&gt;          4s

# kubectl get pod
No resources found in job namespace.
</code></pre>
<p>现在开始观察pod状态,使用watch每 0.5 秒执行一次 <code>kubectl get pod</code> 命令,实时查看 Kubernetes 集群中 Pod 的状态信息。可以发现由于sleep 10,所以每个pod运行10秒之后status由running变为Completed。</p>
<pre><code class="language-shell">#每 0.5 秒执行一次 `kubectl get pod` 命令
# watch -n .5 'kubectl get pod'

# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
my-cronjob-27406765-xk2v7   1/1   Running   0          9s

# watch -n .5 'kubectl get pod'

# kubectl get pod

NAME                        READY   STATUS      RESTARTS   AGE
my-cronjob-27406765-xk2v7   0/1   Completed   0          70s
my-cronjob-27406766-7gbjc   1/1   Running   0          10s

# kubectl get pod
NAME                        READY   STATUS      RESTARTS   AGE
my-cronjob-27406765-xk2v7   0/1   Completed   0          76s
my-cronjob-27406766-7gbjc   0/1   Completed   0          16s
</code></pre>
<p>删除cronjob</p>
<pre><code class="language-shell"># kubectl delete cj my-cronjob
cronjob.batch "my-cronjob" deleted

# kubectl get pod
No resources found in job namespace.

# kubectl get cj
No resources found in job namespace.
</code></pre>
<h1 id="七创建具有超时时间的cronjob定时任务">七.创建具有超时时间的CronJob定时任务</h1>
<p>刚才创建的cronjob,每个pod会运行10s(sleep 10),有的pod可能会运行很长时间,我们可以使用activeDeadlineSeconds参数限制pod最多运行多长时间。activeDeadlineSeconds 用于指定 Pod 最大的运行时间。如果一个 Pod 已经运行了超过这个时间,Kubernetes 会强制将其终止删除。</p>
<p>修改yaml文件,添加activeDeadlineSeconds: 5:设置了 Pod 最大运行时间为 5 秒,如果超过这个时间就会被 Kubernetes 强制删除。</p>
<pre><code class="language-yaml"># vim cronjob.yaml

# cat cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
creationTimestamp: null
name: my-cronjob
spec:
jobTemplate:
    metadata:
      creationTimestamp: null
      name: my-cronjob
    spec:
      #activeDeadlineSeconds: 5:设置了 Pod 最大运行时间为 5 秒,如果超过这个时间就会被 Kubernetes 强制删除。
      activeDeadlineSeconds: 5
      template:
      metadata:
          creationTimestamp: null
      spec:
          #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
          terminationGracePeriodSeconds: 0
          containers:
          - command:
            - sh
            - -c
            - date;sleep 10
            image: busybox
            imagePullPolicy: IfNotPresent
            name: my-cronjob
            resources: {}
          #restartPolicy: OnFailure:在容器执行失败时重新启动容器。
          restartPolicy: OnFailure
#表示每分钟执行一次作业。      
schedule: '*/1 * * * *'
status: {}
</code></pre>
<p>创建cronjob</p>
<pre><code class="language-shell"># kubectl apply -f cronjob.yaml
cronjob.batch/my-cronjob created

# kubectl get cj
NAME         SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
my-cronjob   */1 * * * *   False   0      &lt;none&gt;          6s

# kubectl get pod
No resources found in job namespace.
</code></pre>
<p>现在开始观察pod状态,使用watch每 0.5 秒执行一次 <code>kubectl get pod</code> 命令,实时查看 Kubernetes 集群中 Pod 的状态信息。可以发现每一分钟执行一次定时任务“*/1 * * * *” ,sleep 10超过5秒,pod运行5秒之后被强制删除。</p>
<pre><code class="language-shell"># watch -n .5 'kubectl get pod'

# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
my-cronjob-27406771-vskpb   1/1   Running   0          3s

# kubectl get pod
No resources found in job namespace.

# kubectl get pod
No resources found in job namespace.
</code></pre>
<p>删除cronjob</p>
<pre><code class="language-shell"># kubectl delete cj my-cronjob
cronjob.batch "my-cronjob" deleted

# kubectl get cj
No resources found in job namespace.

# kubectl get pod
No resources found in job namespace.

</code></pre>
<h1 id="八总结">八.总结</h1>
<p>本文介绍了Kubernetes CronJob定时任务的语法,如何创建cronjob定时任务,以及创建具有超时时间的cronjob。</p>
<p>Kubernetes CronJob为容器化环境提供了非常便利的任务调度功能,可以帮助我们自动化许多常见的周期性任务。</p>


</div>
<div id="MySignature" role="contentinfo">
    致力于一条龙式的为您解决问题<br><br>
来源:https://www.cnblogs.com/renshengdezheli/p/17452237.html
頁: [1]
查看完整版本: Kubernetes(k8s)定时任务:CronJob