11.2. 실시간 및 짧은 대기 시간 워크로드 프로비저닝

많은 업계와 조직에서 매우 높은 성능의 컴퓨팅을 필요로 하고 있으며 특히 금융 및 통신 업계에서는 짧고 예측 가능한 대기 시간이 요구될 수 있습니다. 고유한 요구 사항이 있는 이러한 업계의 경우 OpenShift Container Platform은 OpenShift Container Platform 애플리케이션에 대해 짧은 대기 시간 성능과 일관된 응답 시간을 실현할 수 있도록 자동 튜닝을 구현하는 Node Tuning Operator를 제공합니다.

클러스터 관리자는 이 성능 프로필 구성을 사용하여 보다 안정적인 방식으로 이러한 변경을 수행할 수 있습니다. 관리자는 커널을 kernel-rt(실시간)로 업데이트할지 여부를 지정하고, Pod 인프라 컨테이너를 포함하여 클러스터 및 운영 체제 하우스키핑 작업을 위해 CPU를 예약하고, 애플리케이션 컨테이너의 CPU를 분리하여 워크로드를 실행하고, 사용하지 않는 CPU를 비활성화하여 전력 소비를 줄일 수 있습니다.

주의

보장된 CPU가 필요한 애플리케이션과 함께 실행 프로브를 사용하면 대기 시간이 급증할 수 있습니다. 적절하게 구성된 네트워크 프로브 세트와 같은 다른 프로브를 대안으로 사용하는 것이 좋습니다.

참고

이전 버전의 OpenShift Container Platform에서는 OpenShift 애플리케이션에 대해 짧은 대기 시간 성능을 실현하기 위해 자동 튜닝을 구현하는 데 Performance Addon Operator를 사용했습니다. OpenShift Container Platform 4.11 이상에서는 이러한 기능이 Node Tuning Operator의 일부입니다.

11.2.1. 실시간에 대한 알려진 제한 사항

참고

대부분의 배포에서 kernel-rt는 세 개의 컨트롤 플레인 노드와 작업자 노드가 세 개 있는 표준 클러스터를 사용하는 경우 작업자 노드에서만 지원됩니다. OpenShift Container Platform 배포에는 컴팩트 및 단일 노드에 예외가 있습니다. 단일 노드에 설치하려면 kernel-rt가 단일 컨트롤 플레인 노드에서 지원됩니다.

실시간 모드를 완전히 활용하려면 상승된 권한으로 컨테이너를 실행해야 합니다. 권한 부여에 대한 자세한 내용은 컨테이너에 대한 기능 설정을 참조하십시오.

OpenShift Container Platform에서는 허용되는 기능을 제한하므로 SecurityContext를 생성해야 할 수도 있습니다.

참고

RHCOS(Red Hat Enterprise Linux CoreOS) 시스템을 사용하는 베어 메탈 설치에서는 이러한 절차가 완전하게 지원됩니다.

적합한 성능 기대치를 설정한다는 것은 실시간 커널이 만능 해결책이 아니라는 것을 나타냅니다. 설정의 목표는 예측 가능한 응답 시간을 제공하는 일관되고 대기 시간이 짧은 결정성을 갖추는 것입니다. 실시간 커널에는 연관된 추가 커널 오버헤드가 있습니다. 이러한 오버헤드는 주로 별도로 예약된 스레드에서 하드웨어 중단을 처리하는 데서 발생합니다. 일부 워크로드에서 오버헤드가 증가하면 전반적으로 처리량 성능이 저하됩니다. 정확한 저하 수치는 워크로드에 따라 달라지며, 범위는 0%에서 30% 사이입니다. 하지만 이러한 저하는 결정성에 대한 대가입니다.

11.2.2. 실시간 기능이 있는 작업자 프로비저닝

  1. 선택사항: OpenShift Container Platform 클러스터에 노드를 추가합니다. 시스템 튜닝을 위한 BIOS 매개변수 설정을 참조하십시오.
  2. oc 명령을 사용하여 실시간 기능이 필요한 작업자 노드에 worker-rt 레이블을 추가합니다.
  3. 실시간 노드에 사용할 새 머신 구성 풀을 생성합니다.

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      name: worker-rt
      labels:
        machineconfiguration.openshift.io/role: worker-rt
    spec:
      machineConfigSelector:
        matchExpressions:
          - {
               key: machineconfiguration.openshift.io/role,
               operator: In,
               values: [worker, worker-rt],
            }
      paused: false
      nodeSelector:
        matchLabels:
          node-role.kubernetes.io/worker-rt: ""

    worker-rt 레이블이 있는 노드 그룹에 대해 머신 구성 풀 worker-rt 가 생성됩니다.

  4. 노드 역할 레이블을 사용하여 적절한 머신 구성 풀에 노드를 추가합니다.

    참고

    실시간 워크로드로 구성된 노드를 결정해야 합니다. 클러스터의 모든 노드 또는 노드의 하위 집합을 구성할 수 있습니다. 모든 노드를 예상하는 Node Tuning Operator는 전용 머신 구성 풀의 일부입니다. 모든 노드를 사용하는 경우 Node Tuning Operator에서 작업자 노드 역할 레이블을 가리켜야 합니다. 서브 세트를 사용하는 경우 해당 노드를 새 머신 구성 풀로 그룹화해야 합니다.

  5. 적절한 하우스키핑 코어 세트와 realTimeKernel: enabled: true를 사용하여 PerformanceProfile을 생성합니다.
  6. PerformanceProfile 에서 machineConfigPoolSelector 를 설정해야 합니다.

      apiVersion: performance.openshift.io/v2
      kind: PerformanceProfile
      metadata:
       name: example-performanceprofile
      spec:
      ...
        realTimeKernel:
          enabled: true
        nodeSelector:
           node-role.kubernetes.io/worker-rt: ""
        machineConfigPoolSelector:
           machineconfiguration.openshift.io/role: worker-rt
  7. 레이블과 일치하는 머신 구성 풀이 있는지 검증합니다.

    $ oc describe mcp/worker-rt

    출력 예

    Name:         worker-rt
    Namespace:
    Labels:       machineconfiguration.openshift.io/role=worker-rt

  8. OpenShift Container Platform에서 노드 구성을 시작합니다. 이 작업에서는 여러 번 재부팅이 수행될 수 있습니다. 노드가 설정될 때까지 기다리십시오. 사용하는 하드웨어에 따라 시간이 오래 걸릴 수 있으며 노드당 20분으로 예상됩니다.
  9. 모든 요소가 예상대로 작동하는지 검증하십시오.

11.2.3. 실시간 커널 설치 검증

다음 명령을 사용하여 실시간 커널이 설치되었는지 검증합니다.

$ oc get node -o wide

4.18.0-305.30.1.rt7.102.el8_4.x86_64 cri-o://1.25.0-99.rhaos4.10.gitc3131de.el8 문자열이 포함된 worker-rt 역할의 작업자를 기록해 둡니다.

NAME                               	STATUS   ROLES           	AGE 	VERSION                  	INTERNAL-IP
EXTERNAL-IP   OS-IMAGE                                       	KERNEL-VERSION
CONTAINER-RUNTIME
rt-worker-0.example.com	          Ready	 worker,worker-rt   5d17h   v1.25.0
128.66.135.107   <none>    	        Red Hat Enterprise Linux CoreOS 46.82.202008252340-0 (Ootpa)
4.18.0-305.30.1.rt7.102.el8_4.x86_64   cri-o://1.25.0-99.rhaos4.10.gitc3131de.el8
[...]

11.2.4. 실시간으로 작동하는 워크로드 생성

실시간 기능을 사용할 워크로드를 준비하려면 다음 절차를 사용하십시오.

프로세스

  1. QoS 클래스가 Guaranteed인 Pod를 생성합니다.
  2. 선택사항: DPDK에 대해 CPU 부하 분산을 비활성화합니다.
  3. 적절한 노드 선택기를 할당합니다.

애플리케이션을 작성하는 경우 애플리케이션 튜닝 및 배포에 설명된 일반 권장 사항을 따르십시오.

11.2.5. QoS 클래스가 Guaranteed인 Pod 생성

QoS 클래스가 Guaranteed로 지정된 Pod를 생성하는 경우 다음 사항에 유의하십시오.

  • Pod의 모든 컨테이너에는 메모리 제한과 메모리 요청이 있어야 하며 동일해야 합니다.
  • Pod의 모든 컨테이너에는 CPU 제한과 CPU 요청이 있어야 하며 동일해야 합니다.

다음 예에서는 컨테이너가 하나인 Pod의 구성 파일을 보여줍니다. 이 컨테이너에는 메모리 제한과 메모리 요청이 있으며 둘 다 200MiB입니다. 이 컨테이너에는 CPU 제한과 CPU 요청이 있으며 둘 다 CPU 1개입니다.

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-ctr
    image: <image-pull-spec>
    resources:
      limits:
        memory: "200Mi"
        cpu: "1"
      requests:
        memory: "200Mi"
        cpu: "1"
  1. Pod를 생성합니다.

    $ oc  apply -f qos-pod.yaml --namespace=qos-example
  2. Pod에 대한 자세한 정보를 봅니다.

    $ oc get pod qos-demo --namespace=qos-example --output=yaml

    출력 예

    spec:
      containers:
        ...
    status:
      qosClass: Guaranteed

    참고

    컨테이너가 자체 메모리 제한은 지정하지만 메모리 요청은 지정하지 않으면 OpenShift Container Platform에서 제한과 일치하는 메모리 요청을 자동으로 할당합니다. 마찬가지로, 컨테이너가 자체 CPU 제한은 지정하지만 CPU 요청은 지정하지 않으면 OpenShift Container Platform에서 제한과 일치하는 CPU 요청을 자동으로 할당합니다.

11.2.6. 선택사항: DPDK에 대해 CPU 부하 분산 비활성화

CPU 부하 분산을 비활성화하거나 활성화하는 기능은 CRI-O 수준에서 구현됩니다. CRI-O 아래의 코드는 다음 요구사항이 충족되는 경우에만 CPU 부하 분산을 비활성화하거나 활성화합니다.

  • Pod는 performance-<profile-name> 런타임 클래스를 사용해야 합니다. 다음과 같이 성능 프로필의 상태를 보고 적절한 이름을 가져올 수 있습니다.

    apiVersion: performance.openshift.io/v2
    kind: PerformanceProfile
    ...
    status:
      ...
      runtimeClass: performance-manual
참고

현재 cgroup v2에서는 CPU 부하 분산을 비활성화하는 것은 지원되지 않습니다.

Node Tuning Operator는 관련 노드 아래에 고성능 런타임 처리기 구성 스니펫을 생성하고 클러스터에 고성능 런타임 클래스를 생성해야 합니다. CPU 부하 분산 구성 기능을 활성화하는 것을 제외하고는 기본 런타임 처리기와 콘텐츠가 동일합니다.

Pod에 대해 CPU 부하 분산을 비활성화하려면 Pod 사양에 다음 필드가 포함되어야 합니다.

apiVersion: v1
kind: Pod
metadata:
  ...
  annotations:
    ...
    cpu-load-balancing.crio.io: "disable"
    ...
  ...
spec:
  ...
  runtimeClassName: performance-<profile_name>
  ...
참고

CPU 관리자 static 정책이 활성화되어 있는 경우 전체 CPU를 사용하는 guaranteed QoS가 있는 Pod에 대해서만 CPU 부하 분산을 비활성화하십시오. 그렇지 않은 경우 CPU 부하 분산을 비활성화하면 클러스터에 있는 다른 컨테이너의 성능에 영향을 미칠 수 있습니다.

11.2.7. 적절한 노드 선택기 할당

노드에 Pod를 할당하는 기본 방법은 다음과 같이 성능 프로필에서 사용한 것과 동일한 노드 선택기를 사용하는 것입니다.

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  # ...
  nodeSelector:
    node-role.kubernetes.io/worker-rt: ""

자세한 내용은 노드 선택기를 사용하여 특정 노드에 Pod 배치를 참조하십시오.

11.2.8. 실시간 기능이 있는 작업자에 대해 워크로드 예약

Node Tuning Operator에서 짧은 대기 시간을 위해 구성된 머신 구성 풀에 연결된 노드와 일치하는 라벨 선택기를 사용합니다. 자세한 내용은 노드에 Pod 할당을 참조하십시오.

11.2.9. CPU를 오프라인 상태에서 사용하여 전력 소비 감소

일반적으로 Telemunication 워크로드를 예상할 수 있습니다. 모든 CPU 리소스가 필요하지 않은 경우 Node Tuning Operator를 사용하면 성능 프로필을 수동으로 업데이트하여 전력 소비를 줄일 수 있도록 Node Tuning Operator를 오프라인에서 사용할 수 있습니다.

사용되지 않는 CPU를 오프라인으로 전환하려면 다음 작업을 수행해야 합니다.

  1. 성능 프로필에 오프라인 CPU를 설정하고 YAML 파일의 내용을 저장합니다.

    오프라인 CPU가 있는 성능 프로파일의 예

    apiVersion: performance.openshift.io/v2
    kind: PerformanceProfile
    metadata:
      name: performance
    spec:
      additionalKernelArgs:
      - nmi_watchdog=0
      - audit=0
      - mce=off
      - processor.max_cstate=1
      - intel_idle.max_cstate=0
      - idle=poll
      cpu:
        isolated: "2-23,26-47"
        reserved: "0,1,24,25"
        offlined: "48-59" 1
      nodeSelector:
        node-role.kubernetes.io/worker-cnf: ""
      numa:
        topologyPolicy: single-numa-node
      realTimeKernel:
        enabled: true

    1
    선택 사항: 오프라인 필드에서 CPU를 나열하여 지정된 CPU를 오프라인으로 가져올 수 있습니다.
  2. 다음 명령을 실행하여 업데이트된 프로필을 적용합니다.

    $ oc apply -f my-performance-profile.yaml

11.2.10. 선택 사항: 절전 구성

높은 우선 순위 워크로드의 대기 시간 또는 처리량에 영향을 주지 않고 우선 순위가 높은 워크로드와 함께 배치되는 우선 순위가 낮은 노드에 대해 전력 절감을 활성화할 수 있습니다. 워크로드 자체를 수정하지 않고 절전을 수행할 수 있습니다.

중요

이 기능은 Intel Ice Lake 및 이후 세대의 Intel CPU에서 지원됩니다. 프로세서의 기능은 높은 우선 순위 워크로드의 대기 시간 및 처리량에 영향을 미칠 수 있습니다.

절전 구성을 사용하여 노드를 구성하는 경우 Pod 수준에서 성능 구성으로 높은 우선 순위의 워크로드를 구성해야 합니다. 즉, 구성이 Pod에서 사용하는 모든 코어에 적용됩니다.

Pod 수준에서 P-states 및 C-states를 비활성화하면 높은 우선 순위의 워크로드를 구성하여 최상의 성능과 대기 시간을 단축할 수 있습니다.

표 11.1. 우선 순위가 높은 워크로드 구성

주석설명
annotations:
  cpu-c-states.crio.io: "disable"
  cpu-freq-governor.crio.io: "<governor>"

C-states를 비활성화하고 CPU 스케일링에 대한 governor 유형을 지정하여 Pod에 가장 적합한 성능을 제공합니다. 높은 우선 순위 워크로드에 성능 관리자가 권장됩니다.

사전 요구 사항

  • BIOS에서 C-states 및 OS 제어 P-states 활성화

절차

  1. per-pod-power-managementtrue 로 설정하여 PerformanceProfile 을 생성합니다.

    $ podman run --entrypoint performance-profile-creator -v \
    /must-gather:/must-gather:z registry.redhat.io/openshift4/ose-cluster-node-tuning-operator:v4.12 \
    --mcp-name=worker-cnf --reserved-cpu-count=20 --rt-kernel=true \
    --split-reserved-cpus-across-numa=false --topology-manager-policy=single-numa-node \
    --must-gather-dir-path /must-gather -power-consumption-mode=low-latency \ 1
    --per-pod-power-management=true > my-performance-profile.yaml
    1
    power-consumption-modeper-pod-power-managementtrue 로 설정된 경우 default 또는 low-latency 여야 합니다.

    perPodPowerManagement가 있는 PerformanceProfile 의 예

    apiVersion: performance.openshift.io/v2
    kind: PerformanceProfile
    metadata:
         name: performance
    spec:
        [.....]
        workloadHints:
            realTime: true
            highPowerConsumption: false
            perPodPowerManagement: true

  2. 기본 cpufreq governor를 PerformanceProfile CR(사용자 정의 리소스)에서 추가 커널 인수로 설정합니다.

    apiVersion: performance.openshift.io/v2
    kind: PerformanceProfile
    metadata:
         name: performance
    spec:
        ...
        additionalKernelArgs:
        - cpufreq.default_governor=schedutil 1
    1
    그러나 schedutil governor를 사용하는 것이 좋습니다. 그러나 ondemand 또는 powersave governors와 같은 다른 governors를 사용할 수 있습니다.
  3. TunedPerformancePatch CR에서 최대 CPU 빈도를 설정합니다.

    spec:
      profile:
      - data: |
          [sysfs]
          /sys/devices/system/cpu/intel_pstate/max_perf_pct = <x> 1
    1
    max_perf_pctcpufreq 드라이버가 지원되는 최대 CPU 빈도의 백분율로 설정할 수 있는 최대 빈도를 제어합니다. 이 값은 모든 CPU에 적용됩니다. /sys/devices/system/cpu0/cpufreq/cpuinfo_max_freq 에서 지원되는 최대 빈도를 확인할 수 있습니다. 시작점으로 모든 코어 s의 frequency에서 모든 CPU를 제한하는 백분율을 사용할 수 있습니다. 모든 코어sECDHE 빈도는 코어가 모두 완전히 사용 중인 경우 모든 코어가 실행되는 빈도입니다.
  4. 높은 우선 순위 워크로드 Pod에 원하는 주석을 추가합니다. 주석은 기본 설정을 재정의합니다.

    우선 순위가 높은 워크로드 주석 예

    apiVersion: v1
    kind: Pod
    metadata:
      ...
      annotations:
        ...
        cpu-c-states.crio.io: "disable"
        cpu-freq-governor.crio.io: "<governor>"
        ...
      ...
    spec:
      ...
      runtimeClassName: performance-<profile_name>
      ...

  5. Pod를 다시 시작합니다.

추가 리소스

11.2.11. 보장된 pod 분리 CPU의 장치 중단 처리 관리

Node Tuning Operator는 Pod 인프라 컨테이너를 포함하여 클러스터 및 운영 체제 하우스키핑 작업을 위해 예약된 CPU와 워크로드를 실행하는 애플리케이션 컨테이너의 분리된 CPU로 호스트 CPU를 관리할 수 있습니다. 이를 통해 대기 시간이 짧은 워크로드의 CPU를 분리된 상태로 설정할 수 있습니다.

장치 중단은 보장된 pod가 실행 중인 CPU를 제외하고 CPU의 과부하를 방지하기 위해 모든 분리된 CPU와 예약된 CPU 간에 균형을 유지합니다. pod에 관련 주석이 설정되어 있으면 보장된 Pod CPU가 장치 인터럽트를 처리하지 못합니다.

새로운 성능 프로파일 필드 globallyDisableIrqLoadBalancing은 장치 중단을 처리할지 여부를 관리하는 데 사용할 수 있습니다. 특정 워크로드의 경우 예약된 CPU가 장치 인터럽트를 처리하기에 충분하지 않으며 이러한 이유로 장치 중단은 분리된 CPU에서 전역적으로 비활성화되지 않습니다. 기본적으로 Node Tuning Operator는 분리된 CPU에서 장치 인터럽트를 비활성화하지 않습니다.

워크로드에 대한 대기 시간을 단축하기 위해 일부(전체) pod에는 장치 인터럽트를 처리하지 않기 위한 실행 중인 CPU가 필요합니다. pod 주석 irq-load-balancing.crio.io는 장치 인터럽트의 처리 여부를 정의하는 데 사용됩니다. 설정되어 있는 경우 CRI-O는 pod가 실행되는 경우에만 장치 인터럽트를 비활성화합니다.

11.2.11.1. CPU CFS 할당량 비활성화

보장된 개별 Pod의 CPU 제한을 줄이려면 cpu-quota.crio.io: "disable" 주석이 있는 Pod 사양을 생성합니다. 이 주석은 Pod 런타임에 CPU 완전 공정 스케줄러(CFS) 할당량을 비활성화합니다. 다음 Pod 사양에는 이 주석이 포함되어 있습니다.

apiVersion: v1
kind: Pod
metadata:
  annotations:
      cpu-quota.crio.io: "disable"
spec:
    runtimeClassName: performance-<profile_name>
...
참고

CPU 관리자 정적 정책이 활성화되어 있고 전체 CPU를 사용하는 보장된 QoS가 있는 Pod의 경우 CPU CFS 할당량만 비활성화합니다. 그렇지 않으면 CPU CFS 할당량을 비활성화하면 클러스터에 있는 다른 컨테이너의 성능에 영향을 미칠 수 있습니다.

11.2.11.2. Node Tuning Operator에서 글로벌 장치 인터럽트 처리 비활성화

분리된 CPU 세트에 대한 글로벌 장치 인터럽트를 비활성화하도록 Node Tuning Operator를 구성하려면 성능 프로필의 globallyDisableIrqLoadBalancing 필드를 true 로 설정합니다. true인 경우 충돌하는 Pod 주석이 무시됩니다. false인 경우 IRQ 로드는 모든 CPU에서 균형을 유지합니다.

성능 프로파일 스니펫에서는 이 설정을 보여줍니다.

apiVersion: performance.openshift.io/v2
kind: PerformanceProfile
metadata:
  name: manual
spec:
  globallyDisableIrqLoadBalancing: true
...

11.2.11.3. 개별 pod에 대한 인터럽트 처리 비활성화

개별 pod의 인터럽트 처리를 비활성화하려면 성능 프로필에서 globallyDisableIrqLoadBalancingfalse 로 설정되어 있는지 확인합니다. 그런 다음 Pod 사양에서 irq-load-balancing.crio.io Pod 주석을 설정하여 를 비활성화합니다. 다음 Pod 사양에는 이 주석이 포함되어 있습니다.

apiVersion: performance.openshift.io/v2
kind: Pod
metadata:
  annotations:
      irq-load-balancing.crio.io: "disable"
spec:
    runtimeClassName: performance-<profile_name>
...

11.2.12. 장치 인터럽트 처리를 사용하기 위해 성능 프로파일을 업그레이드

기존 프로필에서 Node Tuning Operator 성능 프로필 CRD(사용자 정의 리소스 정의)를 v1 또는 v1alpha1에서 v2로 업그레이드하는 경우 기존 프로필에서 globallyDisableIrqLoadBalancingtrue 로 설정됩니다.

참고

globallyDisableIrqLoadBalancing toggles whether IRQ 로드 밸런싱이 Isolated CPU 세트에 대해 비활성화됩니다. 옵션을 true 로 설정하면 Isolated CPU 세트에 대한 IRQ 부하 분산을 비활성화합니다. 옵션을 false 로 설정하면 IRQ가 모든 CPU에서 균형을 유지할 수 있습니다.

11.2.12.1. 지원되는 API 버전

Node Tuning Operator는 성능 프로파일 apiVersion 필드에 v2,v1v1alpha1 을 지원합니다. v1 및 v1alpha1 API는 동일합니다. v2 API에는 기본값인 false 값을 사용하여 선택적 부울 필드 loballyDisableIrqLoadBalancing이 포함됩니다.

11.2.12.1.1. Node Tuning Operator API를 v1alpha1에서 v1로 업그레이드

Node Tuning Operator API 버전을 v1alpha1에서 v1로 업그레이드하는 경우 "None" 변환 전략을 사용하여 v1alpha1 성능 프로파일이 즉시 변환되고 API 버전 v1과 Node Tuning Operator에 제공됩니다.

11.2.12.1.2. Node Tuning Operator API를 v1alpha1 또는 v1에서 v2로 업그레이드

이전 Node Tuning Operator API 버전에서 업그레이드할 때 기존 v1 및 v1alpha1 성능 프로파일은 true 값이 있는 globallyDisableIrqLoadBalancing 필드를 삽입하는 변환 Webhook를 사용하여 변환됩니다.