第13章 CPU マネージャーの使用

13.1. CPU マネージャーの機能

CPU マネージャーは、CPU グループを管理して、ワークロードを特定の CPU に制限します。

CPU マネージャーは、以下のような属性が考慮されるワークロードに役立ちます。

  • できるだけ長い CPU 時間が必要な場合
  • プロセッサーのキャッシュミスの影響を受ける場合
  • レイテンシーが低いネットワークアプリケーションの場合
  • 他のプロセスと連携し、単一のプロセッサーキャッシュを共有することに利点がある場合

13.2. CPU マネージャーの設定

CPU マネージャーを設定するには、以下を実行します。

  1. オプションで、ノードにラベルを指定します。

    # oc label node perf-node.example.com cpumanager=true
  2. ターゲットノードで CPU マネージャーのサポートを有効にします。

    # oc edit configmap <name> -n openshift-node

    例:

    # oc edit cm node-config-compute -n openshift-node

    出力例

    ...
    kubeletArguments:
    ...
      feature-gates:
      - CPUManager=true
      cpu-manager-policy:
      - static
      cpu-manager-reconcile-period:
      - 5s
      kube-reserved: 1
      - cpu=500m

    # systemctl restart atomic-openshift-node
    1
    kube-reserved は必須の設定です。この値は、環境に合わせて調整する必要があります。
  3. コア 1 つまたは複数を要求する Pod を作成します。制限および要求の CPU の値は整数にする必要があります。これは、対象の Pod 専用のコアの数になります。

    # cat cpumanager.yaml

    出力例

    apiVersion: v1
    kind: Pod
    metadata:
      generateName: cpumanager-
    spec:
      containers:
      - name: cpumanager
        image: gcr.io/google_containers/pause-amd64:3.0
        resources:
          requests:
            cpu: 1
            memory: "1G"
          limits:
            cpu: 1
            memory: "1G"
      nodeSelector:
        cpumanager: "true"

  4. Pod を作成します。

    # oc create -f cpumanager.yaml
  5. Pod がラベル指定されたノードにスケジュールされていることを確認します。

    # oc describe pod cpumanager

    出力例

    Name:         cpumanager-4gdtn
    Namespace:    test
    Node:         perf-node.example.com/172.31.62.105
    ...
        Limits:
          cpu:     1
          memory:  1G
        Requests:
          cpu:        1
          memory:     1G
    ...
    QoS Class:       Guaranteed
    Node-Selectors:  cpumanager=true
                     region=primary

  6. cgroups が正しく設定されていることを確認します。一時停止プロセスの PID を取得します。

    # systemd-cgls -l

    出力例

    ├─1 /usr/lib/systemd/systemd --system --deserialize 20
    ├─kubepods.slice
    │ ├─kubepods-pod0ec1ab8b_e1c4_11e7_bb22_027b30990a24.slice
    │ │ ├─docker-b24e29bc4021064057f941dc5f3538595c317d294f2c8e448b5e61a29c026d1c.scope
    │ │ │ └─44216 /pause

    QoS 階層 Guaranteed の Pod は、kubepods.slice に配置されます。他の QoS の Pod は、kubepods の子である cgroups に配置されます。

    # cd /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-pod0ec1ab8b_e1c4_11e7_bb22_027b30990a24.slice/docker-b24e29bc4021064057f941dc5f3538595c317d294f2c8e448b5e61a29c026d1c.scope
    # for i in `ls cpuset.cpus tasks` ; do echo -n "$i "; cat $i ; done

    出力例

    cpuset.cpus 2
    tasks 44216

  7. 対象のタスクで許可される CPU 一覧を確認します。

    # grep ^Cpus_allowed_list /proc/44216/status

    出力例

    Cpus_allowed_list:      2

  8. システム上の別の Pod (この場合は burstable QoS 階層にあるPod) が、Guaranteed Pod に割り当てられたコアで実行できないことを確認します。

    # cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podbe76ff22_dead_11e7_b99e_027b30990a24.slice/docker-da621bea7569704fc39f84385a179923309ab9d832f6360cccbff102e73f9557.scope/cpuset.cpus
    0-1,3
    # oc describe node perf-node.example.com

    出力例

    ...
    Capacity:
     cpu:     4
     memory:  16266720Ki
     pods:    40
    Allocatable:
     cpu:     3500m
     memory:  16164320Ki
     pods:    40
    ---
      Namespace                  Name                      CPU Requests  CPU Limits  Memory Requests  Memory Limits
      ---------                  ----                      ------------  ----------  ---------------  -------------
      test                        cpumanager-4gdtn          1 (28%)       1 (28%)     1G (6%)          1G (6%)
      test                        cpumanager-hczts          1 (28%)       1 (28%)     1G (6%)          1G (6%)
      test                        cpumanager-r9wrq          1 (28%)       1 (28%)     1G (6%)          1G (6%)
    ...
    Allocated resources:
      (Total limits may be over 100 percent, i.e., overcommitted.)
      CPU Requests  CPU Limits  Memory Requests  Memory Limits
      ------------  ----------  ---------------  -------------
      3 (85%)       3 (85%)     5437500k (32%)   9250M (55%)

    この仮想マシンには、CPU コアが 4 基あります。kube-reserved を 500 ミリコアに設定して、Node Allocatable の数になるように、ノードの全容量からコア の半分を引きます。

    Allocatable CPU が 3500 ミリコアであることを確認できます。これは、それぞれがコアを 1 つ受け入れるので、CPU マネージャー Pod の内 3 つを実行できるという意味になります。1 つのコア全体は、1000 ミリコアに相当します。

    4 つ目の Pod をスケジュールしようとすると、システムは Pod を受け入れますが、スケジュールはされません。

    # oc get pods --all-namespaces |grep test

    出力例

    test              cpumanager-4gdtn               1/1       Running            0          8m
    test              cpumanager-hczts               1/1       Running            0          8m
    test              cpumanager-nb9d5               0/1       Pending            0          8m
    test              cpumanager-r9wrq               1/1       Running            0          8m