- 作者: Marko Luksa
- 出版社/メーカー: Manning Pubns Co
- 発売日: 2018/01/20
- メディア: ペーパーバック
- この商品を含むブログを見る
「Kubernetes in Action」を読んで学んだ結果を社内で共有しました。 その第5回の内容です。
node affinity, pod affinity
Kubernetesのnode affinity, pod affinityについて
Summry
- もしnodeにtaintsをセットすると、podがそのtaintsを許容できるtolerationsをセットしていない限りそのnodeにそのpodはscheduleされない。
- taintsは3タイプあり、NoScheduleは完璧にscheduleされない。 PreferNoScheduleはそこまで厳密ではない。NoExecuteはnode上の実行中のpodであっても追い出す。
- NoExecute taintは、nodeがunreachableやunready状態になった場合podがどのくらいの時間schedulingされるのを待つか指定できる。
- Node affinityはどのnodeにpodがscheduleされるべきか指定できる。
- Pod affinityは同じaffinity ruleをもったpodが実行されているnodeにpodをscheduleすることができる
- Pod anti-affinity はお互いのpodを避けさせることができる
Init containers
Init containersを使うと、Pod内のコンテナを起動する前に特定の順番で特定の処理を行うことができる。
https://qiita.com/tkusumi/items/f64fff37a724b86d9819#init-containers-alpha
Pod内で初期化処理をするコンテナを指定をできる機能です。Podの定義にinitContainersという項目で、従来のcontainersで指定したコンテナの前に起動するコンテナを指定できるようになるようです。複数のコンテナを指定することができますが、containersがパラレルに起動されるのに対してinitContainersは指定した順番に1つずつ起動していくようです。
使用用途としては例えば以下のようなものが挙げられます。
- データを動的にダウンロードしてくる
- データベーススキーマの反映
- アプリケーションが何らかの事前条件を満たすまでウェイトする
Init containersを使えば事前条件が満たされるまでpodのmainコンテナが起動するのを遅らせることができます。 readiness probesを設定するのを忘れてはいけません。 アプリケーションがまだ準備段階ではない場合にserviceにpodが追加されるのを防ぐことができますし、 Deployment controllerが、bad versionをrolloutするのを防ぐためにも使用されます。
もしInit Containerの実行がエラーになった場合、KubernetesはInit Containerの実行が成功するまでpodを再起動します。
しかしもしrestartPolicy
がNever
に設定していたなら再起動しません。
例:
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] - name: init-mydb image: busybox command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
参考: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
lifecycle hooks
podのlifecycleに以下の2つのhookを定義することができる。これらをlifecycle hooksと呼ぶ。
- Post-start hooks
- Pre-stop hooks
pod全体に設定するinit containersと違って、lifecycle hooksはpodのコンテナごとに設定できる。 lifecycle hooksはcontainerがstartするときとstopするときに実行される。
lifecycle hooksは、以下の点でlivenes、 readiness probesと似ている。
- containerの内部で実行されるコマンド
- URLに対してHTTP GET Requestとして実行される
Post-start hooks
Post-start hookはコンテナのmain processが実行された後すぐに実行される。
もしコンテナのアプリケーションとは別のアプリケーションを動かしたい場合、あなたがそのアプリケーションの開発者ならアプリケーション内で別のアプリケーションを動かすことができるが、アプリケーションの開発者ではない場合、post-start hookは役に立つ。
Post-start hookはmain processと平行して実行されるが、以下の点でcontainerに影響を与える
まずPost-start hookの実行が完了するまで、containerのstate
はWaiting
のままでありreason
はContainerCreating
のまま。そのためpodのstatusはRunningではなくPendingのまま。
もしPost-start hookが実行に失敗したりnon-zero exit statusを返した場合、main containerはkillされる。
以下が定義例。
apiVersion: v1 kind: Pod metadata: name: pod-with-poststart-hook spec: containers: - image: luksa/kubia name: kubia lifecycle: postStart: exec command: - sh - -c - "echo 'hook will fail with exit code 15'; sleep 5; exit 15"
hookによって開始されたprocessが標準出力に出力してもそれをみるすべはない。そのため永続的volumeに書き込むこと。
Pre-stop hooks
Pre-stop hooksはコンテナが終了する前にすぐに呼び出される。つまりコンテナが終了するのをブロッキングする。 なのでコンテナを削除する呼び出しが送られる前にPre-stop hooksは終了しなければならない。 またPre-stop hooksには何のパラメーターも渡されない。 Podの終了時の振る舞いの詳細はTermination of Podsを参照すること。
Pre-stop hooksの実行タイミング等は以下の記事がとても詳しいです。 Kubernetes: 詳解 Pods の終了
以下が定義例。コンテナが終了する前に http://POD_IP:8080/shutdown へリクエストが送信される。
apiVersion: v1 kind: Pod metadata: name: pre-stop-hook-httpget-pod spec: containers: - image: luksa/kubia name: kubia lifecycle: preStop: httpGet: port: 8080 path: shutdown
また以下のように定義すると、shellコマンドが実行される。
apiVersion: v1 kind: Pod metadata: name: pre-stop-hook-shell-pod spec: containers: - image: luksa/kubia name: kubia lifecycle: preStop: exec: command: ["sh", "-c", "sleep 1; nginx -s quit; sleep 5"]
参考: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/