k8s での Pod のスケジューリングについて確認した時のメモ。
長くなりそうなのでまずは nodeSelector まで
時間があれば続きの内容を書くかもしれないし、書かないかもしれない...
概要
- スケジューリングでは Affinity と Anti-Affinity という考え方を利用する。Affinity では特定条件に一致する所にスケジューリングする。Anti-Affinity では特定の条件に一致しない所にスケジューリングする
- Pod のスケジューリング方法として大きく分けて以下の5つがある
- nodeSelecter(Simplest Node Affinity)->簡易的な Node Affinity この記事の範囲
- Node Affinity->特定のノード上だけで実行する
- Node Anti-Affinity->特定のノード以外で実行する
- Inter-Pod Affinity->特定の Pod がいるドメイン(ノード、ゾーン etc)上で実行する
- Inter-Pod Anti-Affinity->特定の Pod がいないドメイン(ノード、ゾーン etc)上で実行する
参考
検証環境
- eksctl を利用して作成した k8s 環境を利用
-
kubectl
はk
として alias を設定済みの環境 - 環境情報は以下の通り
$k version
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.5", GitCommit:"20c265fef0741dd71a66480e35bd69f18351daea", GitTreeState:"clean", BuildDate:"2019-10-15T19:16:51Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"14+", GitVersion:"v1.14.9-eks-f459c0", GitCommit:"f459c0672169dd35e77af56c24556530a05e9ab1", GitTreeState:"clean", BuildDate:"2020-03-18T04:24:17Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"linux/amd64"}
ラベルについて
Node には ラベル を付与することでスケジューリングの際に利用する事が出来る。大きく分けて以下の2種類のラベルがある(ラベルという意味では同じ)
- ビルトインラベル->利用者が意識せず、自動的に付与されるラベル
- ラベル->利用者が意図して付与するラベル
ビルトインラベル
以下にいくつかの例の記載があるが OS や zone などの情報がある。
実際に eksctl
より作った環境で付与されたラベルを確認してみる。
$k get nodes -o json|jq ".items[]|.metadata.labels"
{
"alpha.eksctl.io/cluster-name": "test-cluster",
"alpha.eksctl.io/instance-id": "i-0b26392bc266a5999",
"alpha.eksctl.io/nodegroup-name": "standard-workers",
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/instance-type": "t3.medium",
"beta.kubernetes.io/os": "linux",
"failure-domain.beta.kubernetes.io/region": "ap-northeast-1",
"failure-domain.beta.kubernetes.io/zone": "ap-northeast-1c",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "ip-192-168-44-10.ap-northeast-1.compute.internal",
"kubernetes.io/os": "linux"
}
{
"alpha.eksctl.io/cluster-name": "test-cluster",
"alpha.eksctl.io/instance-id": "i-02b72bf1fd5120455",
"alpha.eksctl.io/nodegroup-name": "standard-workers",
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/instance-type": "t3.medium",
"beta.kubernetes.io/os": "linux",
"failure-domain.beta.kubernetes.io/region": "ap-northeast-1",
"failure-domain.beta.kubernetes.io/zone": "ap-northeast-1d",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "ip-192-168-65-145.ap-northeast-1.compute.internal",
"kubernetes.io/os": "linux"
}
ラベル
利用者が手動で Node にラベルを付与することも出来る。
具体的には kubectl label nodes <node-name> <label-key>=<label-value>
という形式で任意のラベルの付与が可能
試しにやってみる。
# Node 名を確認
$k get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-44-10.ap-northeast-1.compute.internal Ready <none> 7m34s v1.14.9-eks-1f0ca9
ip-192-168-65-145.ap-northeast-1.compute.internal Ready <none> 7m32s v1.14.9-eks-1f0ca9
# ラベルを付与
$k label nodes ip-192-168-44-10.ap-northeast-1.compute.internal disktype=ssd
node/ip-192-168-44-10.ap-northeast-1.compute.internal labeled
# ラベルが付与された Node のみ表示
$ k get nodes -l disktype=ssd
NAME STATUS ROLES AGE VERSION
ip-192-168-44-10.ap-northeast-1.compute.internal Ready <none> 16m v1.14.9-eks-1f0ca9
なお、実際には Node 起動時にラベルを付与したいというユースケースも多いと思う。
その場合、kubelet
の --node-labels
で付与出来る(未検証)
--node-labels mapStringString
Labels to add when registering the node in the cluster. Labels must be key=value pairs separated by ','. Labels in the 'kubernetes.io' namespace must begin with an allowed prefix (kubelet.kubernetes.io, node.kubernetes.io) or be in the specifically allowed set (beta.kubernetes.io/arch, beta.kubernetes.io/instance-type, beta.kubernetes.io/os, failure-domain.beta.kubernetes.io/region, failure-domain.beta.kubernetes.io/zone, failure-domain.kubernetes.io/region, failure-domain.kubernetes.io/zone, kubernetes.io/arch, kubernetes.io/hostname, kubernetes.io/instance-type, kubernetes.io/os)
nodeSelecter(Simplest Node Affinity)
以下にも記載があるように最もシンプルならスケジューリングが nodeSelector
となる。
nodeSelectorは、Nodeを選択するための、最も簡単で推奨されている手法です。
先程付与したラベル(disktype = ssd)を利用してこのラベルが付与した Node に Pod を起動する。
上記を実現するために Pod の YAML では nodeSelector
を記載する。
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
# Pod を起動
$k apply -f pod-nginx.yaml
pod/nginx created
# disktype = ssd をラベルで設定した Node に起動した
$k describe pods |grep Node
Node: ip-192-168-44-10.ap-northeast-1.compute.internal/192.168.44.10
Node-Selectors: disktype=ssd
想定した Node に Pod を配置する事が出来た