내용으로 건너뛰기

Amazon EKS에서 Karpenter 오토 스케일링을 사용하여 클러스터 규모 조정 문제를 해결하려면 어떻게 해야 합니까?

9분 분량
0

Amazon Elastic Kubernetes Service(Amazon EKS)에서 Karpenter 오토스케일러를 사용하여 클러스터 규모 조정 문제를 해결하고 싶습니다.

해결 방법

수신한 오류 메시지를 기반으로 문제를 해결하십시오.

Amazon EKS 노드 그룹 인스턴스가 충분하지 않아 Karpenter 포드를 예약할 수 없음

참고: AWS Command Line Interface(AWS CLI) 명령을 실행할 때 오류가 발생하면 AWS CLI의 오류 해결을 참조하십시오. 또한 최신 AWS CLI 버전을 사용하고 있는지 확인하십시오.

Karpenter 버전 0.16.0 이상에서는 기본 복제본 수가 1에서 2로 변경되었습니다. 자세한 내용은 GitHub 웹 사이트의 v0.16.0을 참조하십시오. 클러스터의 노드 용량이 구성된 복제본 수를 지원할 만큼 충분하지 않은 경우 Karpenter 포드를 예약할 수 없습니다. Karpenter는 자체 포드를 실행하도록 노드를 프로비저닝할 수 없으므로 용량 부족으로 인해 실패하고 예약되지 않은 포드가 발생합니다. 그러면 다음과 같은 오류 메시지가 표시됩니다.

"Warning FailedScheduling 3m default-scheduler 0/1 nodes are available: 1 Insufficient memory."

이 오류를 해결하려면 다음 작업 중 하나를 수행하십시오.

Karpenter 배포 복제본을 하나로 줄이기

Karpenter 배포에 중복성이 필요하지 않은 경우 단일 복제본을 사용하도록 변경하십시오. 다음 명령을 실행합니다.

kubectl scale deployment karpenter --replicas=1

Karpenter 포드의 노드 용량 늘리기

Karpenter 복제본 2개를 실행하려면 복제본 2개에 충분한 용량이 있어야 합니다. 다음 옵션 중 하나를 선택합니다.

Auto Scaling 그룹 스케일 아웃

  1. Auto Scaling 그룹의 최소 인스턴스 수를 늘립니다. 다음 명령을 실행합니다.
    aws autoscaling update-auto-scaling-group --auto-scaling-group-name your-node-group-name --min-size 2 --desired-capacity 2
    참고: your-node-group-name을 Auto Scaling 그룹 이름으로 바꾸십시오.
  2. Karpenter에서 관리하지 않는 노드가 있는지 확인합니다. Karpenter 레이블의 노드 레이블(예: karpenter.sh/nodepool)을 확인합니다. 다음 명령을 실행합니다.
    kubectl get nodes --show-labels | grep karpenter.sh/nodepool

기존 노드 사용

대상 기존 노드에 karpenter.sh/nodepool과 같은 Karpenter 레이블이 있는 경우 레이블을 제거하십시오. 다음 명령을 실행합니다.

kubectl label nodes your-node-name karpenter.sh/nodepool-

참고: your-node-name을 노드 이름으로 바꾸십시오.

볼륨 연결 및 탑재 실패

영구 볼륨 클레임(PVC)이 있는 여러 포드가 동일한 노드에 예약되면 노드가 볼륨 연결 제한을 초과할 수 있습니다. 그러면 다음 오류 메시지 중 하나가 표시될 수 있습니다.

"Warning FailedAttachVolume pod/example-pod AttachVolume. Attach failed for volume " " : rpc error: code = Internal desc = Could not attach volume " " to node " ": attachment of disk " " failed, expected device to be attached but was attaching"

"Warning FailedMount pod/example-pod Unable to attach or mount volumes: unmounted volumes=[], unattached volumes=[]: timed out waiting for the condition"

PVC를 많이 사용하는 워크로드의 볼륨 연결 및 탑재 실패를 해결하려면 다음 단계를 완료하십시오.

  1. topologySpreadConstraints 및 podAntiAffinity를 적용하여 PVC를 많이 사용하는 포드가 동일한 노드에서 예약되는 것을 방지합니다. 자세한 내용은 Kubernetes 웹 사이트의 topologySpreadConstraints field 및 포드 선호도 예제를 참조하십시오. 이 작업은 PVC를 많이 사용하는 포드를 여러 노드에 분산하여 볼륨 연결이 단일 노드에 집중되는 것을 방지합니다.
  2. Amazon Elastic Block Store(Amazon EBS) 컨테이너 스토리지 인터페이스(CSI) 드라이버(aws-ebs-csi-driver)와 같은 CSI 드라이버를 사용하고 NodePool에 시작 테인트를 추가합니다. 이러한 작업을 통해 포드가 완전히 준비되기 전에 노드에서 조기에 예약되지 않도록 할 수 있습니다.
    Amazon EBS의 시작 테인트 구성 예시:
    --yaml--
    apiVersion: karpenter.sh/v1
    kind: NodePool
    spec:
      template:
        spec:
          startupTaints:
            - key: ebs.csi.aws.com/agent-not-ready
              effect: NoExecute
    

더 이상 사용되지 않는 스토리지 플러그인 오류

Karpenter는 Amazon EBS와 같이 더 이상 사용되지 않는 인트리 스토리지 플러그인을 지원하지 않습니다. 인트리 플러그인과 함께 정적으로 프로비저닝된 영구 볼륨(PV)을 사용하는 경우 Karpenter는 노드의 볼륨 연결 제한을 검색할 수 없습니다. 이 시나리오로 인해 예약이 실패할 수 있으며 다음과 같은 오류 메시지가 표시될 수 있습니다.

"ERROR controller.node_state PersistentVolume source 'AWSElasticBlockStore' uses an in-tree storage plugin which is unsupported by Karpenter and is deprecated by Kubernetes."

이 문제를 해결하려면 Amazon EBS용 CSI 드라이버를 사용하고 CSI 드라이버를 사용하도록 PV 구성을 업데이트하십시오.

지정되지 않은 리소스 요청으로 인한 예약 또는 빈팩 실패

Karpenter는 리소스 요청을 기반으로 포드를 빈패킹합니다. 요청이 너무 적거나 누락된 경우, Karpenter는 동일한 노드에 너무 많은 포드를 할당할 수 있습니다. 이 시나리오는 리소스 경합과 CPU 스로틀링으로 이어질 수 있습니다. 또한 메모리 제한이 설정되어 있고 포드가 제한보다 많은 메모리를 사용하려고 하면 메모리 부족(OOM) 종료가 발생할 수 있습니다. 다음과 같은 오류 메시지가 표시될 수 있습니다.

"Warning OOMKilled pod/your-pod-name Container "container-name" was killed due to OOM (Out of Memory). Memory limit: 512Mi, Memory usage: 513Mi"

이러한 문제를 방지하려면 LimitRange 구성을 사용하여 정확한 빈 패킹을 위한 최소 리소스 요청을 설정하십시오. LimitRange 구성은 최대 제한을 설정하여 과도한 소비를 방지하는 데 도움이 됩니다. 또한 지정되지 않은 포드에 대한 기본 제한을 제공합니다. 자세한 내용은 LimitRange를 사용하여 리소스 요청 및 제한에 대한 기본값 구성을 참조하십시오.

Windows 포드가 이미지 가져오기 오류로 인해 시작되지 않음

컨테이너 운영 체제(OS) 버전이 Windows OS 버전과 일치하지 않으면 포드가 시작되지 않습니다. 다음과 유사한 오류 메시지가 표시됩니다.

"Failed to pull image "mcr.microsoft.com/windows/servercore:xxx": rpc error: code = NotFound desc = failed to pull and unpack image "mcr.microsoft.com/windows/servercore:xxx": no match for platform in manifest: not found"

이 문제를 해결하려면 포드의 nodeSelector를 정의하여 컨테이너가 호환 가능한 OS 호스트 버전에서 예약되도록 해야 합니다. 자세한 내용은 Microsoft 웹 사이트에서 Windows 컨테이너 버전 호환성을 참조하십시오.

노드가 제대로 초기화되지 않음

시스템은 노드 준비 상태, 예상 리소스 등록 및 NodePool 시작 테인트 제거를 기반으로 노드 초기화를 결정합니다. 이러한 조건 중 하나라도 충족되지 않으면 Karpenter 노드가 제대로 초기화되지 않고 노드는 NotReady 상태로 유지됩니다. 따라서 시스템은 노드를 사용하여 워크로드를 예약하거나 통합할 수 없습니다. 다음과 같은 오류 메시지가 표시될 수 있습니다.

"Nodes provisioned by Karpenter are in a NotReady state"

노드 상태가 Ready인지 확인합니다. 그렇지 않은 경우 Kubelet 로그를 검사하여 권한, 보안 그룹 또는 네트워킹과 관련된 잠재적 문제를 파악하십시오.

nvidia.com/gpu 또는 vpc.amazonaws.com/pod-eni와 같은 모든 필수 리소스가 노드에 올바르게 등록되었는지 확인합니다.

노드에서 nvidia.com/gpu 리소스를 확인하려면 다음 명령을 실행합니다.

kubectl describe node your-node-name

참고: your-node-name을 노드 이름으로 바꾸십시오.

출력 예시:

...
Capacity:
  nvidia.com/gpu.shared: 80
...

이러한 리소스가 없는 경우 적절한 대몬셋 또는 플러그인이 실행 중인지 확인하십시오. 대몬셋을 확인하려면 다음 명령을 실행합니다.

kubectl get ds -n your-daemonset-namespace

참고: your-daemonset-namespace를 대몬셋 네임스페이스로 바꾸십시오.

다양한 제약 및 제한으로 인한 예약 실패

선호도, 비선호도 또는 토폴로지 분산 제약으로 인해 포드를 예약할 수 없음

선호도, 비선호도 또는 토폴로지 분산 제약에 특정 노드나 영역이 필요하지만 필수 위치에 적합한 노드가 없는 경우 포드는 예약되지 않습니다. 노드 또는 영역 요구 사항이 충족되지 않아 시스템에서 포드를 배치할 수 없는 경우 다음 오류 메시지가 표시될 수 있습니다.

"Warning FailedScheduling pod/"pod-name" 0/3 nodes are available: 1 node(s) didn't match pod affinity rules, 2 node(s) didn't match pod topology spread constraints rules, 3 nodes(s) didn't match inter-pod anti-affinity rules."

이 오류를 해결하려면 포드의 선호도 및 비선호도 설정 또는 토폴로지 분산 제약 조건을 검토하고 조정하여 사용 가능한 노드에 맞춰야 합니다. 이러한 제약 조건을 완화하거나 필요한 영역에 더 많은 노드를 프로비저닝할 수 있습니다.

리소스가 부족하여 포드를 예약하지 못함

사용 가능한 노드 용량을 초과하는 리소스 요청으로 인해 포드가 예약되지 않은 상태로 남아 있습니다. 포드를 수용하기에 충분한 CPU, 메모리 또는 기타 리소스를 갖춘 노드가 없는 경우, 다음과 같은 오류 메시지가 표시될 수 있습니다.

"Warning FailedScheduling 30s (x13 over 60m) default-scheduler 0/5 nodes are available: 1 Insufficient memory. preemption: 0/5 nodes are available: 5 No preemption victims found for incoming pod."

이 문제를 해결하려면 포드 사양의 리소스 요청이 실제 사용량을 반영하는지 확인하십시오. 필요한 경우 리소스 요청 및 제한을 조정하거나 리소스 수요를 충족할 수 있도록 용량을 늘려 더 큰 노드를 프로비저닝합니다.

테인트로 인해 포드가 예약되지 않음

클러스터 관리자가 특정 노드에 사용자 지정 테인트를 적용하면 포드의 톨러레이션이 일치해야 합니다. 일치하는 톨러레이션이 없는 경우 시스템은 해당 노드에서 포드를 예약할 수 없습니다. 다음 오류 메시지가 표시됩니다.

"0/5 nodes are available: 3 node(s) had taint {dedicated: gpu}, that the pod didn't tolerate, 2 node(s) had taint {dedicated: non-gpu}, that the pod didn't tolerate."

이 오류를 해결하려면 포드 사양에 적절한 톨러레이션을 추가하여 테인트를 허용하도록 합니다. 또는 너무 제한적인 경우 노드에서 불필요한 사용자 지정 테인트를 제거하거나 수정할 수 있습니다.

노드에서 테인트를 제거하려면 다음 명령을 실행합니다.

kubectl taint nodes your-node-name your-custom-taint-

참고: your-node-name을 노드 이름으로 바꾸고 your-custom-taint를 사용자 지정 테인트의 이름으로 바꾸십시오.

NodeAffinity 또는 NodeSelector 제약 조건이 충족되지 않음

클러스터의 사용 가능한 노드와 일치하지 않는 노드 선호도 또는 노드 선택기 제약이 있는 경우, 스케줄러는 포드를 배치할 수 없습니다. 다음 오류 메시지가 표시됩니다.

"Warning FailedScheduling  3m    default-scheduler 0/4 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 3 node(s) didn't satisfy existing pods anti-affinity rules, 4 node(s) didn't match Pod's node affinity rules."

이 오류를 해결하려면 포드의 노드 선호도 또는 노드 선택기 요구 사항을 좀 더 유연하게 수정합니다. 또는 필요한 경우 포드의 기준을 충족하는 추가 노드를 프로비저닝할 수 있습니다. 자세한 내용은 Kubernetes 웹 사이트에서 노드 선호도 및 nodeSelector를 참조하십시오.

서브넷의 IP 주소가 충분하지 않음

Karpenter가 새 노드를 프로비저닝하려고 하면 서브넷의 IP 주소가 충분하지 않아 실패합니다. 이 시나리오는 서브넷의 CIDR(Classless Inter-Domain Routing) 범위가 초과되어 새로운 Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스를 수용할 수 없을 때 발생합니다. 다음 오류 메시지가 표시됩니다.

"error": "creating machine, creating instance, with fleet error(s), InsufficientFreeAddressesInSubnet: There are not enough free addresses in subnet 'subnet-a to satisfy the requested number of instances."

이 오류를 해결하려면 다음 작업 중 하나를 수행하십시오.

서브넷의 IP 주소가 고갈된 경우 추가 IPv4 CIDR 블록을 Amazon Virtual Private Cloud(Amazon VPC)에 보조 CIDR로 더합니다.

-또는-

사용자 지정 네트워킹을 사용하여 포드와 노드에 별도의 IP 주소 공간을 할당합니다. 사용자 지정 네트워킹을 활성화하려면 다음 명령을 실행합니다.

kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true

사용자 지정 네트워킹에 대한 자세한 내용은 Amazon EKS 클러스터에서 포드의 특정 IP 주소 서브넷을 선택하려면 어떻게 해야 합니까?를 참조하십시오.

호환되지 않는 요구 사항으로 인해 포드를 예약할 수 없음

Karpenter는 노드 풀 구성에 정의된 값과 일치하지 않는 eks.amazonaws.com/nodegroup과 같은 노드 그룹 레이블을 지정하는 포드를 예약하지 못합니다. 이러한 불일치가 발생하면 필요한 노드 레이블이 없기 때문에 Karpenter는 노드에 포드를 배치할 수 없습니다. 다음 오류 메시지 중 하나가 표시됩니다.

"incompatible requirements, label \"eks.amazonaws.com/nodegroup\" does not have known values""

"incompatible requirements, key topology.kubernetes.io/zone, topology.kubernetes.io/zone In [us-east-1a] not in topology.kubernetes.io/zone In [us-east-1b us-east-1c]"

"incompatible requirements, key nodes.ktp.io/role, nodes.ktp.io/role In [ktp-atom-apps] not in nodes.ktp.io/role In [kube-apps]"

Karpenter에서 포드를 예약할 수 있도록 하려면 관리형 노드 그룹별 nodeSelector를 제거하여 이 오류를 해결합니다.

예:

kubectl edit pod your-pod-name
or  
kubectl edit deployment your-deployment-name
or
kubectl edit daemonset your-daemonset-name

참고: your-pod-name, your-deployment-name 또는 your-daemonset-name을 포드, 배포 또는 대몬셋의 이름으로 바꾸십시오.

노드 통합 실패

Karpenter의 노드 통합은 예약 제약 또는 포드 마이그레이션을 방해하는 특정 포드 구성으로 인해 실패할 수 있습니다.

예약 제약

다음과 같은 이유로 포드를 마이그레이션할 수 없는 경우 노드 통합이 실패합니다.

  • 포드 간 선호도 또는 비선호도: 다른 포드와 함께 배치해야 하거나 함께 배치하지 않는 포드
  • 토폴로지 분산 제약: 서로 다른 영역, 노드 또는 랙에 분산되어야 하는 포드
  • 기타 예약 제한 사항: 포드가 다른 노드로 이동하지 못하게 하는 기타 제약 조건

포드 선호도 및 비선호도 규칙을 검토하고 덜 제한적이도록 조정합니다. 토폴로지 분산 제약 조건을 조정하여 유연성을 높이고 너무 빠듯할 수 있는 기타 예약 제한을 허용하십시오.

포드별 방지

노드에서 실행되는 특정 유형의 포드가 있는 경우 Karpenter가 노드를 통합하지 못할 수 있습니다. Karpenter는 주석, 예약 제약, 포드 중단 예산(PDB) 또는 컨트롤러 소유자 부족으로 인해 이러한 포드를 제거할 수 없습니다. kube-scheduler가 기술적으로 포드를 다른 곳에 맞출 수 있더라도 Karpenter가 이러한 기본 설정을 위반하지 않기 때문에 통합이 실패할 수 있습니다.

AWS 공식업데이트됨 일 년 전