Slide 1

Slide 1 text

Kubernetes 上で単発のジョブを実⾏す るkube-job というツールを作った Kubernetes Meetup Tokyo #22 @h3_poteto

Slide 2

Slide 2 text

⾃⼰紹介 Akira Fukushima ( 福島 明) GitHub: h3poteto twitter: h3_poteto 仕事: SRE / LAPRAS Inc. 2

Slide 3

Slide 3 text

Kubernetes 上でcron job を実⾏したい 3

Slide 4

Slide 4 text

ふつうCronJob を使いますよね? 4

Slide 5

Slide 5 text

でもRundeck を使いたい Rundeck OSS のジョブスケジューラ Rundeck プロセスからSSH して任意のインスタンスでジョブを実⾏す る スケジュールの書き⽅はだいたいcron と同じ 失敗時の通知や再実⾏ができる 5

Slide 6

Slide 6 text

Rundeck を使いたい理由 ジョブの成功/ 失敗をSlack に通知したい ジョブの並列実⾏をしたい ログをWebUI 上で⾒られるようにしたい 元々Rundeck を使っていたので移⾏が楽 6

Slide 7

Slide 7 text

Kubernetes のCronJob 失敗時の再実⾏はできる Slack 通知は⾃分で作り込む必要がある ジョブの並列実⾏は⼀応できるが,パラメータを少しずつ変えた ジョブを並列実⾏したりはできない 7

Slide 8

Slide 8 text

Rundeck からKubernetes のJob を実⾏で きればよくね? 8

Slide 9

Slide 9 text

というわけで単発のジョブを実⾏できる CLI ツールを作った https://github.com/h3poteto/kube-job 9

Slide 10

Slide 10 text

やってほしいこと 1. ジョブを同期的に実⾏する 2. pod のログを標準出⼒に出してほしい 3. ジョブの定義⾃体は,予め⽤意したyaml を使って良い(ジョブ定義 に必要なパラメータを全てCLI のパラメータで取るようなことはなし ない) 4. ジョブ定義の⼀部(args )を任意のコマンドで上書きした上でジョブ 実⾏したい 5. Job がFail したらコマンドもFail してほしい 6. 実⾏し終わったらJob/Pod を掃除しておいてほしい 10

Slide 11

Slide 11 text

Job 定義を⽤意しておく # job.yaml apiVersion: batch/v1 kind: Job metadata: name: example-job spec: template: spec: containers: - name: alpine image: alpine:latest args: ["env"] # <= ここをCLI で上書き可能 env: - name: HOGE value: fuga restartPolicy: Never backoffLimit: 2 11

Slide 12

Slide 12 text

kube-job を呼ぶ $ ./kube-job run \ --config=$HOME/.kube/config \ --template-file=./job.yaml \ --container="alpine" \ # <= ログを出したいコンテナを指定する --args="echo fuga" fuga 12

Slide 13

Slide 13 text

ジョブが失敗する場合 $ ./kube-job run \ --config=$HOME/.kube/config \ --template-file=./job.yaml \ --container="alpine" \ --args="hoge" container_linux.go:247: starting container process caused "exec: \"hoge\": executable container_linux.go:247: starting container process caused "exec: \"hoge\": executable container_linux.go:247: starting container process caused "exec: \"hoge\": executable FATA[0046] Job is failed: BackoffLimitExceeded exit status 1 $ echo $? 1 コマンドラインツールもexit 1 する 13

Slide 14

Slide 14 text

中⾝の話 golang で実装している client-go を使う clientcmd.BuildConfigFromFlags すれば $HOME/.kube/config をそのま ま使える kubectl と同じように認証できる job.yaml は yaml.Unmarshal するだけで k8s.io/api/batch/v1.Job にパー スできる あとはArgs を上書きしてJobs.Create するだけ 14

Slide 15

Slide 15 text

ジョブを同期的に実⾏する Job をJobs.Create した後に,ジョブを定期的にポーリングする 数秒置きに Jobs.Get する Status.Active をチェックする これを繰り返し Job が終了した場合 JobCondition に応じてツールを終了させる このときに終了したJob, Pods を削除する 15

Slide 16

Slide 16 text

ログの取得 Job のLabel を元にPods を探す 失敗してBackoff している可能性があるので常にPods を再取得し続 ける GetLogs で k8s.io/client-go/rest.Request が取得できる これをStream するとio.ReadCloser が返る os.Stdout に io.Copy するとログが標準出⼒に出る 16

Slide 17

Slide 17 text

他の細かい機能とか Job 定義はローカルファイルだけでなくURL も指定できる GitHub のprivate repository も指定できる (personal access token が 必要) Job 終了後の削除では,以下の挙動が選べる 成功時のみJob/Pods を削除する 失敗時のみJob/Pods を削除する 成功でも失敗でも関係なくJob/Pods を削除する 17

Slide 18

Slide 18 text

Rundeck で使う もはやRundeck からKubernetes のノードにSSH しても何もできない のでSSH はしない ローカルコマンドでkube-job を叩く 認証情報だけはRundeck のホストに保存しておく必要がある 18

Slide 19

Slide 19 text

副産物 デプロイ時にmigration を流したいような場合に便利 1. migration はコンテナを⼊れ替える前に⾏いたい 異様に重いクエリを流さなきゃいけない場合がある migration が失敗する場合,そこで中断してほしい 2. migration が失敗した場合に,CI/CD の画⾯上にログが出るのは便利 19

Slide 20

Slide 20 text

まとめ client-go 使うとかなり⾃由度⾼く作れる kubectl と同じスキームで認証が通るので楽 ただし依存解決にglide を使う必要はある dep とか最近流⾏りのgo mod は使えない 今の所上書きできるのはargs のみ.そのうち増やすかもしれない 20

Slide 21

Slide 21 text

この⼿のツールは検索するとかなり出てくるの でみんな結構⾃前で作ってる? 21