kubernetesのCronJobを触る

kubernetes上で定期的に何か処理を行う場合どうやるのかなと思っていたら、Cron Jobsというものがあるらしい。軽く触ってどんなものか見てみた。

なお、使用したminikubeとkubernetesのバージョンは以下の通り。

$ minikube version
minikube version: v0.15.0
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"08e099554f3c31f6e6f07b448ab3ed78d0520507", GitTreeState:"clean", BuildDate:"2017-01-12T04:57:25Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.1", GitCommit:"82450d03cb057bab0950214ef122b67c83fb11df", GitTreeState:"clean", BuildDate:"1970-01-01T00:00:00Z", GoVersion:"go1.7.1", Compiler:"gc", Platform:"linux/amd64"}

CronJobのマニフェスト

以下のようにした。イメージはrails.ymlと同じものを使う。argsに、実行するコマンドを指定するようだ。実行タイミングはcron形式なのでなじみがありますね。

apiVersion: batch/v2alpha1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: localhost:5000/r_takaishi/docker-mysql-rails
            args: ["bundle", "exec", "rake", "foo"]
            env:
              - name: RAILS_ENV
                value: development
              - name: MYSQL_HOST
                value: mysql.default.svc.cluster.local
              - name: MYSQL_USER
                value: root
              - name: MYSQL_PASSWORD
                value: passw0rd
          restartPolicy: Never

なお、実行するRakeタスクは追加してイメージを更新しておく。

desc "this is foo"
task :foo => :environment do
    p :foo
end

さて、マニフェストを作成したらCronJobを作る。

$kubectl create -f ./cron.yml
cronjob "hello" created

作成されたことが確認できた。この時点ではジョブは1回も動いていない。

$ kubectl get cronjob
NAME      SCHEDULE      SUSPEND   ACTIVE    LAST-SCHEDULE
hello     */1 * * * *   False     0         <none>

ジョブが動いた!

ジョブが動作するとLAST-SCHEDULEが更新されるようだ。動作中だとACTIVEが1になるのかな。

$ kubectl get cronjob
NAME      SCHEDULE      SUSPEND   ACTIVE    LAST-SCHEDULE
hello     */1 * * * *   False     1         Tue, 07 Feb 2017 22:19:00 +0900

ジョブ一覧を見てみる。成功したようだ。

$ kubectl get job
NAME               DESIRED   SUCCESSFUL   AGE
hello-1486473540   1         1            17s

ジョブ hello-1486473540 の詳細を見る。実際に動作したのはhello-1486473540-cxr0n というポッドの中ということがわかる。

$ kubectl describe job hello-148647354
Name:           hello-1486473540
Namespace:      default
Image(s):       localhost:5000/r_takaishi/docker-mysql-rails
Selector:       controller-uid=00f009f6-ed38-11e6-93b9-080027cb3417
Parallelism:    1
Completions:    1
Start Time:     Tue, 07 Feb 2017 22:19:07 +0900
Labels:         controller-uid=00f009f6-ed38-11e6-93b9-080027cb3417
                job-name=hello-1486473540
Pods Statuses:  0 Running / 1 Succeeded / 0 Failed
No volumes.
Events:
  FirstSeen     LastSeen        Count   From                    SubObjectPath   Type            Reason                  Message
  ---------     --------        -----   ----                    -------------   --------        ------                  -------
  34s           34s             1       {job-controller }                       Normal          SuccessfulCreate        Created pod: hello-1486473540-cxr0n

ポッドのログを見ると、Rakeに追加したタスクが実行されていることが確認できた!

$ kubectl logs hello-1486473540-cxr0n
:foo

yamlでマニフェストを書けば後はk8sにまかせられるという感じで、楽そうですね。

ところで、しばらく放置してからジョブ一覧を見るとこんな感じに。

$ kubectl get job
NAME               DESIRED   SUCCESSFUL   AGE
hello-1486473540   1         1            7m
hello-1486473600   1         1            6m
hello-1486473660   1         1            5m
hello-1486473720   1         1            4m
hello-1486473780   1         1            3m
hello-1486473840   1         1            2m
hello-1486473900   1         1            1m
hello-1486473960   1         1            34s

ポッドも、-aオプションをつけると完了したものが残っている。

$ kubectl get pod -a
NAME                     READY     STATUS      RESTARTS   AGE
hello-1486473540-cxr0n   0/1       Completed   0          8m
hello-1486473600-t3tls   0/1       Completed   0          7m
hello-1486473660-7m4w9   0/1       Completed   0          6m
hello-1486473720-6hjsc   0/1       Completed   0          5m
hello-1486473780-jq2vn   0/1       Completed   0          4m
hello-1486473840-f26cj   0/1       Completed   0          3m
hello-1486473900-3b5h6   0/1       Completed   0          2m
hello-1486473960-ph0db   0/1       Completed   0          1m
hello-1486474020-f44k3   0/1       Completed   0          50s
mysql-8kd4q              1/1       Running     2          6d
rails-8cnzn              1/1       Running     0          2d

ジョブの種類が増えて、しばらく時間が経過すると見るのが大変そうだと感じた。そのうち変わるのかな−。ある程度前のジョブは消すようにするのがいいのかも。

まとめ

CronJobを軽く触ってみた。ちゃんと動いていて、しかも実行時だけコンテナを起動しているのでFaaSっぽい雰囲気。ただ、ハンドリングに慣れないうちは中でcrondを動かすコンテナを常時起動しておき、今まで通りのcronで定期実行する方法も併用してもいいのかも。

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *