LinuCエヴァンジェリスト・Open Source Summit Japan 2022ボランティアリーダーの鯨井貴博@opensourcetechです。
はじめに
今回は、kubernetesにおけるnodeSelectorを使ったPod起動ノートの制御をしてみます。
nodeSelectorとは
仕組みとしてはシンプルで、
ノードに付与されたラベルを指定して、そのノード上にPodを起動するというものです。
https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
nodeSelectorを使ってみる
では、実際にやってみましょう!
まず、ラベルを付与する前のノードの状態を確認。
kubeuser@master01:~/nodeSelector$ kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS master01 Ready control-plane 153d v1.27.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master01,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers= worker01 Ready <none> 153d v1.27.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=worker01,kubernetes.io/os=linux worker02 Ready <none> 153d v1.27.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=worker02,kubernetes.io/os=linux
続いて、worker01にdisktype=ssd・cpu=high、worker02にdisktype=hdd・cpu=lowというラベルを付与します。
※worker01はハイスペック、worker02はロースペックと仮定したもの。
kubeuser@master01:~/nodeSelector$ kubectl label node worker01 disktype=ssd node/worker01 labeled kubeuser@master01:~/nodeSelector$ kubectl label node worker02 disktype=hdd node/worker02 labeled kubeuser@master01:~/nodeSelector$ kubectl label node worker01 cpu=high node/worker01 labeled kubeuser@master01:~/nodeSelector$ kubectl label node worker02 cpu=low node/worker02 labeled kubeuser@master01:~/nodeSelector$ kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS master01 Ready control-plane 153d v1.27.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master01,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers= worker01 Ready <none> 153d v1.27.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,cpu=high,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=worker01,kubernetes.io/os=linux worker02 Ready <none> 153d v1.27.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,cpu=low,disktype=hdd,kubernetes.io/arch=amd64,kubernetes.io/hostname=worker02,kubernetes.io/os=linux
続いて、Podを起動するためのyaml作成。
※disktype: ssdを指定したので、worker01上で起動する想定。
kubeuser@master01:~/nodeSelector$ vi testpod.yaml kubeuser@master01:~/nodeSelector$ cat testpod.yaml apiVersion: v1 kind: Pod metadata: labels: run: testpod name: testpod spec: containers: - image: nginx name: testpod nodeSelector: disktype: ssd dnsPolicy: ClusterFirst restartPolicy: Always
そしてPodのデプロイ(起動)。
想定通り、worker01上で起動しました。
kubeuser@master01:~/nodeSelector$ kubectl apply -f testpod.yaml pod/testpod created kubeuser@master01:~/nodeSelector$ kubectl get pods testpod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES testpod 1/1 Running 0 14s 10.0.5.60 worker01 <none> <none>
nodeSelectorの追加検証
せっかくなので、以下の2パターンについても検証しておきます。
①ちぐはぐ(どのノードか特定出来ない)なラベル指定だとどうなる?
②複数のラベル指定は可能?
まずは①から。
kubeuser@master01:~/nodeSelector$ vi testpod.yaml kubeuser@master01:~/nodeSelector$ cat testpod.yaml apiVersion: v1 kind: Pod metadata: labels: run: testpod name: testpod spec: containers: - image: nginx name: testpod nodeSelector: disktype: ssd cpu: low dnsPolicy: ClusterFirst restartPolicy: Always kubeuser@master01:~/nodeSelector$ kubectl apply -f testpod.yaml pod/testpod created kubeuser@master01:~/nodeSelector$ kubectl get pods testpod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES testpod 0/1 Pending 0 16s <none> <none> <none> <none> kubeuser@master01:~/nodeSelector$ kubectl describe pod testpod Name: testpod Namespace: default Priority: 0 Service Account: default Node: <none> Labels: run=testpod Annotations: <none> Status: Pending IP: IPs: <none> Containers: testpod: Image: nginx Port: <none> Host Port: <none> Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pvjr9 (ro) Conditions: Type Status PodScheduled False Volumes: kube-api-access-pvjr9: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: cpu=low disktype=ssd Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 23s default-scheduler 0/3 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }, 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.. kubeuser@master01:~/nodeSelector$ kubectl get pods testpod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES testpod 0/1 Pending 0 34s <none> <none> <none> <none>
0/3 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }, 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling..(Podを起動出来るノードがないぞ!)って怒られましたw
Podはステータス"Pending"のままです。
続いて②。
kubeuser@master01:~/nodeSelector$ vi testpod.yaml kubeuser@master01:~/nodeSelector$ cat testpod.yaml apiVersion: v1 kind: Pod metadata: labels: run: testpod name: testpod spec: containers: - image: nginx name: testpod nodeSelector: disktype: hdd cpu: low dnsPolicy: ClusterFirst restartPolicy: Always kubeuser@master01:~/nodeSelector$ kubectl apply -f testpod.yaml pod/testpod created kubeuser@master01:~/nodeSelector$ kubectl get pods testpod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES testpod 1/1 Running 0 102s 10.0.30.79 worker02 <none> <none>
こちらは複数ラベルが一致するノード(worker02)で起動されました。
おわりに
kubernetesのノードやPodなど付与したラベルってどういう利用方法があるのって思っていましたが、なかなか便利ですね!
特に規模の大きな商用環境などになると、ラベルの管理が重要になってくるので追加検証の部分が役に立ちそうです。