AWS Load Balancer Controller를 사용하여 로드 밸런서를 만들 때 발생하는 문제를 해결하려면 어떻게 해야 합니까?
AWS Load Balancer Controller로 로드 밸런서를 만들려고 할 때 발생하는 문제를 해결하고 싶습니다.
간략한 설명
AWS Load Balancer Controller는 Amazon Elastic Kubernetes Service(Amazon EKS) 클러스터의 Elastic Load Balancing을 관리합니다.
컨트롤러는 다음 리소스를 제공합니다.
- Kubernetes 수신 생성 시 Application Load Balancer.
- LoadBalancer 유형의 Kubernetes 서비스를 생성할 때 Network Load Balancer.
참고: AWS Load Balancer Controller 버전 2.3.0 이상에서는 인스턴스 또는 IP 대상 유형으로 Network Load Balancer를 만들 수 있습니다.
해결 방법
AWS Load Balancer Controller를 설치하고 사용하기 위한 모든 사전 조건을 충족하는지 확인
취해야 할 초기 작업 목록은 사전 조건을 참조하십시오.
다음 명령을 실행하여 AWS Load Balancer Controller를 성공적으로 배포했는지 확인합니다.
kubectl get deployment -n kube-system aws-load-balancer-controller
참고: 버전 2.4.4 이상을 사용하는 것이 가장 좋습니다.
출력 예시:
NAME READY UP-TO-DATE AVAILABLE AGE aws-load-balancer-controller 2/2 2 2 84s
Application Load Balancer를 사용하는 경우 서로 다른 가용 영역에 서브넷이 두 개 이상 있는지 확인하십시오. Network Load Balancer에는 하나 이상의 서브넷이 있어야 합니다. 서브넷에는 사용 가능한 IP 주소가 8개 이상 있어야 합니다. 자세한 내용은 가상 프라이빗 클라우드(VPC) 만들기를 참조하십시오.
특정 시나리오에서는 다음 태그를 사용해야 합니다.
- 키: “kubernetes.io/cluster/cluster-name”
- 값: “shared” 또는 “owned”
Application Load Balancer
다음 시나리오에서는 하나의 보안 그룹에 태그를 지정해야 합니다.
- 워커 노드에 연결된 여러 보안 그룹을 사용합니다.
- AWS Load Balancer Controller 버전 v2.1.1 이하를 사용합니다.
Network Load Balancer
AWS Load Balancer Controller 버전 v2.1.1 이하를 사용하는 경우 서브넷에 태그를 추가해야 합니다.
서비스 또는 수신 주석에 서브넷 ID를 지정하지 않은 경우 서브넷에 서브넷 자동 검색에 필요한 태그가 있는지 확인하십시오. 자세한 내용은 GitHub 웹 사이트의 서브넷 자동 검색을 참조하십시오.
프라이빗 서브넷의 경우 다음 태그를 사용하십시오.
- 키: "kubernetes.io/role/internal-elb"
- 값: "1"
퍼블릭 서브넷의 경우 다음 태그를 사용합니다.
- 키: "kubernetes.io/role/elb"
- 값: "1"
수신 또는 서비스 개체의 주석 확인
서비스 개체 또는 수신 개체의 주석이 올바른지 확인하십시오.
참고: 다음 명령에서 SERVICE-NAME, INGRESS-NAME 및 NAMESPACE를 해당 값으로 바꾸십시오.
서비스 개체를 보려면 다음 명령을 실행합니다.
kubectl describe service SERVICE-NAME -n NAMESPACE
수신 개체를 보려면 다음 명령을 실행합니다.
kubectl describe ingress INGRESS-NAME -n NAMESPACE
서비스 개체를 편집하려면 다음 명령을 실행합니다.
kubectl edit service SERVICE-NAME -n NAMESPACE
수신 개체를 편집하려면 다음 명령을 실행합니다.
kubectl edit ingress INGRESS-NAME -n NAMESPACE
다른 주석에는 기본값이 사용됩니다. AWS Load Balancer Controller가 Application Load Balancer에 지원하는 주석 목록은 GitHub 웹 사이트의 수신 주석을 참조하십시오. Network Load Balancer에 지원되는 주석 목록은 GitHub 웹 사이트의 서비스 주석을 참조하십시오.
Application Load Balancer
Kubernetes 1.18 이전 버전에서 수신 클래스는 수신 컨트롤러 이름을 참조하는 kubernetes.io/ingress.class 주석을 사용했습니다. 이후 버전의 모든 Kubernetes에 있는 수신 클래스는 수신 클래스 리소스를 참조하는 ingressClassName 주석을 사용합니다.
자세한 내용은 GitHub 웹 사이트의 Deprecated kubernetes.io/ingress.class annotation을 참조하십시오.
Network Load Balancer
다음 주석을 사용하십시오.
- IP 대상에는 service.beta.kubernetes.io/aws-load-balancer-type: "external" 및 **service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"**를 사용합니다.
- 인스턴스 대상에는 service.beta.kubernetes.io/aws-load-balancer-type: "external" 및 **service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance"**를 사용합니다.
Amazon EKS에서 수신 또는 서비스 유형 로드 밸런서를 만들 때 발생하는 문제 해결
"AccessDenied" 오류 메시지가 표시됨
다음 오류 메시지가 표시됩니다.
"Failed deploy model due to AccessDenied"
이 오류는 리소스를 만드는 데 필요한 elasticloadbalancing:AddTags 권한이 변경되었기 때문에 발생합니다. 문제를 해결하려면 최신 AWS Identity and Access Management(AWS IAM) 정책을 AWSLoadBalancerController 역할에 연결하십시오. 최신 정책을 보려면 GitHub 웹 사이트에서 IAM 정책 JSON을 참조하십시오.
자세한 내용은 eksctl을 사용하여 IAM 역할 만들기를 참조하십시오.
로드 밸런서가 가용 영역에서 지원되지 않음
제한된 가용 영역에 서브넷을 지정하면 다음과 비슷한 오류 메시지가 표시될 수 있습니다.
"Load balancers with type 'network' are not supported in availability-zone-name"
이 문제를 해결하려면 제한되지 않은 다른 가용 영역에 서브넷을 지정하십시오. 그런 다음 교차 영역 부하 분산을 사용하여 제한된 가용 영역의 대상으로 트래픽을 분산합니다.
다른 서브넷을 사용하려면 내부 Network Load Balancer를 만드는 데 사용하는 서브넷에 kubernetes.io/role/internal-elb=1 태그를 추가하십시오. 자세한 내용은 Network Load Balancer 태그 지정을 참조하십시오.
또는 다음 주석을 추가하여 서비스 매니페스트 파일에 서브넷을 지정합니다.
service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxxx, mySubnet
참고: subnet-xxxx를 서브넷 ID로 바꾸고 mySubnet을 서브넷 이름으로 바꾸십시오.
서브넷에 자동 검색을 사용할 수 없음
서브넷에 자동 검색용 태그를 지정하지 않으면 다음과 같은 오류 메시지가 표시될 수 있습니다.
"couldn't auto-discover subnets: unable to resolve at least one subnet"
AWS Load Balancer Controller는 기본적으로 네트워크 서브넷을 자동으로 검색합니다. Application Load Balancer의 경우 서로 다른 가용 영역에 서브넷이 2개 이상 있어야 합니다. Network Load Balancer는 서브넷이 하나만 필요합니다.
자동 검색이 작동하려면 서브넷에 적절한 태그를 적용해야 합니다. 컨트롤러는 각 가용 영역에서 하나의 서브넷을 선택합니다. 가용 영역에 태그가 지정된 서브넷이 여러 개 있는 경우 컨트롤러는 알파벳 서브넷 ID를 기반으로 하나의 서브넷만 선택합니다.
프라이빗 및 퍼블릭 서브넷에 필요한 서브넷 태그에 대한 자세한 내용은 GitHub 웹 사이트의 Subnet auto discovery를 참조하십시오.
인증서 관리자 또는 웹후크 구성에 문제가 있음
웹후크 검증이 실패하면 다음과 같은 오류 메시지가 표시될 수 있습니다.
"Internal error occurred: failed calling webhook "vingress.elbv2.k8s.aws": Post "https://aws-load-balancer-webhook-service.kube-system.svc:443/validate-networking-v1beta1-ingress?timeout=10s": x509: certificate has expired or is not yet valid"
이 오류는 AWS Certificate Manager(ACM)가 웹후크에 대해 관리하는 인증서에 문제가 있을 때 발생합니다.
이 문제를 해결하려면 Certificate Manager 포드가 실행 중인지 확인하십시오.
포드 상태를 확인하려면 다음 명령을 실행합니다.
kubectl describe pod your-pod-name -n your-namespace
로그를 수집하려면 다음 명령을 실행합니다.
kubectl logs your-pod-name -n your-namespace
참고: 위의 명령에서 your-pod-name을 포드의 이름으로 바꾸고 your-namespace를 네임스페이스의 이름으로 바꾸십시오.
대상 그룹 바인딩 생성 실패
대상 그룹 바인딩 생성에 실패하면 다음과 같은 오류 메시지가 표시될 수 있습니다.
"Warning FailedDeployModel 11m (x2 over 39m) ingress Failed deploy model due to Internal error occurred: failed calling webhook "vtargetgroupbinding.elbv2.k8s.aws": failed to call webhook: Post "https://aws-load-balancer-webhook-service.kube-system.svc:443/validate-elbv2-k8s-aws-v1beta1-targetgroupbinding?timeout=10s": context deadline exceeded"
이 오류는 보안 그룹 제한 사항으로 인해 웹후크 서비스에 대한 액세스가 차단될 때 발생합니다. 이 서비스는 기본적으로 포트 9443을 사용합니다.
이 문제를 해결하려면 노드 보안 그룹을 수정하십시오. 포트 9443에서 컨트롤 플레인 보안 그룹의 인바운드 트래픽을 허용하십시오. 자세한 내용은 GitHub 웹 사이트의 Controller configuration options를 참조하십시오.
노드 역할에 대한 AssumeRoleWithWebIdentity 실패
노드 역할이 서비스 계정에 지정된 역할을 수임할 수 없는 경우 다음과 같은 오류 메시지가 표시될 수 있습니다.
"WebIdentityErr: failed to retrieve credentials\ncaused by: AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity\n\tstatus code: 403, request id: c6241a7d-d8a8-452c-bb67-bf1ff9bab0c0"
이 오류는 서비스 계정(IRSA)에 대한 IAM 역할을 잘못 구성했기 때문에 발생합니다.
이 문제를 해결하려면 서비스 계정에서 올바른 역할을 사용하고 역할에 대한 신뢰 정책을 정의하십시오.
자세한 내용은 Amazon EKS에서 AWS Load Balancer Controller를 사용할 때 "WebIdentityErr" 오류가 발생하는 이유는 무엇입니까? 및 Amazon EKS에서 OIDC 공급자 및 IRSA 문제를 해결하려면 어떻게 해야 합니까?를 참조하십시오.
컨트롤러 포드 로그의 데이터가 부족함
기본 컨트롤러 포드 로그가 제공하는 것보다 더 많은 디버그 정보가 필요한 경우 컨트롤러 포드 구성에 --log-level debug 플래그를 추가하십시오.
자세한 내용은 GitHub 웹 사이트의 Controller command line flags를 참조하십시오.
AWS Load Balancer Controller 포드의 로그에서 추가 정보 검토
AWS Load Balancer Controller 로그를 검토하려면 다음 명령을 실행합니다.
kubectl logs -n kube-system deployment.apps/aws-load-balancer-controller
문제가 있는 경우 "Reconciler error"가 표시됩니다. 수신 개체 또는 로드 밸런서 서비스가 생성이나 업데이트에 실패한 이유를 설명하는 자세한 오류 메시지도 표시됩니다.
이 실패는 다음과 같은 이유로 발생할 수 있습니다.
- 컨트롤러가 AWS API 호출을 시도할 때 오류가 발생하는 경우에는 권한 또는 연결 문제가 있는 것입니다. 컨트롤러의 IAM 권한을 검토하십시오. 그런 다음, 보안 그룹 또는 네트워크 액세스 제어 목록(네트워크 ACL)이 아웃바운드 연결을 명시적으로 거부하지 않는지 확인합니다.
- 개체 구성에서 오류가 발생하면 수신 또는 서비스 사양 또는 주석을 잘못 구성한 것입니다. GitHub 웹 사이트의 Application Load Balancer 또는 Network Load Balancer에 대한 주석을 검토하십시오.
컨트롤러 포드에 로그가 표시되지 않는 경우 다음 명령을 실행하여 컨트롤러 포드가 실행 중인지 확인합니다.
kubectl get deployment -n kube-system aws-load-balancer-controller
지원되는 컨트롤러 버전으로 업그레이드
더 이상 지원되지 않는 AWS Load Balancer Controller 버전을 사용하는 경우 이후 버전으로 업그레이드할 수 없습니다. 대신 기존 컨트롤러를 제거한 다음 최신 버전을 설치해야 합니다.
레거시 클라우드 제공업체가 아닌 AWS Load Balancer Controller 사용
Kubernetes에는 Classic Load Balancer를 제공할 수 있는 AWS 레거시 클라우드 제공업체가 포함되어 있습니다. AWS Load Balancer Controller를 설치하지 않으면 Kubernetes가 레거시 클라우드 제공업체를 사용합니다. 하지만 AWS Load Balancer Controller를 사용하는 것이 가장 좋습니다.
AWS Load Balancer Controller 버전 2.5 이상은 LoadBalancer 유형의 Kubernetes 서비스 리소스에 대한 기본 컨트롤러입니다. 각 서비스의 Network Load Balancer를 만듭니다. 또한 최신 버전은 서비스의 변형 웹후크를 구현합니다. 새로운 유형의 LoadBalancer 서비스에 대해 spec.loadBalancerClass 필드를 service.k8s.aws/nlb로 설정했습니다.
AWS Load Balancer Controller로 업그레이드하려면 다음 명령을 실행합니다.
helm upgrade aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=CLUSTER-NAME --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set enableServiceMutatorWebhook=false
참고: CLUSTER-NAME을 클러스터 이름으로 바꾸십시오.
레거시 클라우드 제공업체를 사용해야 하는 경우 enableServiceMutatorWebhook 헬름 차트 값을 false로 설정하여 새 Classic Load Balancer를 제공하지 않도록 하십시오. 기존 Classic Load Balancer만 계속 작동합니다.
수신 또는 서비스 개체가 있는 네임스페이스에 대한 Fargate 프로필을 만들었는지 확인
대상 포드가 AWS Fargate에서 실행되는 경우 IP 대상 유형을 포함해야 합니다. 수신 또는 서비스 개체가 있는 네임스페이스에 대한 Fargate 프로필이 있는지 확인하려면 다음 명령을 실행합니다.
eksctl get fargateprofile --cluster CLUSTER-NAME -o yaml
참고: CLUSTER-NAME을 클러스터 이름으로 바꾸십시오.
Fargate 프로필을 만들려면 다음 명령을 실행합니다.
eksctl create fargateprofile --cluster CLUSTER-NAME --region REGION --name FARGATE-PROFILE-NAME --namespace NAMESPACE
참고: CLUSTER-NAME, REGION, FARGATE-PROFILE-NAME 및 NAMESPACE를 해당 값으로 바꾸십시오.
트래픽 라우팅 요구 사항을 충족하는지 확인
모든 요구 사항을 충족하는지 확인하려면Application Load Balancer의 사전 요건 및 Network Load Balancer의 사전 요건을 참조하십시오. 예를 들어 Application Load Balancer를 사용하는 경우 서비스 개체는 NodePort 또는 LoadBalancer를 지정하여 인스턴스 트래픽 모드를 사용해야 합니다.
Amazon EKS는 노드의 보안 그룹에 다음 규칙을 추가합니다.
- 클라이언트 트래픽에 대한 인바운드 규칙
- 생성된 Network Load Balancer마다 VPC의 각 로드 밸런서 서브넷에 대한 상태 확인용 인바운드 규칙
Amazon EKS가 추가한 규칙으로 인해 보안 그룹이 최대 규칙 수를 초과할 경우 로드 밸런서 배포가 실패할 수 있습니다.
- 언어
- 한국어
