🗂
KubernetesにおけるNode・Pod配置制御の手法まとめ
概要
Kubernetesには複数のスケジューリング制御方法がある。本記事では、nodeSelector、Node Affinity、Pod Affinity、Taints/Tolerations、Pod Topology Spread Constraintsについて、それぞれの特徴と使い分けについて記述する。
1. nodeSelector
最もシンプルなノード選択の仕組み。ノードのラベルに基づいて、Podを配置するノードを指定する。
設定例
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeSelector:
disktype: ssd
特徴
- シンプルで分かりやすい
- 柔軟性に欠ける(完全一致のみ)
- 後述のNode Affinityのほうがより柔軟
2. Node Affinity
より柔軟なノード選択の仕組み。
設定例
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
- nvme
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-label
operator: In
values:
- another-value
特徴
- より柔軟な条件指定が可能(In、NotIn、Exists、DoesNotExist等)
- 必須条件(required)と優先条件(preferred)の指定が可能
- 重み付けによる優先度の調整が可能
3. Pod Affinity
Pod間の関係に基づいてスケジューリングを制御する仕組み。
設定例
apiVersion: v1
kind: Pod
metadata:
name: web-pod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- cache
topologyKey: kubernetes.io/hostname
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname
特徴
- Pod間のAffinityやAntiAffinityを制御可能
- トポロジーキーによる配置範囲の制御が可能
- パフォーマンスや可用性の最適化に有効
4. Taints/Tolerations
ノードに対する制約とその許容を制御する仕組み。
設定例
# ノードへのTaint設定
kubectl taint nodes node1 key=value:NoSchedule
# Pod側のToleration設定
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
特徴
- ノードを特定の用途に制限可能
- 問題のあるノードの隔離に有効
- 3種類のeffect(NoSchedule、PreferNoSchedule、NoExecute)を使用可能
5. Pod Topology Spread Constraints
クラスター全体でのPodの分散を制御する仕組み。
設定例
apiVersion: v1
kind: Pod
metadata:
name: web-server
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web
特徴
- クラスター全体でのPod分散を制御可能
- トポロジードメイン(ノード、ゾーン、リージョン等)での分散が可能
- maxSkewによる分散の度合いを制御可能
使い分けの指針
-
シンプルなノード選択
- nodeSelector: 単純な条件での選択
- Node Affinity: より複雑な条件や優先度が必要な場合
-
Pod間の関係制御
- Pod Affinity: 特定のPod同士の配置関係が重要な場合
- Pod AntiAffinity: 特定のPod同士の分散が必要な場合
-
ノードの用途制限
- Taints/Tolerations: 特定のノードを特定の用途に制限したい場合
-
全体的な分散制御
- Pod Topology Spread Constraints: クラスター全体でのPod分散が必要な場合
実践的な組み合わせ例
高可用性アプリケーションの例
apiVersion: apps/v1
kind: Deployment
metadata:
name: high-availability-app
spec:
template:
spec:
# ノード要件の指定
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- production
# Pod分散の制御
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: web
# 同一アプリケーションの分散
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
まとめ
複数のスケジューリング制御機能を適切に組み合わせることで、より細かい制御が可能となる。運用要件を明確に理解し、それに合わせた最適な制御方法を選択することが重要。また、複雑な設定は運用コストの増加につながる可能性があるため、必要最小限の制御にとどめることも検討すべき。
Discussion