Affinityとは
Affinityとは、Podをスケジューリングの条件を設定する機能である。
以下の3種類があるが、このページではNode Affinityについて説明する。
- Node Affinity
- Pod Affinity
- Pod Anti-Affinity
Pod Affinity、Pod Anti-Affinityについては以下を参照。
【KubernetesのAffinity】その2 - Pod Affinity / Pod Anti-Affinityの使い方
似たような機能でTaint / Tolerationというものもある。
KubernetesのTaint / Tolerationの使い方
目次
Node Affinity
PodをどのNodeにスケジューリングするのかを設定できる。
NodeSelectorと似ているが、Node Affinityのほうが柔軟な設定できる。
matchExpressions、matchFieldsの2つの条件設定方法がある。
matchExpressionsの使い方
NodeにLabelをセット
environment=dev
というLabelをセットする。
$ sudo kubectl label node/minikube environment=dev
$ sudo kubectl get node --show-labels
Podを定義
matchExpressionsで、敢えてenvironment=prod
という存在しないLabelを指定する。
apiVersion: v1
kind: Pod
metadata:
name: node-affinity-pod
spec:
containers:
- name: main
image: nginx
affinity:
nodeAffinity:
###################################################
# - requiredDuringSchedulingIgnoredDuringExecution
# - Affinityルールに合致したNodeにのみスケジュールする
# - preferredDuringSchedulingIgnoredDuringExecution
# - Affinityルールに合致したNodeに優先的にスケジュールするが、合致しない場合他のNodeへスケジュールする
# - IgnoredDuringExecutionというのは、実行中のPodには影響しないことを意味する。
###################################################
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
# NodeのLabelに対して集合ベースの比較
- matchExpressions:
- key: environment
operator: In
values:
- prod
apply
$ sudo kubectl apply -f pod.yml
pod/node-affinity-pod created
Podの状態を確認
STATUSがPendingのまま。
$ sudo kubectl get pod
NAME READY STATUS RESTARTS AGE
node-affinity-pod 0/1 Pending 0 13s
マッチするNodeが存在しないというエラーが出ている。
$ sudo kubectl describe pod/node-affinity-pod
# **snip**
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 18s (x2 over 18s) default-scheduler 0/1 nodes are available: 1 node(s) didn't match node selector.
Delete
一旦Podを削除する。
$ sudo kubectl delete -f pod.yml
pod "node-affinity-pod" deleted
Podを修正
matchExpressionsのenvironment
をdev
に修正する。
apiVersion: v1
kind: Pod
metadata:
name: node-affinity-pod
spec:
containers:
- name: main
image: nginx
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: environment
operator: In
values:
- - prod
+ - dev
再度apply
$ sudo kubectl apply -f pod.yml
pod/node-affinity-pod created
再度Podの状態を確認
Runningになった。
$ sudo kubectl get pod
NAME READY STATUS RESTARTS AGE
node-affinity-pod 1/1 Running 0 11s
Podが指定したNodeにスケジューリングされた。
$ sudo kubectl describe pod/node-affinity-pod
# **snip**
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 43s default-scheduler Successfully assigned default/node-affinity-pod to minikube
Normal Pulling 42s kubelet, minikube Pulling image "nginx"
Normal Pulled 36s kubelet, minikube Successfully pulled image "nginx"
Normal Created 36s kubelet, minikube Created container main
Normal Started 35s kubelet, minikube Started container main
matchFieldsの使い方
matchExpressionsと似ているが、こちらはkeyにオブジェクトのフィールド名を指定する。
matchFieldsサポートしているものとしていないオブジェクトがあるので注意。
以下の例では、nodeのNAMEを指定して、Podを関連付ける。
$ sudo kubectl get node
NAME STATUS ROLES AGE VERSION
minikube Ready master 5h2m v1.14.3
nodeのNAMEがminikube
なので、下記の用に、key: metada.name
に対してminikube
を指定する。当然、この値を違うものに変更すると、Podはスケジューリング先を見つけられず、起動しない。
apiVersion: v1
kind: Pod
metadata:
name: node-affinity-pod
spec:
containers:
- name: main
image: nginx
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
# Nodeオブジェクトのフィールドに対して集合ベースの比較
nodeSelectorTerms:
- matchFields:
- key: metadata.name
operator: In
values:
- minikube
Podの状態を確認
Runningになった。
$ sudo kubectl get pod
NAME READY STATUS RESTARTS AGE
node-affinity-pod 1/1 Running 0 6s
$ sudo kubectl describe pod/node-affinity-pod
# **snip**
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 8s default-scheduler Successfully assigned default/node-affinity-pod to minikube
Normal Pulling 7s kubelet, minikube Pulling image "nginx"
Normal Pulled 4s kubelet, minikube Successfully pulled image "nginx"
Normal Created 4s kubelet, minikube Created container main
Normal Started 4s kubelet, minikube Started container main