YAML書いてみる
なんだかんだで一度もリソースを手で書いたことが無いので, 自分でつくってみる.
やったことのまとめ
- 任意のコマンドが実行できる
Docker image
を作成してKubernetes
のJob
を実行してみた
Jobとは
- 使い切りの
Pod
を実行し, 設定した回数ぶん終了したら完了となるリソースPod
が処理を行った後停止することが前提Pod
を監視し, 正常終了の回数が設定値を満たすまで再起動等の処理を行う- 一回の処理を確実に行いたい場合やバッチ的な処理に向いている
参考 : https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
やったこと
Docker imageの作成
まずはDocker image
をつくる.Dockerfile
の書き方はだいたいわかっているつもり…
下記のDockerfile
を適当なディレクトリで作成する.
特に何かの処理をするわけではなく, ただ alpine のimageをベースにして適当な環境変数等を設定しただけ.ENTRYPOINT
に /bin/sh を指定することで引数で任意のコマンドを渡せるようにする.
Dockerfile
# ベースイメージはalpine
FROM alpine:3.10.3
# 管理者の名前
MAINTAINER uzimihsr-01
# ディレクトリを変更
WORKDIR /uzimihsr/workdir
# 環境変数を設定
ENV AUTHOR uzimihsr
ENV NUMBER 777
# エントリーポイントはsh
ENTRYPOINT ["/bin/sh"]
# デフォルトでは環境変数AUTHORを表示する
CMD ["-c", "echo ${AUTHOR}"]
image
をビルドしてDocker Hubにアップロードする.
# Dockerfileがあるところで作業
$ cd path/to/Dockerfile
$ ls
Dockerfile
# uzimihsr(Docker HubのID)とrepository, tagを指定してビルド
$ docker image build -t uzimihsr/uzimihsr-sample-image:0.1 .
Sending build context to Docker daemon 58.37kB
Step 1/7 : FROM alpine:3.10.3
---> 965ea09ff2eb
Step 2/7 : MAINTAINER uzimihsr-01
---> Using cache
---> be67ea5322ce
Step 3/7 : WORKDIR /uzimihsr/workdir
---> Using cache
---> d953d022ec9e
Step 4/7 : ENV AUTHOR uzimihsr
---> Using cache
---> f2e3624824fd
Step 5/7 : ENV NUMBER 777
---> Using cache
---> c5ccb27bba82
Step 6/7 : ENTRYPOINT ["/bin/sh"]
---> Using cache
---> 42d33fa1c9ab
Step 7/7 : CMD ["-c", "echo ${AUTHOR}"]
---> Using cache
---> ec0ff7287ea6
Successfully built ec0ff7287ea6
Successfully tagged uzimihsr/uzimihsr-sample-image:0.1
# imageをDocker Hubにpush
$ docker image push uzimihsr/uzimihsr-sample-image:0.1
The push refers to repository [docker.io/uzimihsr/uzimihsr-sample-image]
47cb607f05a0: Pushed
77cae8ab23bf: Mounted from library/alpine
0.1: digest: sha256:eab7f925c7b33c5604196d30a9daa3e2d9c763166543069b8f31676a74003702 size: 735
https://hub.docker.com/r/uzimihsr/uzimihsr-sample-image
試しにローカルにある uzimihsr/uzimihsr-sample-image:0.1 を削除した状態でコンテナを実行してみる.
# Docker Hubにあるimageを指定してコンテナを実行
# Dockerfileで指定した通り$AUTHORが表示される
$ docker container run uzimihsr/uzimihsr-sample-image:0.1
Unable to find image 'uzimihsr/uzimihsr-sample-image:0.1' locally
0.1: Pulling from uzimihsr/uzimihsr-sample-image
Digest: sha256:eab7f925c7b33c5604196d30a9daa3e2d9c763166543069b8f31676a74003702
Status: Downloaded newer image for uzimihsr/uzimihsr-sample-image:0.1
uzimihsr
動作確認はOK.
マニフェストファイルの作成
いよいよYAML
を書いていく.
基本的にはapiVersion
, kind
, metadata
, spec
の項目を埋めていけばいいはず.
apiVersion
: このマニフェストを読むKubernetes API
のバージョンを指定- 今回は
Job
を使うのでbatch/v1
を指定する - https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.16/#job-v1-batch
- 今回は
kind
: 今回定義するリソースの種類Job
を定義する
metadata
: リソースを識別するためのメタ情報spec
: このリソースのパラメータや設定
job.yaml
apiVersion: batch/v1 # APIのバージョン
kind: Job # リソースの種類
metadata: # メタ情報
name: uzimihsr-echo-number # リソース名
spec: # Jobの定義
template: # Pod情報
spec: # Jobで作成されるPodの定義
containers: # Podに含まれるコンテナ
- name: echo-number # コンテナ名
image: uzimihsr/uzimihsr-sample-image:0.1 # 使用するimage
args: ["-c", "echo ${NUMBER}"] # imageのCMDを上書きする
restartPolicy: Never # Podが失敗した場合の挙動
backoffLimit: 1 # 再トライ回数の制限
ちょっとコメントを多めに入れたのでごちゃごちゃしているが, やっていることは非常にシンプル.spec
にはJob
で実行されるPod
内のコンテナとその設定を書いている.
今回は先程作ったimage
の実行時引数をargs
で指定するとDockerfile
で指定したCMD
を上書きしてくれるので,image
が持つ環境変数 NUMBER を表示するように指定している.Job
ではPod
失敗時の挙動を指定するrestartPolicy
にNever
(新しいPod
を作成)かOnFailure
(Node
にPod
を残したままコンテナを再実行)が指定できるが, Never
にしておくのが無難そう.
Jobの実行
いよいよマニフェストを実行する.kubectl
でリソースを作成して, その後の挙動を確認する.
# リソースの作成
$ kubectl apply -f job.yaml
job.batch/uzimihsr-echo-number created
# Jobの一覧を確認
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
uzimihsr-echo-number 1/1 5s 5s
# Podの一覧を確認
# JobによってPodが起動している
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
uzimihsr-echo-number-vpbg7 0/1 Completed 0 14s
# Podのログを確認
# imageの元々の挙動ではなくJobで定義した処理が実行されている
$ kubectl logs uzimihsr-echo-number-vpbg7
777
# Podが作成された際のeventを確認
$ kubectl get events
LAST SEEN TYPE REASON OBJECT MESSAGE
<unknown> Normal Scheduled pod/uzimihsr-echo-number-vpbg7 Successfully assigned default/uzimihsr-echo-number-vpbg7 to minikube
3m Normal Pulled pod/uzimihsr-echo-number-vpbg7 Container image "uzimihsr/uzimihsr-sample-image:0.1" already present on machine
3m Normal Created pod/uzimihsr-echo-number-vpbg7 Created container echo-number
3m Normal Started pod/uzimihsr-echo-number-vpbg7 Started container echo-number
3m1s Normal SuccessfulCreate job/uzimihsr-echo-number Created pod: uzimihsr-echo-number-vpbg7
# Jobの情報を確認
# Job定義の他, Podのステータス監視情報などが表示される
$ kubectl describe job uzimihsr-echo-number
Name: uzimihsr-echo-number
Namespace: default
Selector: controller-uid=77d09e29-33f9-4175-a8e4-7b903ee44a9c
Labels: controller-uid=77d09e29-33f9-4175-a8e4-7b903ee44a9c
job-name=uzimihsr-echo-number
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"uzimihsr-echo-number","namespace":"default"},"spec":{"backoffLimit":1,"templ..."
Parallelism: 1
Completions: 1
Start Time: Sun, 15 Dec 2019 20:29:29 +0900
Pods Statuses: 0 Running / 1 Succeeded / 0 Failed
Pod Template:
Labels: controller-uid=77d09e29-33f9-4175-a8e4-7b903ee44a9c
job-name=uzimihsr-echo-number
Containers:
echo-number:
Image: uzimihsr/uzimihsr-sample-image:0.1
Port: <none>
Host Port: <none>
Args:
-c
echo ${NUMBER}
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 3m job-controller Created pod: uzimihsr-echo-number-vpbg7
# Podの情報を確認
$ kubectl describe pod uzimihsr-echo-number-vpbg7
Name: uzimihsr-echo-number-vpbg7
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/192.168.99.110
Start Time: Sun, 15 Dec 2019 20:29:29 +0900
Labels: controller-uid=77d09e29-33f9-4175-a8e4-7b903ee44a9c
job-name=uzimihsr-echo-number
Annotations: <none>
Status: Succeeded
IP: 172.17.0.6
Controlled By: Job/uzimihsr-echo-number
Containers:
echo-number:
Container ID: docker://d3cb3192f650cb916995ad25d533fb4f9edcd42a800cbf41bf2bbc0221ef204c
Image: uzimihsr/uzimihsr-sample-image:0.1
Image ID: docker-pullable://uzimihsr/uzimihsr-sample-image@sha256:eab7f925c7b33c5604196d30a9daa3e2d9c763166543069b8f31676a74003702
Port: <none>
Host Port: <none>
Args:
-c
echo ${NUMBER}
State: Terminated
Reason: Completed
Exit Code: 0
Started: Sun, 15 Dec 2019 20:29:30 +0900
Finished: Sun, 15 Dec 2019 20:29:30 +0900
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-smq54 (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-smq54:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-smq54
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/uzimihsr-echo-number-vpbg7 to minikube
Normal Pulled 10m kubelet, minikube Container image "uzimihsr/uzimihsr-sample-image:0.1" already present on machine
Normal Created 10m kubelet, minikube Created container echo-number
Normal Started 10m kubelet, minikube Started container echo-number
できた.event
の順番を見るとJob
が作成された際の各コンポーネントの動きが推測できておもしろい.
多分以下の流れ.
kubectl
から指示を受けたkube-apiserver
がJob
の情報をetcd
に書き込みkube-controller-manager
にJob
のController
が作成されるJob
のController
がkube-apiserver
に指示を出してPod
の情報をetcd
に書き込みkube-scheduler
によってPod
がNode
に割り当てられるNode
のDocker
がPod
に使うimage
を探してコンテナを作成+起動, これをkubelet
が報告Pod
が作成されたことをJob
のController
が検知
Pod
が完了したときにそれを示すevent
が作成されないのはなんでだろう…
たぶん意図があるはずなのでそのうち調べたい.
おわり
Kubernetes
のマニフェストを初めて手書きして実行までやってみた.
やっぱり先にコンポーネントの役割を理解しておいたほうがクラスタ全体の挙動がなんとなくわかって良い気がする.
(間違ってたらかなしい)