Amazon EKS의 애플리케이션 로드 밸런싱 - Amazon EKS

Amazon EKS의 애플리케이션 로드 밸런싱

Kubernetes ingress를 생성할 때 애플리케이션 트래픽을 로드 밸런싱하는 AWS Application Load Balancer(ALB)가 프로비저닝됩니다. 자세한 내용은 Application Load Balancer 사용 설명서Application Load Balancer란 무엇인가요? 및 Kubernetes 설명서의 수신을 참조하세요. ALB는 노드 또는 AWS Fargate에 배포되는 pods와 함께 사용됩니다. ALB를 퍼블릭 또는 프라이빗 서브넷에 배포할 수 있습니다.

애플리케이션 트래픽은 OSI 모델의 L7에서 로드 밸런싱됩니다. L4에서 네트워크 트래픽을 로드 밸런싱하려면 LoadBalancer 유형의 Kubernetes service를 배포합니다. 이 유형은 AWS Network Load Balancer를 프로비저닝합니다. 자세한 내용은 Amazon EKS의 네트워크 로드 밸런싱을 참조하세요. 두 가지 유형의 로드 밸런싱 간의 차이점에 대한 자세히 알아보려면 AWS 웹 사이트에서 Elastic Load Balancing 기능 섹션을 참조하세요.

사전 조건

애플리케이션에 대한 애플리케이션 트래픽의 로드를 분산하려면 먼저 다음 요구 사항을 충족해야 합니다.

  • 기존 클러스터 보유 기존 클러스터가 없는 경우 Amazon EKS 시작하기 섹션을 참조하세요. 기존 클러스터의 버전을 업데이트해야 하는 경우에는 Amazon EKS 클러스터 Kubernetes 버전 업데이트 섹션을 참조하세요.

  • 클러스터에 배포된 AWS Load Balancer Controller가 있습니다. 자세한 내용은 AWS Load Balancer Controller 추가 기능 설치을 참조하세요. 2.4.2 이상 클러스터의 경우 버전 1.19 이상을 사용하는 것이 좋습니다. 클러스터가 1.19 이전 버전인 경우 버전 2.3.1을 사용하는 것이 좋습니다.

  • 서로 다른 가용 영역에 두 개 이상의 서브넷이 있습니다. AWS Load Balancer Controller는 각 가용 영역에서 서브넷을 하나씩 선택합니다. 가용 영역에서 태그가 지정된 서브넷이 여러 개 있는 경우 컨트롤러는 서브넷 ID가 사전 순으로 가장 먼저 표시되는 서브넷을 선택합니다. 각 서브넷에는 최소 8개의 사용 가능한 IP 주소가 있어야 합니다.

    작업자 노드에 연결된 여러 보안 그룹을 사용하는 경우 정확히 하나의 보안 그룹에 다음과 같이 태그를 지정해야 합니다. cluster-name을 클러스터 이름으로 교체합니다.

    • - kubernetes.io/cluster/cluster-name

    • - shared 또는 owned

  • AWS Load Balancer Controller 버전 2.1.1 이하를 사용하는 경우 서브넷에 다음과 같은 형식으로 태그를 지정해야 합니다. 버전 2.1.2 이상을 사용하는 경우 태그 지정은 선택 사항입니다. 그러나 다음 중 하나라도 해당되는 경우 서브넷에 태그를 지정하는 것이 좋습니다. 동일한 VPC에서 실행 중인 클러스터가 여러 개 있거나 VPC에서 서브넷을 공유하는 AWS 서비스가 여러 개 있습니다. 또는 각 클러스터에 대해 로드 밸런서가 프로비저닝되는 위치를 보다 정밀하게 제어하려 합니다. cluster-name을 클러스터 이름으로 교체합니다.

    • - kubernetes.io/cluster/cluster-name

    • - shared 또는 owned

  • 퍼블릭 및 프라이빗 서브넷은 다음 요구 사항을 충족해야 합니다. 서비스 또는 수신 개체에서 서브넷 ID를 주석으로 명시적으로 지정하지 않는 한 마찬가지입니다. 서브넷 ID를 서비스 또는 수신 개체에 주석으로 명시적으로 지정하여 로드 밸런서를 프로비저닝한다고 가정합니다. 이 상황에서 Kubernetes 및 AWS 로드 밸런서 컨트롤러는 이러한 서브넷을 직접 사용하여 로드 밸런서를 생성하며 다음 태그는 필요하지 않습니다.

    • 프라이빗 서브넷(Private subnets) - 다음 형식으로 태그를 지정해야 합니다. 이렇게 하면 Kubernetes 및 AWS 로드 밸런서 컨트롤러가 서브넷을 내부 로드 밸런서에 사용할 수 있음을 알 수 있습니다. 2020년 3월 26일 이후에 eksctl 또는 Amazon EKS AWS CloudFormation 템플릿을 사용하여 VPC를 생성하는 경우 서브넷은 생성될 때 적절하게 태그 지정됩니다. Amazon EKS AWS CloudFormation VPC 템플릿에 대한 자세한 내용은 Amazon EKS 클러스터에 대해 VPC 생성를 참조하세요.

      • - kubernetes.io/role/internal-elb

      • - 1

    • 퍼블릭 서브넷(Public subnets) - 다음 형식으로 태그를 지정해야 합니다. 이렇게 하면 Kubernetes에서 외부 로드 밸런서에 지정된 서브넷만 사용할 수 있음을 알 수 있습니다. 따라서 Kubernetes는 각 가용 영역에서 퍼블릭 서브넷을 선택하지 않습니다(서브넷 ID를 기준으로 사전 순으로). 2020년 3월 26일 이후에 eksctl 또는 Amazon EKS AWS CloudFormation 템플릿을 사용하여 VPC를 생성하는 경우 서브넷은 생성될 때 적절하게 태그 지정됩니다. Amazon EKS AWS CloudFormation VPC 템플릿에 대한 자세한 내용은 Amazon EKS 클러스터에 대해 VPC 생성를 참조하세요.

      • - kubernetes.io/role/elb

      • - 1

    서브넷 역할 태그가 명시적으로 추가되지 않은 경우 Kubernetes 서비스 컨트롤러는 클러스터 VPC 서브넷의 라우팅 테이블을 검사합니다. 이는 서브넷이 프라이빗 또는 퍼블릭 서브넷인지 확인하기 위함입니다. 이 동작에는 의존하지 않는 것이 좋습니다. 대신 프라이빗 또는 퍼블릭 역할 태그를 명시적으로 추가합니다. AWS Load Balancer Controller에서는 라우팅 테이블을 검사하지 않습니다. 또한 자동 검색에 성공하려면 프라이빗 및 퍼블릭 태그가 있어야 합니다.

고려 사항

  • AWS Load Balancer Controllerkubernetes.io/ingress.class: alb 주석을 사용하여 클러스터에 Kubernetes 수신 리소스가 생성될 때마다 ALB 및 필요한 지원 AWS 리소스를 생성합니다. 수신 리소스는 ALB를 구성하여 HTTP 또는 HTTPS 트래픽을 클러스터 내 다른 pods로 라우팅합니다. 수신 객체에서 AWS Load Balancer Controller를 사용하는지 확인하려면 Kubernetes 수신 사양에 다음 주석을 추가합니다. 자세한 내용은 GitHub의 수신 사양을 참조하세요.

    annotations: kubernetes.io/ingress.class: alb
    참고

    IPv6 pods로 로드 밸런싱하는 경우 수신 사양에 다음 주석을 추가합니다. IPv6를 통해서는 인스턴스 대상이 아닌 IP 대상으로만 로드 밸런싱할 수 있습니다. 이 주석이 없으면 로드 밸런싱은 IPv4를 통해 이루어집니다.

    alb.ingress.kubernetes.io/ip-address-type: dualstack
  • AWS Load Balancer Controller는 다음과 같은 트래픽 모드를 지원합니다.

    • 인스턴스 - 클러스터 내의 노드를 ALB의 대상으로 등록합니다. ALB에 도달하는 트래픽은 서비스를 위해 pods로 라우팅된 다음 NodePort로 프록시됩니다. 이것이 기본 트래픽 모드입니다. alb.ingress.kubernetes.io/target-type: instance 주석을 사용하여 명시적으로 지정할 수도 있습니다.

      참고

      Kubernetes 서비스에서 NodePort 또는 이 트래픽 모드를 사용할 ‘LoadBalancer’ 유형을 지정해야 합니다.

    • IP - pods를 ALB의 대상으로 등록합니다. ALB에 도달하는 트래픽은 서비스를 위해 pods로 직접 라우팅됩니다. 이 트래픽 모드를 사용하려면 alb.ingress.kubernetes.io/target-type: ip 주석을 지정해야 합니다. Fargate에서 대상 pods가 실행 중인 경우 IP 대상 유형이 필요합니다.

  • 컨트롤러에 의해 생성 된 ALB에 태그를 지정하려면 컨트롤러에 다음 주석을 추가합니다. alb.ingress.kubernetes.io/tags. AWS Load Balancer Controller에서 지원하는 모든 사용 가능한 주석의 목록은 GitHub의 수신 주석을 참조하세요.

  • ALB 컨트롤러 버전을 업그레이드하거나 다운그레이드하면 해당 버전에 의존하는 기능에 새로운 변경 사항이 발생할 수 있습니다. 각 릴리스에서 발생하는 새로운 변경 사항에 대한 자세한 내용은 GitHub의 ALB 컨트롤러 릴리스 정보를 참조하세요.

IngressGroups를 사용하여 여러 서비스 리소스 간에 Application Load Balancer 공유

그룹 수신에 가입하려면 Kubernetes 수신 리소스 사양에 다음 주석을 추가합니다.

alb.ingress.kubernetes.io/group.name: my-group

그룹 이름은 다음과 같아야 합니다.

  • 63자 이하의 길이여야 합니다.

  • 소문자, 숫자, -.으로 구성됩니다.

  • 글자나 숫자로 시작하고 끝납니다.

컨트롤러는 동일한 수신 그룹에 있는 모든 수신에 대한 수신 규칙을 자동으로 병합하고 단일 ALB로 지원합니다. 수신에 정의된 대부분의 주석은 해당 수신에 의해 정의된 경로에만 적용됩니다. 기본적으로 수신 리소스는 수신 그룹에 속하지 않습니다.

주의

잠재적 보안 위험: 수신 리소스를 만들거나 수정할 수 있는 RBAC 권한이 있는 모든 Kubernetes 사용자가 동일한 신뢰 경계 내에 있는 경우에만 수신에 대한 수신 그룹을 지정합니다. 그룹 이름을 사용하여 주석을 추가하는 경우 다른 Kubernetes 사용자가 동일한 수신 그룹에 속하도록 해당 수신을 생성하거나 수정할 수 있습니다. 이렇게 하면 기존 규칙을 우선 순위가 높은 규칙으로 덮어쓰는 것과 같이 바람직하지 않은 동작이 발생할 수 있습니다.

수신 리소스의 주문 번호를 추가할 수 있습니다.

alb.ingress.kubernetes.io/group.order: '10'

숫자는 1~1,000 사이일 수 있습니다. 동일한 수신 그룹의 모든 수신 중 가장 낮은 수가 먼저 평가됩니다. 이 주석이 없는 모든 수신은 값이 0인 것으로 평가됩니다. 숫자가 높은 중복 규칙은 낮은 수의 규칙을 덮어쓸 수 있습니다. 기본적으로 동일한 수신 그룹 내의 수신 간의 규칙 순서는 네임스페이스 및 이름을 기준으로 사전 순으로 결정됩니다.

중요

동일한 수신 그룹의 각 수신에 고유한 우선 순위 번호가 있는지 확인합니다. 수신에서 중복 주문 번호를 사용할 수 없습니다.

(선택 사항) 샘플 애플리케이션을 배포합니다.

사전 조건

  • 클러스터 VPC의 퍼블릭 또는 프라이빗 서브넷 하나 이상.

  • 클러스터에 배포된 AWS Load Balancer Controller가 있습니다. 자세한 내용은 AWS Load Balancer Controller 추가 기능 설치을 참조하세요. 버전 2.4.2 이상을 사용하는 것이 좋습니다.

샘플 애플리케이션을 배포하려면

Amazon EC2 노드가 있거나 Fargate pods가 있거나 둘 다 있는 클러스터에서 샘플 애플리케이션을 실행할 수 있습니다.

  1. Fargate에 배포하지 않는 경우 이 단계를 건너뜁니다. Fargate 에 배포하는 경우 Fargate 프로필을 생성합니다. 다음 명령을 실행하여 프로필을 생성하거나, AWS Management Console에서 명령의 namenamespace에 동일한 값을 사용하여 프로필을 생성할 수 있습니다. example values을 사용자의 값으로 교체합니다.

    eksctl create fargateprofile \ --cluster my-cluster \ --region region-code \ --name alb-sample-app \ --namespace game-2048
  2. 게임 2048을 샘플 애플리케이션으로 배포하여 AWS Load Balancer Controller가 수신 객체의 결과로 AWS ALB를 생성하는지 확인합니다. 배포하려는 서브넷 유형에 대한 단계를 완료합니다.

    1. IPv6 패밀리로 생성한 클러스터의 pods에 배포하는 경우 다음 단계로 건너뜁니다.

      • Public

        kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.2/docs/examples/2048/2048_full.yaml
      • 프라이빗

        1. 매니페스트를 다운로드합니다.

          curl -o 2048_full.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.2/docs/examples/2048/2048_full.yaml
        2. 파일을 편집하고 alb.ingress.kubernetes.io/scheme: internet-facing이라는 줄을 검색합니다.

        3. internet-facinginternal로 변경하고 파일을 저장합니다.

        4. 매니페스트를 클러스터에 적용합니다.

          kubectl apply -f 2048_full.yaml
    2. IPv6 패밀리로 생성한 클러스터의 pods에 배포하는 경우 다음 단계를 수행합니다.

      1. 매니페스트를 다운로드합니다.

        curl -o 2048_full.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.2/docs/examples/2048/2048_full.yaml
      2. 편집기에서 파일을 열고 수신 사양의 주석에 다음 줄을 추가합니다.

        alb.ingress.kubernetes.io/ip-address-type: dualstack
      3. 인터넷 연결 pods가 아니라 내부 pods로 로드 밸런싱하는 경우 alb.ingress.kubernetes.io/scheme: internet-facing 줄을 alb.ingress.kubernetes.io/scheme: internal로 변경합니다.

      4. 파일을 저장합니다.

      5. 매니페스트를 클러스터에 적용합니다.

        kubectl apply -f 2048_full.yaml
  3. 몇 분이 지난 후, 수신 리소스가 다음 명령으로 생성되었는지 확인합니다.

    kubectl get ingress/ingress-2048 -n game-2048

    출력 예는 다음과 같습니다.

    NAME CLASS HOSTS ADDRESS PORTS AGE ingress-2048 <none> * k8s-game2048-ingress2-xxxxxxxxxx-yyyyyyyyyy.region-code.elb.amazonaws.com 80 2m32s
    참고

    프라이빗 서브넷에서 로드 밸런서를 생성한 경우 이전 출력에서 ADDRESS 아래의 값은 internal-로 시작합니다.

    몇 분 후에도 수신이 생성되지 않은 경우 다음 명령을 실행하여 AWS Load Balancer Controller 로그를 확인합니다. 이러한 로그에는 배포 문제를 진단하는 데 사용할 수 있는 오류 메시지가 포함될 수 있습니다.

    kubectl logs -n kube-system deployment.apps/aws-load-balancer-controller
  4. 퍼블릭 서브넷에 배포한 경우 브라우저를 열고 이전 명령 출력에서 ADDRESS URL로 이동하여 샘플 애플리케이션을 봅니다. 아무것도 표시되지 않으면 브라우저를 새로 고치고 다시 시도하세요. 프라이빗 서브넷에 배포한 경우 Bastion 호스트와 같은 VPC 내의 디바이스에서 페이지를 확인해야 합니다. 자세한 내용은 AWS 기반 Linux Bastion 호스트를 참조하세요.

    
                        2048 샘플 애플리케이션
  5. 샘플 애플리케이션에 대한 실험이 끝나면 다음 명령 중 하나를 실행하여 이를 삭제합니다.

    • 매니페스트를 적용했다면 다운로드한 사본을 적용하는 대신 다음 명령을 사용합니다.

      kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.2/docs/examples/2048/2048_full.yaml
    • 매니페스트를 다운로드하여 편집한 경우 다음 명령을 사용합니다.

      kubectl delete -f 2048_full.yaml