다음을 통해 공유


AKS(Azure Kubernetes Service)에서 NAP(노드 자동 프로비저닝) 노드에 대한 노드 중단 정책 구성

이 문서에서는 AKS(Azure Kubernetes Service) 노드 NAP(자동 프로비저닝) 노드에 대한 노드 중단 정책을 구성하는 방법과 리소스 사용률 및 비용 효율성을 최적화하기 위해 중단이 작동하는 방식을 자세히 설명합니다.

NAP는 다음을 통해 클러스터를 최적화합니다.

  • 사용량이 부족한 노드를 제거하거나 대체합니다.
  • 워크로드를 통합하여 비용을 절감합니다.
  • 중단 예산 및 유지 관리 기간을 준수합니다.
  • 필요한 경우 수동 제어를 제공합니다.

시작하기 전 주의 사항:

NAP 노드의 노드 중단은 어떻게 작동하나요?

Karpenter는 프로비전하는 각 노드와 노드 클레임에 Kubernetes 파이널라이저를 설정합니다. 종료자는 노드 개체의 삭제를 차단하고 종료 컨트롤러는 기본 노드 클레임을 제거하기 전에 노드를 오염시키고 드레이닝합니다.

노드의 워크로드가 축소되면 NAP는 노드 풀 사양의 중단 규칙을 사용하여 해당 노드를 제거하는 시기와 방법을 결정하고 효율성을 위해 워크로드를 다시 예약할 수 있습니다.

노드 중단 방법

NAP는 자동으로 중단에 적합한 노드를 검색하고 필요할 때 교체를 스핀업합니다. 만료, 통합Drift, 수동 메서드 또는 외부 시스템과 같은 자동화된 메서드를 통해 중단을 트리거할 수 있습니다.

Expiration

만료를 사용하면 NAP 노드의 최대 기간을 설정할 수 있습니다. 노드는 노드 풀 spec.disruption.expireAfter 의 값에 대해 지정한 연령에 도달한 후 만료되고 중단된 것으로 표시됩니다.

만료 구성 예제

다음 예제에서는 NAP 노드의 만료 시간을 24시간으로 설정하는 방법을 보여 줍니다.

spec:
  disruption:
    expireAfter: 24h  # Expire nodes after 24 hours

Consolidation

NAP는 노드가 비어 있거나 사용이 부족하여 제거할 수 있는 시기 또는 노드를 더 낮은 가격의 변형으로 대체할 수 있는 시기를 식별하여 클러스터 비용을 적극적으로 절감합니다. 이 프로세스를 통합이라고 합니다. NAP는 주로 통합을 사용하여 최적의 Pod 배치를 위해 노드를 삭제하거나 대체합니다.

NAP는 리소스 사용률을 최적화하기 위해 다음과 같은 유형의 통합을 수행합니다.

  • 빈 노드 통합: 빈 노드를 병렬로 삭제합니다.
  • 다중 노드 통합: 여러 노드를 삭제하여 단일 대체를 시작할 수 있습니다.
  • 단일 노드 통합: 단일 노드를 삭제하여 대체를 시작할 수 있습니다.

노드 풀 사양의 spec.disruption.consolidationPolicy 필드를 통해 WhenEmpty 또는 WhenEmptyOrUnderUtilized 설정을 사용하여 통합을 트리거할 수 있습니다. 필드 consolidateAfter를 설정할 수도 있으며, 이는 통합 기회를 발견한 후 노드를 중단하기 전에 NAP가 대기하는 시간을 결정하는 시간 기반 조건입니다.

통합 구성 예제

다음 예제에서는 노드가 비어 있을 때 노드를 통합하도록 NAP를 구성하고 노드를 중단하기 전에 통합 기회를 검색한 후 30초 동안 대기하는 방법을 보여 줍니다.

  disruption:
    # Describes which types of nodes NAP should consider for consolidation
    # `WhenEmptyOrUnderUtilized`: NAP considers all nodes for consolidation and attempts to remove or replace nodes when it discovers that the node is empty or underutilized and could be changed to reduce cost
    # `WhenEmpty`: NAP only considers nodes for consolidation that don't contain any workload pods
    
    consolidationPolicy: WhenEmpty

    # The amount of time NAP should wait after discovering a consolidation decision
    # Currently, you can only set this value when the consolidation policy is `WhenEmpty`
    # You can choose to disable consolidation entirely by setting the string value `Never`
    consolidateAfter: 30s

Drift

Drift는 리소스에 NodePool/AKSNodeClass 대한 변경 내용을 처리합니다. 값은 NodeClaimTemplateSpec/AKSNodeClassSpec 설정된 것과 동일한 방식으로 반영됩니다. 연결된 NodePool/AKSNodeClass의 값이 NodeClaim의 값과 일치하지 않으면 NodeClaim은(는) 드리프트됨으로 감지됩니다. Pod에 대한 업스트림 deployment.spec.template 관계와 마찬가지로 Karpenter는 드리프트를 확인하기 위해 연결된 NodePool/AKSNodeClassNodeClaimTemplateSpec의 해시와 함께 주석으로 추가합니다. Karpenter는 다음 시나리오에서 Drifted 상태 조건을 제거합니다.

  • Drift 기능 게이트는 활성화되지 않았지만 NodeClaim은 드리프트되었습니다.
  • NodeClaim은 드리프트되지 않지만 상태 조건이 있습니다.

Karpenter 또는 클라우드 공급자 인터페이스는 변경에 의해NodeClaim/Instance/NodePool/트리거되는 AKSNodeClass 검색할 수 있습니다.

드리프트의 특수 사례

특별한 경우 드리프트는 여러 값에 해당할 수 있으며 다르게 처리해야 합니다. 확인된 필드의 드리프트는 CRD(사용자 지정 리소스 정의)를 변경하지 않고 드리프트가 발생하거나 CRD 변경으로 인해 드리프트가 발생하지 않는 경우를 만들 수 있습니다.

예를 들어, NodeClaimnode.kubernetes.io/instance-type: Standard_D2s_v3일 때, 요구 사항이 node.kubernetes.io/instance-type In [Standard_D2s_v3]에서 node.kubernetes.io/instance-type In [Standard_D2s_v3, Standard_D4s_v3]로 변경되어도 값 NodeClaim은 여전히 새로운 요구 사항과 호환되기 때문에 표류하지 않습니다. 반대로, NodeClaimNodeClaimimageFamily을(를) 사용하지만, spec.imageFamily 필드가 변경되는 경우, Karpenter는 NodeClaim을(를) 드리프트된 것으로 감지하고 해당 사양에 맞게 노드를 회전시킵니다.

중요합니다

Karpenter는 서브넷 구성 변경을 모니터링하고, AKSNodeClass에서 vnetSubnetID이 수정될 때 드리프트를 감지합니다. 사용자 지정 네트워킹 구성을 관리할 때는 이 동작을 이해하는 것이 중요합니다. 자세한 내용은 서브넷 드리프트 동작을 참조하세요.

자세한 내용은 Drift 디자인을 참조하세요.

종료 유예 기간

노드 풀 사양의 필드를 사용하여 NAP 노드에 spec.template.spec.terminationGracePeriod 대한 종료 유예 기간을 설정할 수 있습니다. 이 설정을 사용하면 Karpenter가 Pod가 정상적으로 종료되기를 기다리는 시간을 구성할 수 있습니다. 이 설정은 Pod의 terminationGracePeriodSeconds보다 우선하며, PodDisruptionBudgets을 우회하고 주석 karpenter.sh/do-not-disrupt을 무시합니다.

종료 유예 기간 구성 예제

다음 예제에서는 NAP 노드에 대해 종료 유예 기간을 30초로 설정하는 방법을 보여 줍니다.

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      terminationGracePeriod: 30s

중단 예산

노드 풀 사양에서 spec.disruption.budgets 필드를 수정하여 Karpenter의 중단을 제한할 수 있습니다. 이 설정을 정의되지 않은 상태로 두면 Karpenter는 기본적으로 1개의 예산으로 nodes: 10%설정됩니다. Karpenter는 어떤 이유로든 삭제되는 노드를 예산에 반영하고, 만료, 드리프트, 유휴 상태, 통합 등을 통해 자발적인 중단을 방지하는 역할만 수행합니다.

예산이 노드 중단으로부터 차단하는지 계산할 때, Karpenter는 노드 풀이 소유한 총 노드 수를 계산한 후, 삭제 중인 노드와 NotReady인 노드를 제외합니다. 예산이 백분율 값(예: ) 20%으로 구성된 경우 Karpenter는 허용되는 중단 수를 다음과 같이 allowed_disruptions = roundup(total * percentage) - total_deleting - total_notready계산합니다. 노드 풀에서 여러 예산의 경우 Karpenter는 각 예산의 최소(가장 제한적인) 값을 사용합니다.

일정 및 기간 필드

예산을 사용할 때, 필요에 따라 scheduleduration 필드를 설정하여 시간 기반 예산을 만들 수 있습니다. 이러한 필드를 사용하면 중단 제한이 더 엄격한 경우 유지 관리 기간 또는 특정 기간을 정의할 수 있습니다.

  • 일정은 , 등의 @yearly@monthly@weekly@daily@hourly특수 매크로와 함께 cron 작업 구문을 사용합니다.
  • 기간10h5m, 30m, 160h와 같은 복합 기간을 허용합니다. 기간과 일정을 함께 정의해야 합니다.

일정 및 기간 예제

유지 관리 기간 예산

업무 시간 동안 중단 방지:

budgets:
- nodes: "0"
  schedule: "0 9 * * 1-5"  # 9 AM Monday-Friday
  duration: 8h             # For 8 hours
주말에만 발생하는 중단

주말에만 중단을 허용합니다.

budgets:
- nodes: "50%"
  schedule: "0 0 * * 6"    # Saturday midnight
  duration: 48h            # All weekend
- nodes: "0"               # Block all other times
점진적 출시 예산

중단률 증가 허용:

budgets:
- nodes: "1"
  schedule: "0 2 * * *"    # 2 AM daily
  duration: 2h
- nodes: "3"
  schedule: "0 4 * * *"    # 4 AM daily
  duration: 4h

예산 구성 예제

다음 NodePool 사양에는 세 개의 예산이 구성되어 있습니다.

  • 첫 번째 예산을 사용하면 노드 풀이 소유한 노드의 20%가 한 번에 중단될 수 있도록 허용합니다.
  • 두 번째 예산은 한도의 역할을 하며 노드가 25개가 넘는 경우에만 5개의 중단을 허용합니다.
  • 마지막 예산은 매일 처음 10분 동안 중단을 차단합니다.
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    expireAfter: 720h # 30 * 24h = 720h
    budgets:
    - nodes: "20%"      # Allow 20% of nodes to be disrupted
    - nodes: "5"        # Cap at maximum 5 nodes
    - nodes: "0"        # Block all disruptions during maintenance window
      schedule: "@daily" # Scheduled daily
      duration: 10m # Duration of 10 minutes

수동 노드 장애

kubectl을 사용하여 NAP 노드를 수동으로 중단하거나 NodePool 리소스를 삭제하여 중단할 수 있습니다.

kubectl을 사용하여 노드 제거

명령을 사용하여 kubectl delete node 노드를 수동으로 제거할 수 있습니다. 레이블을 사용하여 특정 노드, 모든 NAP 관리 노드 또는 노드를 특정 노드 풀에서 삭제할 수 있습니다. 예를 들면 다음과 같습니다.

# Delete a specific node
kubectl delete node $NODE_NAME

# Delete all NAP-managed nodes
kubectl delete nodes -l karpenter.sh/nodepool

# Delete nodes from a specific nodepool
kubectl delete nodes -l karpenter.sh/nodepool=$NODEPOOL_NAME

리소스 삭제 NodePool

NodePool는 소유자 참조를 통해 NodeClaims을 소유하고 있습니다. NAP는 연결된 NodePool노드를 삭제할 때 연속 삭제를 통해 노드를 정상적으로 종료합니다.

주석을 사용하여 장애를 제어하십시오.

주석을 사용하여 특정 Pod, 노드 또는 전체 노드 풀에 대한 방해를 차단하거나 비활성화할 수 있습니다.

Pod 제어

NAP가 특정 Pod를 방해하지 않도록 주석 karpenter.sh/do-not-disrupt: "true"을 설정합니다.

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"

이 주석은 만료, 통합 및 Drift에 대한 자발적인 중단을 방지합니다. 외부 시스템의 방해나 수동적 방해 및 kubectl 또는 NodePool 삭제를 방지하지는 않습니다.

노드 컨트롤

NAP가 특정 노드를 중단하지 못하도록 차단합니다.

apiVersion: v1
kind: Node
metadata:
  annotations:
    karpenter.sh/do-not-disrupt: "true"

노드 풀 컨트롤

NodePool의 모든 노드에 대한 중단을 비활성화하세요.

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "true"

다음 단계

AKS의 노드 자동 프로비저닝에 대한 자세한 내용은 다음 문서를 참조하세요.