Scheduling

Label/Selector、Pod の配置制御

Kubernetes の Scheduler は Pod をどのノードに配置するか決定します。Label と Selector でリソースを識別・選択し、 Affinity や Taint で配置を制御します。

Label & Selector

Label はリソースに付けるキーバリューのタグ。Selector で Label を指定してリソースを選択・グループ化します。 Service、Deployment、スケジューリングなど多くの場面で使用。

┌─────────────────────────────────────────────────────────────┐
│           Service / Deployment の selector                  │
│              app=web, tier=frontend                         │
└─────────────────────┬───────────────────────────────────────┘
                      │ マッチ
        ┌─────────────┼─────────────┐
        ▼             ▼             ▼
   ┌─────────┐   ┌─────────┐   ┌─────────┐
   │  Pod 1  │   │  Pod 2  │   │  Pod 3  │
   │ app=web │   │ app=web │   │ app=api │ ← マッチしない
   │tier=    │   │tier=    │   │tier=    │
   │frontend │   │frontend │   │backend  │
   └─────────┘   └─────────┘   └─────────┘

Label 定義

metadata:
  labels:
    app: nginx
    tier: frontend
    env: production
    version: v1.2.3

Selector 指定

# 等価ベース
selector:
  matchLabels:
    app: nginx

# 集合ベース
selector:
  matchExpressions:
    - key: env
      operator: In
      values: [prod, staging]

Label 操作コマンド

kubectl label pods my-pod app=web - Label 追加
kubectl label pods my-pod app- - Label 削除
kubectl get pods -l app=web - Label で絞り込み
kubectl get pods -l 'env in (prod,staging)' - 集合ベース

スケジューリングフロー

┌─────────────────────────────────────────────────────────────┐
│                    kube-scheduler                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. Filtering (フィルタリング)                               │
│     ├── リソース不足のノードを除外                           │
│     ├── NodeSelector に合わないノードを除外                  │
│     ├── Taint に Toleration がないノードを除外               │
│     └── Affinity 条件に合わないノードを除外                  │
│                          ↓                                  │
│  2. Scoring (スコアリング)                                   │
│     ├── リソースバランス                                     │
│     ├── Affinity/Anti-Affinity の優先度                     │
│     └── その他のプラグイン                                   │
│                          ↓                                  │
│  3. Binding (バインド)                                       │
│     └── 最高スコアのノードに Pod を割り当て                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

NodeSelector

最もシンプルな配置制御。ノードの Label を指定して配置先を限定します。

ノードに Label を付与

# ノードに Label を追加
kubectl label nodes node-1 disktype=ssd

# 確認
kubectl get nodes --show-labels

Pod で指定

spec:
  nodeSelector:
    disktype: ssd

Node Affinity

NodeSelector の拡張版。より柔軟な条件指定(In, NotIn, Exists 等)と優先度(required/preferred)を設定できます。

requiredDuringSchedulingIgnoredDuringExecution(必須)

条件を満たすノードがない場合、Pod はスケジュールされない

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: zone
                operator: In
                values:
                  - ap-northeast-1a
                  - ap-northeast-1c

preferredDuringSchedulingIgnoredDuringExecution(優先)

条件を満たすノードを優先するが、なくても他のノードにスケジュール

spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 80
          preference:
            matchExpressions:
              - key: disktype
                operator: In
                values:
                  - ssd

Pod Affinity / Anti-Affinity

他の Pod との位置関係を制御。同じノード/ゾーンに配置(Affinity)、 または分散配置(Anti-Affinity)できます。

┌─────────────────────────────────────────────────────────────┐
│                     Pod Affinity                            │
│  「Web Pod は Cache Pod と同じノードに配置したい」            │
│                                                             │
│     Node 1              Node 2              Node 3          │
│  ┌──────────┐        ┌──────────┐        ┌──────────┐       │
│  │ Cache    │        │          │        │          │       │
│  │ Web  ←───┼───────→│          │        │          │       │
│  └──────────┘  同居   └──────────┘        └──────────┘       │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                    Pod Anti-Affinity                        │
│  「Web Pod は他の Web Pod と別のノードに分散したい」          │
│                                                             │
│     Node 1              Node 2              Node 3          │
│  ┌──────────┐        ┌──────────┐        ┌──────────┐       │
│  │ Web 1    │        │ Web 2    │        │ Web 3    │       │
│  └──────────┘        └──────────┘        └──────────┘       │
│       ↑                  ↑                  ↑               │
│       └──────────────────┴──────────────────┘               │
│                    分散配置                                  │
└─────────────────────────────────────────────────────────────┘

Pod Anti-Affinity 例(高可用性)

spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app: web
          topologyKey: kubernetes.io/hostname  # ノード単位で分散

Taint & Toleration

Taint はノードに「汚れ」を付けて Pod を寄せ付けない仕組み。Toleration を持つ Pod のみがその Taint を許容して配置されます。

                    Taint: gpu=true:NoSchedule
                              │
                              ▼
┌─────────────────────────────────────────────────────────┐
│                      GPU Node                           │
│                   「GPU専用ノード」                      │
│                                                         │
│   ┌─────────┐                                           │
│   │ ML Pod  │ ← Toleration あり → 配置OK               │
│   └─────────┘                                           │
│                                                         │
│   ┌─────────┐                                           │
│   │ Web Pod │ ← Toleration なし → 配置NG ✗             │
│   └─────────┘                                           │
│                                                         │
└─────────────────────────────────────────────────────────┘

Taint をノードに設定

# Taint を追加
kubectl taint nodes gpu-node-1 \
  gpu=true:NoSchedule

# Taint を削除
kubectl taint nodes gpu-node-1 \
  gpu=true:NoSchedule-

Toleration を Pod に設定

spec:
  tolerations:
    - key: "gpu"
      operator: "Equal"
      value: "true"
      effect: "NoSchedule"

Taint Effect の種類

Effect動作
NoSchedule新規 Pod をスケジュールしない
PreferNoScheduleなるべくスケジュールしない(ソフト)
NoExecute既存 Pod も退去させる

リソース要求と制限

requests はスケジューリング時に考慮される最低保証リソース。limits は使用可能な上限。

リソース設定例

spec:
  containers:
    - name: app
      image: myapp:v1
      resources:
        requests:
          memory: "256Mi"   # スケジューリング時に確保
          cpu: "250m"       # 0.25 CPU
        limits:
          memory: "512Mi"   # 超えると OOMKill
          cpu: "500m"       # 超えるとスロットリング

CPU 単位

  • 1 = 1 vCPU / 1 Core
  • 500m = 0.5 CPU
  • 100m = 0.1 CPU

Memory 単位

  • 128Mi = 128 MiB
  • 1Gi = 1 GiB
  • 256M = 256 MB(10進数)