目的
本記事では、Kubernetes Service(IKS)およびOpenShift on IBM Cloud(ROKS)において、NodeAffinityを用いて特定のPodを特定のNodeにスケジューリングする方法を記載する
特に、複数の条件(Nodeのラベルなど)を組み合わせて柔軟に制御したい場合有効となる
比較
項目 | nodeSelector |
nodeAffinity |
---|---|---|
対応条件 | 単一のキーと値 (key=value ) |
複数の条件・演算子 (In , NotIn , Exists など) |
柔軟性 | 低い(完全一致のみ) | 高い(複数条件の組み合わせが可能) |
優先/必須の指定 | 不可(すべて必須) | 必須(required )と優先(preferred )の使い分けが可能 |
用途 | シンプルなNode指定 | 複雑で柔軟なNodeスケジューリングが必要な場合 |
YAMLでの記述 | nodeSelector: { key: value } |
affinity: nodeAffinity: で記述 |
テスト内容
tok-1,tok-2,tok-3にノードがあり、tok-3にだけPODを割り当てたいなどのシンプルな条件はNodeAffinityで実現する。しかし、tok-1とtok-2に特定のPODを割り当てる複数条件を利用したい場合、NodeSelectorではなくNodeAffinityとなる。
今回はtok-1,tok-2,tok-3の3zoneでノードが存在しており、tok-1とtok-2のどちらかにPODを割り当てる条件とする。
1.ワーカープールIDを調べる
% ibmcloud ks worker-pool ls --cluster co9j451t0t7uthsxxxx
OK
名前 ID フレーバー OS ワーカー
lowspec co9j451t0t7uthsxxxx-9476a1e cx2.2x4 UBUNTU_24_64 3
2.ワーカーノードのプライベートIPを調べる
% ibmcloud ks worker ls --cluster co9j451t0t7uthsxxxx --worker-pool co9j451t0t7uthsxxxx-9476a1e
OK
ID プライマリー IP フレーバー 状態 状況 ゾーン バージョン オペレーティング・システム
kube-co9j451t0t7uthsxxxx-acspaasclus-lowspec-00001ac4 10.244.64.11 cx2.2x4 normal Ready jp-tok-2 1.30.7_1549* UBUNTU_24_64
kube-co9j451t0t7uthsxxxx-acspaasclus-lowspec-00001d30 10.244.128.12 cx2.2x4 normal Ready jp-tok-3 1.30.7_1549* UBUNTU_24_64
kube-co9j451t0t7uthsxxxx-acspaasclus-lowspec-00001e31 10.244.0.5 cx2.2x4 normal Ready jp-tok-1 1.30.9_1555 UBUNTU_24_64
3.ワーカー・プール ID ラベルを調べる
% kubectl describe node 10.244.0.5
Name: 10.244.0.5
Roles: <none>
Labels: arch=amd64
beta.kubernetes.io/arch=amd64
beta.kubernetes.io/instance-type=cx2.2x4
beta.kubernetes.io/os=linux
failure-domain.beta.kubernetes.io/region=jp-tok
failure-domain.beta.kubernetes.io/zone=jp-tok-1
ibm-cloud.kubernetes.io/ha-worker=true
ibm-cloud.kubernetes.io/iaas-provider=g2
ibm-cloud.kubernetes.io/instance-id=02e7_1ab84e08-5fb6-4691-aac7-6a3638b033f5
ibm-cloud.kubernetes.io/internal-ip=10.244.0.5
ibm-cloud.kubernetes.io/machine-type=cx2.2x4
ibm-cloud.kubernetes.io/os=UBUNTU_24_64
ibm-cloud.kubernetes.io/region=jp-tok
ibm-cloud.kubernetes.io/sgx-enabled=false
ibm-cloud.kubernetes.io/subnet-id=02e7-2113f672-82c8-4f79-8102-772aaa938c03
ibm-cloud.kubernetes.io/worker-id=kube-co9j451t0t7uthsxxxx-acspaasclus-lowspec-00001e31
ibm-cloud.kubernetes.io/worker-pool-id=co9j451t0t7uthsxxxx-9476a1e
ibm-cloud.kubernetes.io/worker-pool-name=lowspec
ibm-cloud.kubernetes.io/worker-version=1.30.9_1555
ibm-cloud.kubernetes.io/zone=jp-tok-1
kubernetes.io/arch=amd64
kubernetes.io/hostname=10.244.0.5
kubernetes.io/os=linux
node.kubernetes.io/instance-type=cx2.2x4
topology.kubernetes.io/region=jp-tok
topology.kubernetes.io/zone=jp-tok-1
Annotations: node.alpha.kubernetes.io/ttl: 0
projectcalico.org/IPv4Address: 10.244.0.5/24
projectcalico.org/IPv4IPIPTunnelAddr: 172.17.11.192
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Tue, 25 Feb 2025 15:16:00 +0900
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: 10.244.0.5
AcquireTime: <unset>
RenewTime: Tue, 25 Feb 2025 15:17:53 +0900
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
NetworkUnavailable False Tue, 25 Feb 2025 15:16:44 +0900 Tue, 25 Feb 2025 15:16:44 +0900 CalicoIsUp Calico is running on this node
MemoryPressure False Tue, 25 Feb 2025 15:17:32 +0900 Tue, 25 Feb 2025 15:16:00 +0900 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Tue, 25 Feb 2025 15:17:32 +0900 Tue, 25 Feb 2025 15:16:00 +0900 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Tue, 25 Feb 2025 15:17:32 +0900 Tue, 25 Feb 2025 15:16:00 +0900 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Tue, 25 Feb 2025 15:17:32 +0900 Tue, 25 Feb 2025 15:16:22 +0900 KubeletReady kubelet is posting ready status
Addresses:
InternalIP: 10.244.0.5
ExternalIP: 10.244.0.5
Capacity:
cpu: 2
ephemeral-storage: 101986876Ki
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 3485716Ki
pods: 110
Allocatable:
cpu: 1920m
ephemeral-storage: 93468932039
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 2511892Ki
pods: 110
System Info:
Machine ID: 1ab84e085fb64691aac76a3638b033f5
System UUID: 1ab84e08-5fb6-4691-aac7-6a3638b033f5
Boot ID: b4bc125e-9873-457a-985f-42201b77528e
Kernel Version: 6.8.0-52-generic
OS Image: Ubuntu 24.04.1 LTS
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.7.25
Kubelet Version: v1.30.9+IKS
Kube-Proxy Version: v1.30.9+IKS
ProviderID: ibm://db415c559c0e468cb9414edb82aee6fe///co9j451t0t7uthsxxxx/kube-co9j451t0t7uthsxxxx-acspaasclus-lowspec-00001e31
Non-terminated Pods: (13 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
calico-system calico-node-bz9vg 80m (4%) 0 (0%) 145Mi (5%) 0 (0%) 116s
default shell-daemonset-6lgwn 0 (0%) 0 (0%) 0 (0%) 0 (0%) 72s
ibm-object-s3fs ibmcloud-object-storage-driver-qqhgh 100m (5%) 500m (26%) 128Mi (5%) 500Mi (20%) 116s
ibm-observe sysdig-agent-node-analyzer-crlxr 450m (23%) 1500m (78%) 1152Mi (46%) 3328Mi (135%) 94s
kube-system ibm-master-proxy-static-10.244.0.5 25m (1%) 300m (15%) 32M (1%) 512M (19%) 115s
kube-system ibm-vpc-block-csi-node-pp9d9 55m (2%) 220m (11%) 125Mi (5%) 500Mi (20%) 116s
kube-system ibm-vpc-file-csi-node-5fg9n 48m (2%) 192m (10%) 110Mi (4%) 440Mi (17%) 116s
kube-system ibmcloud-iks-debug-daemonset-dh5cx 0 (0%) 0 (0%) 0 (0%) 0 (0%) 116s
kube-system konnectivity-agent-wxxlw 10m (0%) 0 (0%) 10Mi (0%) 500Mi (20%) 116s
kube-system public-co9j451t0t7uthsxxxx-alb3-747c69d5d-5ccwd 20m (1%) 0 (0%) 135Mi (5%) 0 (0%) 82d
kube-system public-co9j451t0t7uthsxxxx-alb3-88b7f89b-mjwhx 20m (1%) 0 (0%) 135Mi (5%) 0 (0%) 46d
velero node-agent-f9cdg 0 (0%) 0 (0%) 0 (0%) 0 (0%) 72s
velero velero-7f4f557fdd-rk5v8 500m (26%) 1 (52%) 128Mi (5%) 512Mi (20%) 114s
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1308m (68%) 3712m (193%)
memory 2148882Ki (85%) 6418720Ki (255%)
ephemeral-storage 5Mi (0%) 105Mi (0%)
hugepages-1Gi 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Starting 99s kube-proxy
Normal Starting 117s kubelet Starting kubelet.
Warning InvalidDiskCapacity 117s kubelet invalid capacity 0 on image filesystem
Normal NodeAllocatableEnforced 117s kubelet Updated Node Allocatable limit across pods
Normal NodeHasSufficientMemory 116s (x7 over 117s) kubelet Node 10.244.0.5 status is now: NodeHasSufficientMemory
Normal NodeHasNoDiskPressure 116s (x7 over 117s) kubelet Node 10.244.0.5 status is now: NodeHasNoDiskPressure
Normal NodeHasSufficientPID 116s (x7 over 117s) kubelet Node 10.244.0.5 status is now: NodeHasSufficientPID
Normal RegisteredNode 112s node-controller Node 10.244.0.5 event: Registered Node 10.244.0.5 in Controller
Normal Synced 102s cloud-node-controller Node synced successfully
Normal NodeReady 94s kubelet Node 10.244.0.5 status is now: NodeReady
4.Deploymentを作成(上記のラベルを利用)
topology.kubernetes.io/zone=jp-tok-1のラベルを用いて、zoneを指定する
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 10
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- jp-tok-1
- jp-tok-2
5.Deploymentをデプロイ
% ls
NodeAffinity-deployment.yaml NodeSelector-deployment.yaml NotNodeSelector-deployment.yaml deployment.yml service.yml
% kubectl apply -f NodeSelector-deployment.yaml
deployment.apps/nginx-deployment created
6.zone3(jp-tok-3)にはPODが割り当てられていないことが確認できる
% ibmcloud ks worker ls --cluster co9j451t0t7uthsxxxx --worker-pool co9j451t0t7uthsxxxx-9476a1e
OK
ID プライマリー IP フレーバー 状態 状況 ゾーン バージョン オペレーティング・システム
kube-co9j451t0t7uthsxxxx-acspaasclus-lowspec-00001ac4 10.244.64.11 cx2.2x4 normal Ready jp-tok-2 1.30.7_1549* UBUNTU_24_64
kube-co9j451t0t7uthsxxxx-acspaasclus-lowspec-00001d30 10.244.128.12 cx2.2x4 normal Ready jp-tok-3 1.30.7_1549* UBUNTU_24_64
kube-co9j451t0t7uthsxxxx-acspaasclus-lowspec-00001e31 10.244.0.5 cx2.2x4 normal Ready jp-tok-1 1.30.9_1555 UBUNTU_24_64
% kubectl get pods -o wide | grep nginx-dep
nginx-deployment-66b94478d5-4vt7w 1/1 Running 0 10s 172.17.17.124 10.244.64.11 <none> <none>
nginx-deployment-66b94478d5-59wjn 1/1 Running 0 10s 172.17.11.203 10.244.0.5 <none> <none>
nginx-deployment-66b94478d5-bc92x 1/1 Running 0 10s 172.17.11.200 10.244.0.5 <none> <none>
nginx-deployment-66b94478d5-bsfvz 1/1 Running 0 10s 172.17.11.204 10.244.0.5 <none> <none>
nginx-deployment-66b94478d5-lzqnt 1/1 Running 0 10s 172.17.17.121 10.244.64.11 <none> <none>
nginx-deployment-66b94478d5-qgjmm 1/1 Running 0 10s 172.17.17.122 10.244.64.11 <none> <none>
nginx-deployment-66b94478d5-qrz94 1/1 Running 0 10s 172.17.17.125 10.244.64.11 <none> <none>
nginx-deployment-66b94478d5-wqs9c 1/1 Running 0 10s 172.17.11.202 10.244.0.5 <none> <none>
nginx-deployment-66b94478d5-x9p89 1/1 Running 0 10s 172.17.11.201 10.244.0.5 <none> <none>
nginx-deployment-66b94478d5-xcs9l 1/1 Running 0 10s 172.17.17.123 10.244.64.11 <none> <none>