🕌

KubernetesのCronJobでDockerイメージを実行してみる

2021/04/26に公開

kubernetesにあるCronJobというワークロードを試してみました。
下の資料ではshでecho commandを実行するといった内容でしたが、今回はGoのhello worldをDocker buildして実行する形にしてみたいと思います。

https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/

前提

  • kubectlが使える状態
  • Go1.16
  • Docker for Macが入っている

手順

minikubeのインストール

今回はローカルで実行するためminikubeをインストールします。(GKE等を利用する場合はすっ飛ばします)

brew install minikube
minikube start

kubectl config get-contexts 

# minikubeからdocker使える様にする
eval $(minikube docker-env)

docker image 作成

docker build -t hello . -f Dockerfile

# 動作確認
docker run hello

CronJobの作成

CronJobの作成

kubectl apply -f cronjob.yaml

以下動作確認

kubectl get CronJob              
NAME        SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
simplejob   */5 * * * *   False     0        <none>          4s
kubectl get pods
NAME                         READY   STATUS      RESTARTS   AGE
simplejob-1618986720-tw2j5   0/1     Completed   0          44s

completedになっていればおk

kubectl logs simplejob-1618986720-tw2j5
...

期待通りの結果かどうかを確認(この結果は前述の docker run ... と同じ結果になる)

必要に応じて掃除

kubectl delete CronJob simplejob
minikube stop

Code

$ tree
.
├── Dockerfile
├── cronjob.yaml
└── hello.go

Dockerfile

FROM golang:1.16-alpine
RUN mkdir /app
ADD . /app/
WORKDIR /app

RUN GOOS=linux CGO_ENABLED=0 go build -ldflags "-s -w" -o main .
CMD ["./main"]

hello.go

package main

import (
	"fmt"
)

func main() {
	fmt.Println("start job")
	fmt.Println("hello world")
	fmt.Println("finish job")
}

cronjob.yaml

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: hello:latest
            imagePullPolicy: IfNotPresent
          restartPolicy: OnFailure
  schedule: '*/5 * * * *'

雑感

CronJobでgoのバイナリを気軽に実行できるのは結構よいものの、job(=task)間に依存関係性があるならDAGを利用したワークフローエンジンを利用した方が良さげ。

Discussion