6장. CPU 관리자 및 토폴로지 관리자 사용

CPU 관리자는 CPU 그룹을 관리하고 워크로드를 특정 CPU로 제한합니다.

CPU 관리자는 다음과 같은 속성 중 일부가 포함된 워크로드에 유용합니다.

  • 가능한 한 많은 CPU 시간이 필요합니다.
  • 프로세서 캐시 누락에 민감합니다.
  • 대기 시간이 짧은 네트워크 애플리케이션입니다.
  • 다른 프로세스와 조정하고 단일 프로세서 캐시 공유를 통해 얻는 이점이 있습니다.

토폴로지 관리자는 동일한 NUMA(Non-Uniform Memory Access) 노드의 모든 QoS(Quality of Service) 클래스에 대해 CPU 관리자, 장치 관리자, 기타 힌트 공급자로부터 힌트를 수집하여 CPU, SR-IOV VF, 기타 장치 리소스 등의 Pod 리소스를 정렬합니다.

토폴로지 관리자는 토폴로지 관리자 정책 및 요청된 Pod 리소스를 기반으로 수집된 팁의 토폴로지 정보를 사용하여 노드에서 Pod를 수락하거나 거부할 수 있는지 결정합니다.

토폴로지 관리자는 하드웨어 가속기를 사용하여 대기 시간이 중요한 실행과 처리량이 높은 병렬 계산을 지원하는 워크로드에 유용합니다.

토폴로지 관리자를 사용하려면 정적 정책을 사용하여 CPU 관리자를 구성해야 합니다.

6.1. CPU 관리자 설정

프로세스

  1. 선택사항: 노드에 레이블을 지정합니다.

    # oc label node perf-node.example.com cpumanager=true
  2. CPU 관리자를 활성화해야 하는 노드의 MachineConfigPool을 편집합니다. 이 예에서는 모든 작업자의 CPU 관리자가 활성화됩니다.

    # oc edit machineconfigpool worker
  3. 작업자 머신 구성 풀에 레이블을 추가합니다.

    metadata:
      creationTimestamp: 2020-xx-xxx
      generation: 3
      labels:
        custom-kubelet: cpumanager-enabled
  4. KubeletConfig, cpumanager-kubeletconfig.yaml, CR(사용자 정의 리소스)을 생성합니다. 이전 단계에서 생성한 레이블을 참조하여 올바른 노드가 새 kubelet 구성으로 업데이트되도록 합니다. machineConfigPoolSelector 섹션을 참조하십시오.

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: cpumanager-enabled
    spec:
      machineConfigPoolSelector:
        matchLabels:
          custom-kubelet: cpumanager-enabled
      kubeletConfig:
         cpuManagerPolicy: static 1
         cpuManagerReconcilePeriod: 5s 2
    1
    정책을 지정합니다.
    • none. 이 정책은 기존 기본 CPU 선호도 체계를 명시적으로 활성화하여 스케줄러가 자동으로 수행하는 것 이상으로 선호도를 제공하지 않도록 합니다. 이는 기본 정책입니다.
    • static. 이 정책을 사용하면 정수 CPU 요청이 있는 보장된 Pod의 컨테이너를 사용할 수 있습니다. 또한 노드의 전용 CPU에 대한 액세스 권한을 제한합니다. 적인 경우 소문자 s 를 사용해야 합니다.
    2
    선택사항입니다. CPU 관리자 조정 빈도를 지정합니다. 기본값은 5s입니다.
  5. 동적 kubelet 구성을 생성합니다.

    # oc create -f cpumanager-kubeletconfig.yaml

    그러면 kubelet 구성에 CPU 관리자 기능이 추가되고 필요한 경우 MCO(Machine Config Operator)가 노드를 재부팅합니다. CPU 관리자를 활성화하는 데는 재부팅이 필요하지 않습니다.

  6. 병합된 kubelet 구성을 확인합니다.

    # oc get machineconfig 99-worker-XXXXXX-XXXXX-XXXX-XXXXX-kubelet -o json | grep ownerReference -A7

    출력 예

           "ownerReferences": [
                {
                    "apiVersion": "machineconfiguration.openshift.io/v1",
                    "kind": "KubeletConfig",
                    "name": "cpumanager-enabled",
                    "uid": "7ed5616d-6b72-11e9-aae1-021e1ce18878"
                }
            ]

  7. 작업자에서 업데이트된 kubelet.conf를 확인합니다.

    # oc debug node/perf-node.example.com
    sh-4.2# cat /host/etc/kubernetes/kubelet.conf | grep cpuManager

    출력 예

    cpuManagerPolicy: static        1
    cpuManagerReconcilePeriod: 5s   2

    1
    cpuManagerPolicyKubeletConfig CR을 생성할 때 정의됩니다.
    2
    cpuManagerReconcilePeriodKubeletConfig CR을 생성할 때 정의됩니다.
  8. 코어를 하나 이상 요청하는 Pod를 생성합니다. 제한 및 요청 둘 다 해당 CPU 값이 정수로 설정되어야 합니다. 해당 숫자는 이 Pod 전용으로 사용할 코어 수입니다.

    # cat cpumanager-pod.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"

  9. Pod를 생성합니다.

    # oc create -f cpumanager-pod.yaml
  10. 레이블 지정한 노드에 Pod가 예약되어 있는지 검증합니다.

    # oc describe pod cpumanager

    출력 예

    Name:               cpumanager-6cqz7
    Namespace:          default
    Priority:           0
    PriorityClassName:  <none>
    Node:  perf-node.example.com/xxx.xx.xx.xxx
    ...
     Limits:
          cpu:     1
          memory:  1G
        Requests:
          cpu:        1
          memory:     1G
    ...
    QoS Class:       Guaranteed
    Node-Selectors:  cpumanager=true

  11. cgroups가 올바르게 설정되었는지 검증합니다. pause 프로세스의 PID(프로세스 ID)를 가져옵니다.

    # ├─init.scope
    │ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
    └─kubepods.slice
      ├─kubepods-pod69c01f8e_6b74_11e9_ac0f_0a2b62178a22.slice
      │ ├─crio-b5437308f1a574c542bdf08563b865c0345c8f8c0b0a655612c.scope
      │ └─32706 /pause

    QoS(Quality of Service) 계층 Guaranteed의 Pod는 kubepods.slice에 있습니다. 다른 QoS 계층의 Pod는 kubepods의 하위 cgroups에 있습니다.

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

    출력 예

    cpuset.cpus 1
    tasks 32706

  12. 작업에 허용되는 CPU 목록을 확인합니다.

    # grep ^Cpus_allowed_list /proc/32706/status

    출력 예

     Cpus_allowed_list:    1

  13. Guaranteed Pod용으로 할당된 코어에서는 시스템의 다른 Pod(이 경우 burstable QoS 계층의 Pod)를 실행할 수 없는지 검증합니다.

    # cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-podc494a073_6b77_11e9_98c0_06bba5c387ea.slice/crio-c56982f57b75a2420947f0afc6cafe7534c5734efc34157525fa9abbf99e3849.scope/cpuset.cpus
    0
    # oc describe node perf-node.example.com

    출력 예

    ...
    Capacity:
     attachable-volumes-aws-ebs:  39
     cpu:                         2
     ephemeral-storage:           124768236Ki
     hugepages-1Gi:               0
     hugepages-2Mi:               0
     memory:                      8162900Ki
     pods:                        250
    Allocatable:
     attachable-volumes-aws-ebs:  39
     cpu:                         1500m
     ephemeral-storage:           124768236Ki
     hugepages-1Gi:               0
     hugepages-2Mi:               0
     memory:                      7548500Ki
     pods:                        250
    -------                               ----                           ------------  ----------  ---------------  -------------  ---
      default                                 cpumanager-6cqz7               1 (66%)       1 (66%)     1G (12%)         1G (12%)       29m
    
    Allocated resources:
      (Total limits may be over 100 percent, i.e., overcommitted.)
      Resource                    Requests          Limits
      --------                    --------          ------
      cpu                         1440m (96%)       1 (66%)

    이 VM에는 두 개의 CPU 코어가 있습니다. system-reserved 설정은 500밀리코어로 설정되었습니다. 즉, Node Allocatable 양이 되는 노드의 전체 용량에서 한 코어의 절반이 감산되었습니다. Allocatable CPU는 1500 밀리코어임을 확인할 수 있습니다. 즉, Pod마다 하나의 전체 코어를 사용하므로 CPU 관리자 Pod 중 하나를 실행할 수 있습니다. 전체 코어는 1000밀리코어에 해당합니다. 두 번째 Pod를 예약하려고 하면 시스템에서 해당 Pod를 수락하지만 Pod가 예약되지 않습니다.

    NAME                    READY   STATUS    RESTARTS   AGE
    cpumanager-6cqz7        1/1     Running   0          33m
    cpumanager-7qc2t        0/1     Pending   0          11s