---
# System prepended metadata

title: K8S lab7(CronJob)
tags: [k8s]

---

---
title: K8S lab7(CronJob)
tags: k8s
---
K8S lab7(CronJob)
===
[TOC]

## What is CronJob
CronJob 是特定的時間點執行某個 [Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/job/)，也就是俗稱的排程。

CronJobs 按時重複執行的 Kubernetes Jobs 。CronJobs 常用來自動執行常規任務，例如進行備份、創建報告、發送電子郵件或清理任務。

## How CronJob

### CronJob 範例
```yaml=
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox:1.28
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

```
`spec`參數說明
- `schedule`
    代表這個 CronJob 要在哪個時間點執行工作，需要符合 [cron](https://en.wikipedia.org/wiki/Cron) 格式
- `jobTemplate`
    代表要做的任務是什麼，裡面的描述就會跟 Pod 的一樣

:::warning
:bulb: 注意: 在GKE中，所有 CronJob 的 `spec.schedule`: 時間都是採用UTC時間
:::

### 建立 CronJob
0. 事前準備
    - 需要準備有一個簡單的 CommandLineRunner 範例，可以從 Gitea 上 pull 最新的程式碼: [spring-boot-docker-example](https://git.webcomm.com.tw/POC/spring-boot-docker-example)
    - 將 CommandLineRunner 包成 image
    - 使用`docker run`進行測試，確認包成 image 後功能正常
    - 將 image 上傳到 [DockerHub](https://hub.docker.com/)

    測試專案：[cronjob](https://git.webcomm.com.tw/POC/spring-boot-docker-example/src/branch/master/cronjob)
    ![](https://hackmd.io/_uploads/HJZgj4lmc.png)


1. 製作 cronJob.yml
    ```yaml=
    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: lab-my-cronjob
    spec:
      schedule: '* * * * *'
      concurrencyPolicy: Forbid
      successfulJobsHistoryLimit: 3
      failedJobsHistoryLimit: 1
      jobTemplate:
        metadata:
          name: lab-my-cronjob
          labels:
            app: lab-my-cronjob
        spec:
          template:
            spec:
              containers:
                - name: lab-my-cronjob
                  image: <docker-hub-id>/cronjob:<version>
                  resources:
                    requests:
                      memory: "600Mi"
                      cpu: "200m"
                    limits:
                      memory: "600Mi"
              restartPolicy: Never
    ```
2. 部屬 CronJob
    ```shell=
    kubectl apply -f <path-to-cronJob-yaml> -n <namepsace-name>
    ```
3. 確認 CronJob
    ```shell=
    kubectl get cronjobs -n <namespace-name> <cronjob-name>
    ```
4. 查看結果
    - GCP 工作負載
        ![](https://hackmd.io/_uploads/rJ0h8XxXq.png)
    - 查看所有 Pod
        ```
        $ kubectl get pods -n my-namespace
        NAME                            READY   STATUS      RESTARTS   AGE
        lab-my-cronjob-27475607-dxsfd   0/1     Completed   0          2m30s
        lab-my-cronjob-27475608-897w7   0/1     Completed   0          90s
        lab-my-cronjob-27475609-vcd2q   0/1     Completed   0          30s
        net-tool                        1/1     Running     0          8d
        ```
        可以發現 CronJob 相關的 Pod STATUS 都是 Completed
    - 查看特定 Pod log
        ```
        $ kubectl logs -n my-namespace lab-my-cronjob-27475609-vcd2q

          .   ____          _            __ _ _
         /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
        ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
         \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
          '  |____| .__|_| |_|_| |_\__, | / / / /
         =========|_|==============|___/=/_/_/_/
         :: Spring Boot ::                (v2.6.5)

        2022-03-29 06:49:02.964  INFO 1 --- [           main] com.webcomm.cronjob.CronjobApplication   : Starting CronjobApplication v2.6.5 using Java 1.8.0_212 on lab-my-cronjob-27475609-vcd2q with PID 1 (/app/cronjob.jar started by root in /app)
        2022-03-29 06:49:02.971  INFO 1 --- [           main] com.webcomm.cronjob.CronjobApplication   : No active profile set, falling back to 1 default profile: "default"
        2022-03-29 06:49:04.182  INFO 1 --- [           main] com.webcomm.cronjob.CronjobApplication   : Started CronjobApplication in 2.157 seconds (JVM running for 2.976)
        2022-03-29 06:49:04.189  INFO 1 --- [           main] com.webcomm.cronjob.runner.JobRunner     : The Runner start ...
        ```


### 失敗情境測試
1. 調整 JobRunner.java
    ```java=
    @Override
    public void run(String... args) throws Exception {
        try {
            logger.info("The Runner start ...");
            throw new Exception("Error!!");
            // System.exit(0);
        } catch (Exception e) {
            logger.error(e.getMessage());
            System.exit(1);
        }
    }
    ```
2. 重新包成 image 後，推到 DockerHub
3. 調整 cronjob.yml ，更新版號
4. 查看結果
    當 CommandLineRunner 執行失敗時，在 GKE 上可以看到
    ![](https://hackmd.io/_uploads/HJrEgUxXc.png)




## 參考資料
- [Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/job/)
- [CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/)
- [GKE-Running a CronJob](https://cloud.google.com/kubernetes-engine/docs/how-to/cronjobs)