노드 및 가용 영역에 워크로드 분산 - AWS 권장 가이드

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

노드 및 가용 영역에 워크로드 분산

가용 영역 및 노드와 같은 장애 도메인에 워크로드를 분산하면 구성 요소 가용성이 향상되고 수평적으로 확장 가능한 애플리케이션의 장애 가능성이 줄어듭니다. 다음 섹션에서는 노드와 가용 영역에 워크로드를 분산하는 방법을 소개합니다.

포드 토폴로지 분산 제약 조건 사용

Kubernetes 포드 토폴로지 분산 제약 조건은 Kubernetes 스케줄러에 ReplicaSet 또는 StatefulSet에서 관리하는 포드를 다양한 장애 도메인(가용 영역, 노드 및 하드웨어 유형)에 분산하도록 지시합니다. 포드 토폴로지 분산 제약 조건을 사용하는 경우 다음을 수행할 수 있습니다.

  • 애플리케이션 요구 사항에 따라 여러 장애 도메인에 포드를 배포하거나 집중합니다. 예를 들어 복원력을 위해 포드를 배포하고 네트워크 성능을 위해 포드에 집중할 수 있습니다.

  • 가용 영역 간 분산 및 노드 간 분산과 같은 다양한 조건을 결합합니다.

  • 조건을 충족할 수 없는 경우 기본 작업을 지정합니다.

    • maxSkew 및의 조합과 whenUnsatisfiable: DoNotSchedule 함께 minDomains를 사용하여 스케줄러에 대한 하드 요구 사항을 생성합니다.

    • whenUnsatisfiable: ScheduleAnyway를 사용하여를 줄입니다maxSkew.

실패 영역을 사용할 수 없게 되면 해당 영역의 포드가 비정상이 됩니다. Kubernetes는 가능한 경우 분산 제약 조건을 준수하면서 포드를 다시 예약합니다.

포드 토폴로지 분산 제약 조건

다음 코드는 가용 영역 또는 노드 간에 포드 토폴로지 분산 제약 조건을 사용하는 예를 보여줍니다.

... spec: selector: matchLabels: app: <your-app-label> replicas: 3 template: metadata: labels: <your-app-label> spec: serviceAccountName: <ServiceAccountName> ... topologySpreadConstraints: - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: topology.kubernetes.io/zone # <---spread those pods evenly over all availability zones whenUnsatisfiable: ScheduleAnyway - labelSelector: matchLabels: app: <your-app-label> maxSkew: 1 topologyKey: kubernetes.io/hostname # <---spread those pods evenly over all nodes whenUnsatisfiable: ScheduleAnyway

기본 클러스터 전체 토폴로지 분산 제약 조건

Kubernetes는 노드와 가용 영역에 포드를 배포하기 위한 기본 토폴로지 분산 제약 조건 세트를 제공합니다.

defaultConstraints: - maxSkew: 3 topologyKey: "kubernetes.io/hostname" whenUnsatisfiable: ScheduleAnyway - maxSkew: 5 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway
참고

다양한 유형의 토폴로지 제약이 필요한 애플리케이션은 클러스터 수준 정책을 재정의할 수 있습니다.

기본 제약 조건은 높은를 설정maxSkew하므로 포드 수가 적은 배포에는 유용하지 않습니다. 현재 KubeSchedulerConfiguration는 Amazon EKS에서 변경할 수 없습니다. 다른 토폴로지 분산 제약 조건을 적용해야 하는 경우 아래 섹션과 같이 변경 승인 컨트롤러를 사용하는 것이 좋습니다. 대체 스케줄러를 실행하는 경우 기본 토폴로지 분산 제약 조건을 제어할 수도 있습니다. 그러나 사용자 지정 스케줄러를 관리하면 복잡성이 증가하고 클러스터 복원력과 HA에 영향을 미칠 수 있습니다. 이러한 이유로 토폴로지 분산 제약에만 대체 스케줄러를 사용하지 않는 것이 좋습니다.

토폴로지 분산 제약 조건에 대한 Gatekeeper 정책

토폴로지 분산 제약 조건을 적용하기 위한 또 다른 옵션은 Gatekeeper 프로젝트의 정책을 사용하는 것입니다. 게이트키퍼 정책은 애플리케이션 수준에서 정의됩니다.

다음 코드 예제에서는 배포를 위한 Gatekeeper OPA 정책 사용을 보여줍니다. 필요에 따라 정책을 수정할 수 있습니다. 예를 들어 레이블이 인 배포에만 정책을 적용HA=true하거나 다른 정책 컨트롤러를 사용하여 유사한 정책을 작성합니다.

이 첫 번째 예제는에서 ConstraintTemplate 사용되는를 보여줍니다k8stopologyspreadrequired_template.yml.

apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8stopologyspreadrequired spec: crd: spec: names: kind: K8sTopologySpreadRequired validation: openAPIV3Schema: type: object properties: message: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8stopologyspreadrequired get_message(parameters, _default) =3D msg { not parameters.message msg :=_default } get_message(parameters, _default) =3D msg { msg := parameters.message } violation[{"msg": msg}] { input.review.kind.kind ="Deployment" not input.review.object.spec.template.spec.topologySpreadConstraint def_msg :"Pod Topology Spread Constraints are required for Deployments" msg :get_message(input.parameters, def_msg) }

다음 코드는 constraints YAML 매니페스트를 보여줍니다k8stopologyspreadrequired_constraint.yml.

apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sTopologySpreadRequired metadata: name: require-topologyspread-for-deployments spec: match: kinds: - apiGroups: ["apps"] kinds: ["Deployment"] namespaces: ## Without theses two lines will apply to the whole cluster - "example"

토폴로지 분산 제약 조건을 사용해야 하는 경우

다음 시나리오에서는 토폴로지 분산 제약 조건을 사용하는 것이 좋습니다.

  • 수평적으로 확장 가능한 애플리케이션(예: 상태 비저장 웹 서비스)

  • 액티브-액티브 또는 액티브-패시브 복제본이 있는 애플리케이션(예: NoSQL 데이터베이스 또는 캐시)

  • 대기 복제본이 있는 애플리케이션(예: 컨트롤러)

예를 들어 수평적으로 확장 가능한 시나리오에 사용할 수 있는 시스템 구성 요소에는 다음이 포함됩니다.

포드 친화도 및 안티 친화도

경우에 따라 노드에서 특정 유형의 포드가 하나 이상 실행되지 않도록 하는 것이 좋습니다. 예를 들어 동일한 노드에서 네트워크 중심 포드를 여러 개 예약하지 않으려면 레이블 Ingress 또는와 함께 안티 친화도 규칙을 사용할 수 있습니다Network-heavy. 를 사용할 때 다음 조합을 사용할 anti-affinity수도 있습니다.

  • 네트워크 최적화 노드의 테인트

  • 네트워크 중심 포드의 해당 허용치

  • 네트워크 중심 포드가 네트워크 최적화 인스턴스를 사용하도록 하는 노드 선호도 또는 노드 선택기

네트워크 중심 포드가 예로 사용됩니다. GPU, 메모리 또는 로컬 스토리지와 같은 요구 사항이 다를 수 있습니다. 기타 사용 예제 및 구성 옵션은 Kubernetes 설명서를 참조하세요.

포드 리밸런싱

이 섹션에서는 Kubernetes 클러스터에서 포드 리밸런싱을 위한 두 가지 접근 방식을 설명합니다. 첫 번째는 Kubernetes용 Descheduler를 사용합니다. Descheduler는 토폴로지 분산 제약 조건 또는 친화도 방지 규칙을 위반하는 포드를 제거하는 전략을 적용하여 포드 분산을 유지하는 데 도움이 됩니다. 두 번째 접근 방식은 Karpenter 통합 및 빈 패키징 기능을 사용합니다. 통합은 워크로드를 더 적고 효율적으로 패킹된 노드로 통합하여 리소스 사용량을 지속적으로 평가하고 최적화합니다.

Karpenter를 사용하지 않는 경우 Descheduler를 사용하는 것이 좋습니다. Karpenter와 Cluster Autoscaler를 함께 사용하는 경우 노드 그룹에 대해 Descheduler를 Cluster Autoscaler와 함께 사용할 수 있습니다.

그룹 없는 노드의 디스케줄러

포드를 제거할 때 토폴로지 제약 조건이 충족된다는 보장은 없습니다. 예를 들어 배포를 축소하면 포드 배포가 불균형해질 수 있습니다. 그러나 Kubernetes는 예약 단계에서만 포드 토폴로지 분산 제약 조건을 사용하므로 포드는 장애 도메인 전체에서 불균형하게 유지됩니다.

이러한 시나리오에서 균형 잡힌 포드 배포를 유지하려면 Descheduler for Kubernetes를 사용할 수 있습니다. Descheduler는 최대 포드 수명 또는 TTL(Time to Live)을 적용하거나 인프라 사용을 개선하는 등 여러 용도로 유용한 도구입니다. 복원력 및 고가용성(HA)의 맥락에서 다음 Descheduler 전략을 고려하세요.

Karpenter 통합 및 빈 패키징 기능

Karpenter를 사용하는 워크로드의 경우 통합 및 빈 패키징 기능을 사용하여 리소스 사용률을 최적화하고 Kubernetes 클러스터의 비용을 절감할 수 있습니다. Karpenter는 포드 배치 및 노드 사용률을 지속적으로 평가하고 가능한 경우 워크로드를 더 적은 수의 더 효율적으로 패킹된 노드로 통합하려고 시도합니다. 이 프로세스에는 리소스 요구 사항 분석, 포드 선호도 규칙과 같은 제약 조건 고려, 전체 클러스터 효율성을 개선하기 위해 노드 간에 포드 이동이 포함됩니다. 다음 코드는 예제를 제공합니다.

apiVersion: karpenter.sh/v1beta1 kind: NodePool metadata: name: default spec: disruption: consolidationPolicy: WhenUnderutilized expireAfter: 720h

consolidationPolicy경우 WhenUnderutilized 또는를 사용할 수 있습니다WhenEmpty.

  • consolidationPolicy를 로 설정하면 WhenUnderutilizedKarpenter는 통합을 위해 모든 노드를 고려합니다. Karpenter가 비어 있거나 사용률이 낮은 노드를 발견하면 Karpenter는 비용을 절감하기 위해 노드를 제거하거나 교체하려고 시도합니다.

  • consolidationPolicy를 로 설정하면 WhenEmptyKarpenter는 워크로드 포드가 없는 통합 전용 노드를 고려합니다.

Karpenter 통합 결정은 모니터링 도구에서 볼 수 있는 CPU 또는 메모리 사용률만을 기반으로 하지 않습니다. 대신 Karpenter는 포드 리소스 요청 및 잠재적 비용 최적화를 기반으로 보다 복잡한 알고리즘을 사용합니다. 자세한 내용은 Karpenter 설명서를 참조하세요.