Red Hat CoreOS 작업자 노드의 성능 튜닝
Satellite
- 지원되는 작업자 노드 운영 체제
- Red Hat CoreOS (
RHCOS)
Red Hat CoreOS 작업자 노드 성능을 조정하려면 CPU 고정, NUMA(비균일 메모리 액세스) 및 대용량 페이지를 활성화할 수 있습니다. 이러한 구성은 엄격한 성능 요구 사항이 있는 애플리케이션에 도움이 될 수 있습니다. 그러나 이러한 사용자 지정으로 인해 워크로드 스케줄링 문제가 발생할 수 있습니다.
Red Hat OpenShift 에서 MachineConfig 파일로 워커 노드 성능을 조정하는 대신 daemonset 파일로 호스트를 수정할 수 있습니다. 자세한 내용은 Calico MTU 변경하기 또는 Red Hat CoreOS 워커 노드 성능 튜닝하기를 참조하세요.
Node 기능 감지 운영자 배치
Satellite
작업자 노드에서 NUMA, CPU 고정 및 대용량 페이지를 사용으로 설정하기 전에 Node Feature Discovery Operator를 배치해야 합니다. 자세한 내용은 Node 기능 검색 연산자를 참조하세요.
작업자 노드에서 NUMA (Non-Uniform Memory Access), CPU 고정 및 대용량 페이지 사용
Satellite
시작하기 전에 Node Feature Discovery Operator 를 배치했는지 확인하십시오.
-
다음
DaemonSet을customize.yaml파일에 저장하십시오.--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: ibm-user-custom-configurator-privileged roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:openshift:scc:privileged subjects: - kind: ServiceAccount name: ibm-user-custom-configurator namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: ibm-user-custom-configurator namespace: kube-system --- apiVersion: v1 kind: ConfigMap metadata: name: ibm-user-custom-configurator namespace: kube-system data: 89-hugepages.conf: | vm.nr_hugepages=<<NUMBER_OF_HUGEPAGES>> configure.sh: | #!/usr/bin/env bash set -x cp -f /scripts/ibm-user-custom-configuration.sh /host-usr-local-bin/ibm-user-custom-configuration.sh chmod 0755 /host-usr-local-bin/ibm-user-custom-configuration.sh cp -f /scripts/ibm-user-custom-configuration.service /host-etc-systemd-dir/ibm-user-custom-configuration.service chmod 0644 /host-etc-systemd-dir/ibm-user-custom-configuration.service if [[ -f /scripts/89-hugepages.conf ]]; then cp -f /scripts/89-hugepages.conf /host-etc-systctld-dir/89-hugepages.conf fi nsenter -t 1 -m -u -i -n -p -- systemctl daemon-reload nsenter -t 1 -m -u -i -n -p -- systemctl enable ibm-user-custom-configuration.service nsenter -t 1 -m -u -i -n -p -- systemctl start ibm-user-custom-configuration.service ibm-user-custom-configuration.sh: | #!/usr/bin/env bash set -x GIGABYTES_RESERVED_MEMORY=$(echo $SYSTEM_RESERVED_MEMORY | awk -F 'Gi' '{print $1}') GIGABYTES_RESERVED_MEMORY_ROUNDED_UP=$(echo $GIGABYTES_RESERVED_MEMORY | awk '{print int($1+0.999)}') sed -i "s/SYSTEM_RESERVED_MEMORY=.*/SYSTEM_RESERVED_MEMORY=${GIGABYTES_RESERVED_MEMORY_ROUNDED_UP}Gi/g" /etc/node-sizing.env TOTAL_NUMA_MEMORY_TO_ALLOCATE=$(echo "$GIGABYTES_RESERVED_MEMORY_ROUNDED_UP" "1024" | awk '{print $1 * $2 + 100}') if cat /etc/kubernetes/kubelet.conf | jq -r .; then cat >/tmp/ibm-user-config.conf.json <<EOF { "topologyManagerPolicy": "<<TOPOLOGY_MANAGER_POLICY_VALUE>>", "memoryManagerPolicy": "Static", "cpuManagerPolicy": "static", "reservedMemory": [ { "numaNode": 0, "limits": { "memory": "${TOTAL_NUMA_MEMORY_TO_ALLOCATE}Mi" } } ] } EOF if ! cat /tmp/ibm-user-config.conf.json | jq -r .; then exit 1 fi if ! jq -s '.[0] * .[1]' /tmp/ibm-user-config.conf.json /etc/kubernetes/kubelet.conf > /etc/kubernetes/tmp-kubelet.conf; then exit 1 fi mv -f /etc/kubernetes/tmp-kubelet.conf /etc/kubernetes/kubelet.conf else cat >/tmp/ibm-user-config.conf <<EOF #START USER CONFIG topologyManagerPolicy: <<TOPOLOGY_MANAGER_POLICY_VALUE>> memoryManagerPolicy: Static cpuManagerPolicy: static reservedMemory: - numaNode: 0 limits: memory: ${TOTAL_NUMA_MEMORY_TO_ALLOCATE}Mi #END USER CONFIG EOF sed -i '/#START USER CONFIG/,/#END USER CONFIG/d' /etc/kubernetes/kubelet.conf cat /tmp/ibm-user-config.conf >>/etc/kubernetes/kubelet.conf fi ibm-user-custom-configuration.service: | [Unit] Description=Add custom user config to kubelet Before=kubelet.service After=kubelet-auto-node-size.service [Service] Type=oneshot RemainAfterExit=yes EnvironmentFile=/etc/node-sizing.env ExecStart=/usr/local/bin/ibm-user-custom-configuration.sh [Install] WantedBy=multi-user.target --- apiVersion: apps/v1 kind: DaemonSet metadata: labels: app: ibm-user-custom-configurator name: ibm-user-custom-configurator namespace: kube-system spec: selector: matchLabels: app: ibm-user-custom-configurator template: metadata: labels: app: ibm-user-custom-configurator spec: nodeSelector: feature.node.kubernetes.io/memory-numa: "true" ibm-cloud.kubernetes.io/os: RHCOS tolerations: - operator: "Exists" hostPID: true serviceAccount: ibm-user-custom-configurator initContainers: - name: configure image: "registry.access.redhat.com/ubi8/ubi:8.6" command: ['/bin/bash', '-c', 'mkdir /cache && cp /scripts/configure.sh /cache && chmod +x /cache/configure.sh && /bin/bash /cache/configure.sh'] securityContext: privileged: true volumeMounts: - mountPath: /scripts name: script-config - mountPath: /host-etc-systemd-dir name: etc-systemd-dir - mountPath: /host-usr-local-bin name: usr-local-bin - mountPath: /host-etc-systctld-dir name: etc-systctld-dir containers: - name: pause image: us.icr.io/armada-master/pause:3.2 volumes: - name: etc-systemd-dir hostPath: path: /etc/systemd/system - name: etc-systctld-dir hostPath: path: /etc/sysctl.d - name: usr-local-bin hostPath: path: /usr/local/bin - name: script-config configMap: name: ibm-user-custom-configurator -
DaemonSet값을 편집하여 성능을 조정하십시오.
NUMBER_OF_HUGEPAGES-
할당할 대형 페이지 수를 입력하십시오. 예를 들어,
2048입니다. 대형 페이지를 사용하지 않으려면0를 입력하십시오. 대형 페이지를 많이 할당할수록 애플리케이션에 사용할 수 있는 전체 메모리가 줄어듭니다. TOPOLOGY_MANAGER_POLICY_VALUE-
사용하려는 토폴로지 관리자 정책을 입력합니다.
best-effort정책은 최대한의 예약 가용성을 보장하기 위해 권장됩니다. 그러나 다른 정책을 사용하여 워크로드 스케줄링 가용성을 줄이면서 더 엄격한 요구 사항 검증을 수행할 수 있습니다. 자세한 내용은 토폴로지 관리자를 참조하세요.nodeSelector섹션을 편집하여 작업자 노드의 서브세트에만 구성을 적용할 수 있습니다.
- 다음 명령을 실행하여
DaemonSet를 적용하십시오.kubectl replace --force -f customize.yaml - 팟 (Pod) 이
Running상태가 되었는지 확인하십시오.kubectl get pods -n kube-system -l app=ibm-user-custom-configurator -o wide - 팟 (Pod) 이 실행되면 각 작업자 노드를 다시 부팅하십시오.
- 워커 노드에 디버그 포드를 배포하세요.
oc debug node/NODE_NAME ``` 1. 디버그 세션이 시작된 후 다음 명령을 실행하십시오. ```sh {: pre} nsenter -t 1 -m -u -i -n -p -- reboot ``` 1. 재부팅하려는 각 워커 노드에 대해 이 단계를 반복하십시오.
작업자 노드에서 CPU 고정 및 대용량 페이지 사용
Satellite
시작하기 전에 Node Feature Discovery Operator 를 배치했는지 확인하십시오.
-
다음
DaemonSet을cpu-pinning.yaml파일에 저장하십시오.--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: ibm-user-custom-configurator-privileged roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:openshift:scc:privileged subjects: - kind: ServiceAccount name: ibm-user-custom-configurator namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: ibm-user-custom-configurator namespace: kube-system --- apiVersion: v1 kind: ConfigMap metadata: name: ibm-user-custom-configurator namespace: kube-system data: 89-hugepages.conf: | vm.nr_hugepages=<<NUMBER_OF_HUGEPAGES>> configure.sh: | #!/usr/bin/env bash set -x cp -f /scripts/ibm-user-custom-configuration.sh /host-usr-local-bin/ibm-user-custom-configuration.sh chmod 0755 /host-usr-local-bin/ibm-user-custom-configuration.sh cp -f /scripts/ibm-user-custom-configuration.service /host-etc-systemd-dir/ibm-user-custom-configuration.service chmod 0644 /host-etc-systemd-dir/ibm-user-custom-configuration.service if [[ -f /scripts/89-hugepages.conf ]]; then cp -f /scripts/89-hugepages.conf /host-etc-systctld-dir/89-hugepages.conf fi nsenter -t 1 -m -u -i -n -p -- systemctl daemon-reload nsenter -t 1 -m -u -i -n -p -- systemctl enable ibm-user-custom-configuration.service nsenter -t 1 -m -u -i -n -p -- systemctl start ibm-user-custom-configuration.service ibm-user-custom-configuration.sh: | #!/usr/bin/env bash set -x if cat /etc/kubernetes/kubelet.conf | jq -r .; then cat >/tmp/ibm-user-config.conf.json <<EOF { "cpuManagerPolicy": "static" } EOF if ! cat /tmp/ibm-user-config.conf.json | jq -r .; then exit 1 fi if ! jq -s '.[0] * .[1]' /tmp/ibm-user-config.conf.json /etc/kubernetes/kubelet.conf > /etc/kubernetes/tmp-kubelet.conf; then exit 1 fi mv -f /etc/kubernetes/tmp-kubelet.conf /etc/kubernetes/kubelet.conf else cat >/tmp/ibm-user-config.conf <<EOF #START USER CONFIG cpuManagerPolicy: static #END USER CONFIG EOF sed -i '/#START USER CONFIG/,/#END USER CONFIG/d' /etc/kubernetes/kubelet.conf cat /tmp/ibm-user-config.conf >>/etc/kubernetes/kubelet.conf fi ibm-user-custom-configuration.service: | [Unit] Description=Add custom user config to kubelet Before=kubelet.service After=kubelet-auto-node-size.service [Service] Type=oneshot RemainAfterExit=yes EnvironmentFile=/etc/node-sizing.env ExecStart=/usr/local/bin/ibm-user-custom-configuration.sh [Install] WantedBy=multi-user.target --- apiVersion: apps/v1 kind: DaemonSet metadata: labels: app: ibm-user-custom-configurator name: ibm-user-custom-configurator namespace: kube-system spec: selector: matchLabels: app: ibm-user-custom-configurator template: metadata: labels: app: ibm-user-custom-configurator spec: nodeSelector: ibm-cloud.kubernetes.io/os: RHCOS tolerations: - operator: "Exists" hostPID: true serviceAccount: ibm-user-custom-configurator initContainers: - name: configure image: "registry.access.redhat.com/ubi8/ubi:8.6" command: ['/bin/bash', '-c', 'mkdir /cache && cp /scripts/configure.sh /cache && chmod +x /cache/configure.sh && /bin/bash /cache/configure.sh'] securityContext: privileged: true volumeMounts: - mountPath: /scripts name: script-config - mountPath: /host-etc-systemd-dir name: etc-systemd-dir - mountPath: /host-usr-local-bin name: usr-local-bin - mountPath: /host-etc-systctld-dir name: etc-systctld-dir containers: - name: pause image: us.icr.io/armada-master/pause:3.2 volumes: - name: etc-systemd-dir hostPath: path: /etc/systemd/system - name: etc-systctld-dir hostPath: path: /etc/sysctl.d - name: usr-local-bin hostPath: path: /usr/local/bin - name: script-config configMap: name: ibm-user-custom-configurator -
DaemonSet값을 편집하여 성능을 조정하십시오.
NUMBER_OF_HUGEPAGES-
할당할 대형 페이지 수를 입력하십시오. 예를 들어,
2048입니다. 대형 페이지를 사용하지 않으려면0를 입력하십시오. 대형 페이지를 많이 할당할수록 애플리케이션에 사용할 수 있는 전체 메모리가 줄어듭니다.nodeSelector섹션을 편집하여 작업자 노드의 서브세트에만 구성을 적용할 수 있습니다.
- 다음 명령을 실행하여
DaemonSet를 적용하십시오.kubectl replace --force -f cpu-pinnning.yaml - 팟 (Pod) 이
Running상태가 되었는지 확인하십시오.kubectl get pods -n kube-system -l app=ibm-user-custom-configurator -o wide - 팟 (Pod) 이 실행되면 각 작업자 노드를 다시 부팅하십시오.
- 워커 노드에 디버그 포드를 배포하세요.
oc debug node/NODE_NAME ``` 1. 디버그 세션이 시작된 후 다음 명령을 실행하십시오. ```sh {: pre} nsenter -t 1 -m -u -i -n -p -- reboot ``` 1. 재부팅하려는 각 워커 노드에 대해 이 단계를 반복하십시오.
kernel-devel 패키지 사용
Satellite
Satellite 서비스 또는 스토리지 (예: Spectrum Scale Fusion) 를 사용하려면 kernel-devel 패키지를 사용으로 설정해야 합니다.
사용자 정의 구성 맵 및 머신 구성을 작업자 노드에 적용하여 kernel-devel 를 사용으로 설정하려면 다음 단계를 완료하십시오.
-
MachineConfig를 적용하려면 다음 명령을 실행하십시오.ibmcloud ks cluster config --cluster CLUSTERID cat >"/tmp/kernel-devel-payload.yaml" <<EOF apiVersion: v1 kind: List metadata: name: pvg-machine-config-tester annotations: items: - apiVersion: v1 kind: Namespace metadata: name: ibm-machine-config - apiVersion: v1 data: config: |+ apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: name: 97-kerneldevel labels: machineconfiguration.openshift.io/role: worker spec: config: ignition: version: 3.2.0 extensions: - kernel-devel kind: ConfigMap metadata: labels: ibm-cloud.kubernetes.io/user-specified-config: "true" name: user-ignition-config-97-kerneldevel namespace: ibm-machine-config EOF kubectl apply -f /tmp/kernel-devel-payload.yaml -
리소스가 배포될 때까지 기다리세요. 이 작업은 5분이상 소요될 수 있습니다.
-
구성 맵의 세부사항을 검토하여 배치가 성공했는지 확인하십시오.
config-validation="valid"필드가 있는지 확인하십시오.
kubectl get cm -n ibm-machine-config user-ignition-config-97-kerneldevel -o yaml | grep config-validation ``` 1. `user-ignition-config-97-kerneldevel` 가 구성 맵에 있는지 확인하십시오. ```sh {: pre} kubectl get cm -n ibm-machine-config -l ibm-cloud.kubernetes.io/nodepoolfeedback="true" -o yaml | grep user-ignition-config-97-kerneldevel ``` -
클러스터에 워커 노드를 추가하세요. 추가하는 작업자 노드에는
kernel-devel가 사용으로 설정되어 있습니다. -
kernel-devel가 활성화되어 있는지 확인하십시오.- 노드 중 하나에서 디버그 팟 (Pod) 을 시작하십시오.
oc debug node/NODEIP ``` 1. 다음 `nsenter` 명령을 실행하십시오. ```sh {: pre} nsenter -t 1 -m -u -i -n -p -- rpm -qa | grep kernel-devel ``` -
선택사항:
kernel-devel가 더 이상 필요하지 않은 경우 다음 명령을 실행하여 제거할 수 있습니다.kubectl delete cm -n ibm-machine-config user-ignition-config-97-kerneldevel
성능 사용자 정의 제거
Satellite
작업자 노드에서 사용자 정의를 제거하고 기본 구성으로 재설정하려면 다음 DaemonSet 을 적용하십시오.
-
다음
DaemonSet을remove-custom.yaml파일에 저장하십시오.--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: ibm-user-custom-configurator-privileged roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:openshift:scc:privileged subjects: - kind: ServiceAccount name: ibm-user-custom-configurator namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: ibm-user-custom-configurator namespace: kube-system --- apiVersion: v1 kind: ConfigMap metadata: name: ibm-user-custom-configurator namespace: kube-system data: 89-hugepages.conf: | vm.nr_hugepages=0 configure.sh: | #!/usr/bin/env bash set -x cp -f /scripts/ibm-user-custom-configuration.sh /host-usr-local-bin/ibm-user-custom-configuration.sh chmod 0755 /host-usr-local-bin/ibm-user-custom-configuration.sh cp -f /scripts/ibm-user-custom-configuration.service /host-etc-systemd-dir/ibm-user-custom-configuration.service chmod 0644 /host-etc-systemd-dir/ibm-user-custom-configuration.service if [[ -f /scripts/89-hugepages.conf ]]; then cp -f /scripts/89-hugepages.conf /host-etc-systctld-dir/89-hugepages.conf fi nsenter -t 1 -m -u -i -n -p -- systemctl daemon-reload nsenter -t 1 -m -u -i -n -p -- systemctl enable ibm-user-custom-configuration.service nsenter -t 1 -m -u -i -n -p -- systemctl start ibm-user-custom-configuration.service ibm-user-custom-configuration.sh: | #!/usr/bin/env bash set -x if cat /etc/kubernetes/kubelet.conf | jq -r .; then if ! jq 'del(.topologyManagerPolicy, .memoryManagerPolicy, .cpuManagerPolicy, .reservedMemory)' /etc/kubernetes/kubelet.conf > /etc/kubernetes/tmp-kubelet.conf; then exit 1 fi mv -f /etc/kubernetes/tmp-kubelet.conf /etc/kubernetes/kubelet.conf else sed -i '/#START USER CONFIG/,/#END USER CONFIG/d' /etc/kubernetes/kubelet.conf fi ibm-user-custom-configuration.service: | [Unit] Description=Add custom user config to kubelet Before=kubelet.service After=kubelet-auto-node-size.service [Service] Type=oneshot RemainAfterExit=yes EnvironmentFile=/etc/node-sizing.env ExecStart=/usr/local/bin/ibm-user-custom-configuration.sh [Install] WantedBy=multi-user.target --- apiVersion: apps/v1 kind: DaemonSet metadata: labels: app: ibm-user-custom-configurator name: ibm-user-custom-configurator namespace: kube-system spec: selector: matchLabels: app: ibm-user-custom-configurator template: metadata: labels: app: ibm-user-custom-configurator spec: nodeSelector: ibm-cloud.kubernetes.io/os: RHCOS tolerations: - operator: "Exists" hostPID: true serviceAccount: ibm-user-custom-configurator initContainers: - name: configure image: "registry.access.redhat.com/ubi8/ubi:8.6" command: ['/bin/bash', '-c', 'mkdir /cache && cp /scripts/configure.sh /cache && chmod +x /cache/configure.sh && /bin/bash /cache/configure.sh'] securityContext: privileged: true volumeMounts: - mountPath: /scripts name: script-config - mountPath: /host-etc-systemd-dir name: etc-systemd-dir - mountPath: /host-usr-local-bin name: usr-local-bin - mountPath: /host-etc-systctld-dir name: etc-systctld-dir containers: - name: pause image: us.icr.io/armada-master/pause:3.2 volumes: - name: etc-systemd-dir hostPath: path: /etc/systemd/system - name: etc-systctld-dir hostPath: path: /etc/sysctl.d - name: usr-local-bin hostPath: path: /usr/local/bin - name: script-config configMap: name: ibm-user-custom-configurator -
다음 명령을 실행하여 클러스터에 ‘
DaemonSet’를 적용하십시오.kubectl replace --force -f remove-custom.yaml -
팟 (Pod) 이
Running상태가 되었는지 확인하십시오.kubectl get pods -n kube-system -l app=ibm-user-custom-configurator -o wide -
팟 (Pod) 이 실행되면 각 작업자 노드를 다시 부팅하십시오.
- 워커 노드에 디버그 포드를 배포하세요.
oc debug node/NODE_NAME ``` 1. 디버그 세션이 시작된 후 다음 명령을 실행하십시오. ```sh {: pre} nsenter -t 1 -m -u -i -n -p -- reboot ``` 1. 재부팅하려는 각 워커 노드에 대해 이 단계를 반복하십시오.