GKE上にバッチジョブを稼働させる方法

### 記事の目的
* バッチジョブのDockerイメージをビルドする
* GKE上のバッチジョブを稼働させる

### 手順のまとめ
* バッチジョブ作成
* Dockerイメージのビルド
* GCP Container RegistryにDockerイメージをプッシュ
* Container RegistryからGKEにデプロイ

## １．バッチジョブ作成
まずgo言語を使って、簡単なバッチジョブを作成します。

ジョブフォルダの構成

```
simplejob
├── README.md
├── go.mod
├── job
│   ├── handler
│   │   └── simplejob_handler.go
│   └── simplejob.go
├── simplejob.Dockerfile
└── simplejob.deployment.yaml
```

```go:simplejob.go
package main

import (
	"context"
	"log"

	"github.com/itdevsamurai/gke/simplejob/job/handler"
)

func main() {
	log.Println("Job Started.")

	ctx := context.Background()
	handler.SimpleJobHandler{}.Run(ctx)

	log.Println("Job Finished.")
}
```

```go:simplejob_handler.go
package handler

import (
	"context"
	"flag"
	"log"
	"os/exec"
)

type SimpleJobHandler struct {
}

func (j SimpleJobHandler) Run(ctx context.Context) error {
	log.Println("Processing ...")

	runTime := getArguments()
	cmd := exec.Command("sleep", runTime)
	err := cmd.Run()
	if err != nil {
		log.Printf("Error at command: %v", cmd)
		return err
	}

	log.Println("Process completed.")
	return nil
}

func getArguments() string {
	runTime := flag.String("run-time", "", "specify number of seconds to run job")
	flag.Parse()
	return *runTime
}
```

このバッチジョブはインプットパラメータで稼働時間（何秒か）を指定する。

ローカルで稼働させてみる

```
cd path_to_simplejob
go run job/simplejob.go --run-time=5
```
<img width="553" alt="gcp_gke_kubernetes_batch_job_devsamurai_001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535698/aa32f0ca-42b0-63e3-b867-2e00fc032b7c.png">

## ２．Dockerイメージのビルド
Dockerfileを準備

```go:simplejob.Dockerfile
FROM golang:1.12 as build_env

WORKDIR /go/src/github.com/itdevsamurai/gke/simplejob

COPY ./job ./job
COPY go.mod ./

ENV PATH="${PATH}:$GOPATH/bin"
ENV GO111MODULE=on

RUN export GOPROXY="https://proxy.golang.org" && export GO111MODULE=on && CGO_ENABLED=0 go build -o simplejob job/simplejob.go

FROM alpine:latest
WORKDIR /app
COPY --from=build_env /go/src/github.com/itdevsamurai/gke/simplejob /job
```

Dockerイメージをビルドする

```
# ockerを事前に起動する必要は注意
cd path_to_simplejob

# tag名付きDockerイメージをビルド
docker build -t ds-gke-simplejob:lasters -f simplejob.Dockerfile .

# ビルド後の確認
docker images
> REPOSITORY                                    TAG                 IMAGE ID            CREATED             SIZE
> ds-gke-simplejob                              lasters             d7fb8721594f        24 seconds ago      8.02MB
```

## ３．GCP Container RegistryにDockerイメージをプッシュ
前提： GCPとgcloudコマンドを利用経験がある。

```
# k8sコントロールツールをインストール（事前にインストールされたらこのをスキップ）
gcloud components install kubectl
kubectl version

# GKEのクラスタにアクセスするため、credentialsを設定
gcloud container clusters get-credentials --zone asia-northeast1-b ds-gke-small-cluster

# GKEにバッチジョブをデップロイ
kubectl apply -f simplejob.deployment.yaml
```

```
# ログイン、とワーキングProjectを設定
gcloud auth login
gcloud config set project [PROJECT_ID]

# ロカルDockerはGCPにアクセスするため、GCPのcredentialを設定
gcloud auth configure-docker

# ロカルイメージをレポジトリのタグ名を付ける
# docker tag [SOURCE_IMAGE] [HOSTNAME]/[PROJECT-ID]/[IMAGE]:[TAG]
docker images
> REPOSITORY                                    TAG                 IMAGE ID            CREATED             SIZE
> ds-gke-simplejob                              lasters             d7fb8721594f        24 seconds ago      8.02MB

docker tag d7fb8721594f asia.gcr.io/ds-project/ds-gke-simplejob:latest

# タグ名の確認
docker images
> REPOSITORY                                    TAG                 IMAGE ID            CREATED             SIZE
> asia.gcr.io/ds-project/ds-gke-simplejob       latest              d7fb8721594f        3 minutes ago       8.02MB

# DockerイメージをContainer Registryにプッシュ
# docker push [HOSTNAME]/[PROJECT-ID]/[IMAGE]
docker push asia.gcr.io/ds-project/ds-gke-simplewebapp
```

Container Registry上にイメージを確認
<img width="768" alt="gcp_gke_kubernetes_batch_job_devsamurai_002.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535698/4e4cda17-0404-5947-f60d-fcbc9ec14af2.png">


## ４．Container RegistryからGKEにデプロイ

```
# GKEのクラスタを作成
gcloud container clusters create ds-gke-small-cluster \
	--project ds-project \
	--zone asia-northeast1-b \
	--machine-type n1-standard-1 \
	--num-nodes 1 \
	--enable-stackdriver-kubernetes
```

デプロイメント定義ファイルを準備する。
simplejob.deployment.yaml

```
apiVersion: batch/v1
kind: Job
metadata:
  name: ds-gke-simplejob
spec:
  template:
    metadata:
      name: ds-gke-simplejob
    spec:
      containers:
      - name: ds-gke-simplejob-container
        image: asia.gcr.io/ds-project/ds-gke-simplejob
        command: ["/job/simplejob"]
        args: ["--run-time", "10"]
      restartPolicy: Never
```

このデプロイメント定義ファイルは、ds-gke-simplejobのDockerイメージを使って、Kubernetesジョブをデプロイする。インプットパラメータで稼働時間は10秒に指定。

```
# k8sコントロールツールをインストール（事前にインストールされたらこのをスキップ）
gcloud components install kubectl
kubectl version

# GKEのクラスタにアクセスするため、credentialsを設定
gcloud container clusters get-credentials --zone asia-northeast1-b ds-gke-small-cluster

# GKEにバッチジョブをデップロイ
kubectl apply -f simplejob.deployment.yaml
```

デプロイ後、結果確認
<img width="956" alt="gcp_gke_kubernetes_batch_job_devsamurai_003.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535698/c51e629d-bf47-4208-393a-9490fc80cad5.png">

稼働ログの確認
<img width="1090" alt="gcp_gke_kubernetes_batch_job_devsamurai_004.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535698/24fbb869-7af7-8175-aaa5-31ad498d187b.png">

本記事の利用ソースコードはこちら
[https://github.com/dssolutioninc/dss_gke/tree/master/simplejob](https://github.com/dssolutioninc/dss_gke/tree/master/simplejob)

 

今回は簡単なジョブをご紹介致しましたが、実際の条件はその他にもあります。

デプロイ方法について、Cloud buildを利用すると一部の作業をまとめできて楽です。

また、ジョブの複雑なインプットや処理結果のアウトプットはどうやって渡すことができるか？取得することができるか？次の記事でドンドン紹介したいと思ってます。

 

最後まで読んで頂き、どうも有難う御座います!
DSS 橋本