기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
로드 밸런싱
로드 밸런서는 수신 트래픽을 수신하고 EKS 클러스터에서 호스팅되는 의도한 애플리케이션의 대상에 분산합니다. 이렇게 하면 애플리케이션의 복원력이 향상됩니다. EKS 클러스터에 배포하면 AWS Load Balancer 컨트롤러가 해당 클러스터에 대한 AWS Elastic Load Balancer를 생성하고 관리합니다. LoadBalancer 유형의 Kubernetes 서비스가 생성되면 AWS Load Balancer 컨트롤러는 OSI 모델의 계층 4에서 수신된 트래픽을 로드 밸런싱하는 Network Load Balancer(NLB)를 생성합니다. Kubernetes Ingress 객체가 생성되는 동안 AWS Load Balancer Controller는 OSI 모델의 계층 7에서 트래픽을 로드 밸런싱하는 Application Load Balancer(ALB)를 생성합니다.
Load Balancer 유형 선택
AWS Elastic Load Balancing(ELB) 포트폴리오는 Application Load Balancer(ALB), Network Load Balancer(NLB), Gateway Load Balancer(GWLB), Classic Load Balancer(CLB) 등의 로드 밸런서를 지원합니다. 이 모범 사례 섹션에서는 EKS 클러스터와 가장 관련성이 높은 ALB 및 NLB에 중점을 둡니다.
로드 밸런서 유형을 선택할 때 고려해야 할 주요 사항은 워크로드 요구 사항입니다.
자세한 내용과 모든 AWS 로드 밸런서에 대한 참조는 제품 비교를 참조하세요
워크로드가 HTTP/HTTPS인 경우 Application Load Balancer(ALB)를 선택합니다.
워크로드에 OSI 모델의 계층 7에서 로드 밸런싱이 필요한 경우 AWS Load Balancer Controller를 사용하여 ALB를 프로비저닝할 수 있습니다. 다음 섹션에서 프로비저닝을 다룹니다. ALB는 앞서 언급한 수신 리소스에 의해 제어 및 구성되며 HTTP 또는 HTTPS 트래픽을 클러스터 내의 다른 포드로 라우팅합니다. ALB는 고객에게 애플리케이션 트래픽 라우팅 알고리즘을 변경할 수 있는 유연성을 제공합니다. 기본 라우팅 알고리즘은 미해결 요청 라우팅 알고리즘이 가장 적은 라운드 로빈이기도 합니다.
워크로드가 TCP이거나 워크로드에 클라이언트의 소스 IP 보존이 필요한 경우 Network Load Balancer(NLB)를 선택합니다.
Network Load Balancer는 OSI(Open Systems Interconnection) 모델의 네 번째 계층(전송)에서 작동합니다. TCP 및 UDP 기반 워크로드에 적합합니다. 또한 Network Load Balancer는 기본적으로 포드에 트래픽을 제공할 때 클라이언트 주소의 소스 IP를 보존합니다.
워크로드가 DNS를 활용할 수 없는 경우 Network Load Balancer(NLB)를 선택합니다.
NLB를 사용하는 또 다른 주요 이유는 클라이언트가 DNS를 사용할 수 없는 경우입니다. 이 경우 Network Load Balancer의 IPs가 정적이므로 NLB가 워크로드에 더 적합할 수 있습니다. 클라이언트는 로드 밸런서에 연결할 때 도메인 이름을 IP 주소로 확인할 때 DNS를 사용하는 것이 좋지만, 클라이언트의 애플리케이션이 DNS 확인을 지원하지 않고 하드 코딩된 IPs만 허용하는 경우 IP가 정적 IPs 이고 NLB 수명 동안 동일하게 유지되므로 NLB가 더 적합합니다.
로드 밸런서 프로비저닝
워크로드에 가장 적합한 Load Balancer 결정한 후 고객은 로드 밸런서를 프로비저닝할 수 있는 여러 옵션이 있습니다.
AWS Load Balancer 컨트롤러를 배포하여 Load Balancer 프로비저닝
EKS 클러스터 내에 로드 밸런서를 프로비저닝하는 두 가지 주요 방법이 있습니다.
-
AWS 클라우드 공급자에서 서비스 컨트롤러 활용(레거시)
-
AWS Load Balancer 컨트롤러 활용(권장)
기본적으로 인트리 컨트롤러라고도 하는 Kubernetes 서비스 컨트롤러는 LoadBalancer 유형의 Kubernetes 서비스 리소스를 조정합니다. 이 컨트롤러는 Kubernetes Cloud Controller Manager 역할을 하는 AWS Cloud Provider
프로비저닝된 Elastic Load Balancer의 구성은 Kubernetes Service 매니페스트에 추가해야 하는 주석에 의해 제어됩니다. 서비스 컨트롤러
서비스 컨트롤러는 레거시이며 현재 중요한 버그 수정만 수신하고 있습니다. LoadBalancer 유형의 Kubernetes Service를 생성할 때 서비스 컨트롤러는 기본적으로 AWS CLB를 생성하지만 올바른 주석을 사용하는 경우에도 AWS NLB를 생성할 수 있습니다. 서비스 컨트롤러는 Kubernetes Ingress 리소스를 지원하지 않으며 IPv6도 지원하지 않는다는 점에 유의해야 합니다.
EKS 클러스터에서 AWS Load Balancer Controller를 사용하여 Kubernetes Service 및 Ingress 리소스를 조정하는 것이 좋습니다. AWS Load Balancer Controller가 조정 프로세스를 소유하도록 Kubernetes Service 또는 Ingress 매니페스트에 올바른 주석을 사용해야 합니다(서비스 컨트롤러 대신).
EKS Auto Mode를 사용하는 경우 AWS Load Balancer Controller가 자동으로 제공되므로 설치할 필요가 없습니다.
Load Balancer 대상 유형 선택
IP Target-Type을 사용하여 포드를 대상으로 등록
AWS Elastic Load Balancer: 네트워크 및 애플리케이션은 수신된 트래픽을 대상 그룹에 등록된 대상으로 전송합니다. EKS 클러스터의 경우 대상 그룹에 등록할 수 있는 대상 유형은 두 가지입니다. 인스턴스 및 IP는 어떤 대상 유형이 사용되는지 등록되는 항목과 트래픽이 Load Balancer에서 포드로 라우팅되는 방식에 영향을 미칩니다. 기본적으로 AWS Load Balancer 컨트롤러는 "인스턴스" 유형을 사용하여 대상을 등록하고이 대상은 작업자 노드의 IP 및 NodePort이며, 이는 다음과 같습니다.
-
Load Balancer의 트래픽은 NodePort, 이는 iptables 규칙(노드에서 실행되는 kube-proxy로 구성됨)에 의해 처리되고 ClusterIP의 서비스(노드에 있음)로 전달됩니다. 마지막으로 서비스는 등록된 포드를 임의로 선택하고 트래픽을 전달합니다. 이 흐름에는 여러 홉이 포함되며 특히 서비스가 다른 AZ에도 있을 수 있는 다른 작업자 노드에서 실행 중인 포드를 선택하기 때문에 추가 지연 시간이 발생할 수 있습니다.
-
Load Balancer 작업자 노드를 대상으로 등록하므로 대상으로 전송되는 상태 확인은 포드에서 직접 수신되지 않지만 NodePort의 작업자 노드와 상태 확인 트래픽은 위에서 설명한 것과 동일한 경로를 따릅니다.
-
Load Balancer에서 전달한 트래픽은 포드로 직접 전송되지 않으므로 모니터링 및 문제 해결은 더 복잡하며, 적절한 문제 해결을 위해 패킷의 경로에 대한 전체 end-to-end 가시성을 확보하려면 작업자 노드에서 수신된 패킷을 Service ClusterIP 및 포드와 신중하게 상호 연관시켜야 합니다.

반대로 대상 유형을 "IP"로 구성하면 다음과 같은 영향을 미치는 것이 좋습니다.
-
Load Balancer의 트래픽은 포드로 직접 전달되므로 작업자 노드 및 서비스 클러스터 IP의 이전 추가 홉을 우회할 때 네트워크 경로가 간소화되고, 서비스가 다른 AZ의 포드로 트래픽을 전달하고 마지막으로 작업자 노드에서 iptables 규칙 오버헤드 처리를 제거하는 경우 발생할 수 있는 지연 시간이 줄어듭니다.
-
Load Balancer서의 상태 확인은 포드에 의해 직접 수신되고 응답됩니다. 즉, 대상 상태 "정상" 또는 "비정상"은 포드의 상태를 직접 나타냅니다.
-
모니터링 및 문제 해결이 더 쉽고 패킷 IP 주소를 캡처하는 데 사용되는 모든 도구는 소스 및 대상 필드의 Load Balancer서와 포드 간의 양방향 트래픽을 직접 표시합니다.

IP 대상을 사용하는 AWS Elastic Load Balancing을 생성하려면 다음을 추가합니다.
-
alb.ingress.kubernetes.io/target-type: ip
Kubernetes Ingress(Application Load Balancer)를 구성할 때 수신 매니페스트에 주석 달기 -
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
LoadBalancer(Network Load Balancer) 유형의 Kubernetes 서비스를 구성할 때 서비스 매니페스트에 주석을 추가합니다.
Load Balancer서 상태 확인 구성
Kubernetes는 자체 상태 확인 메커니즘(다음 단원에서 설명)을 제공하지만 Kubernetes 컨트롤 플레인 외부에서 작동하는 보완적 보호 수단으로 ELB 상태 확인을 구현하는 것이 좋습니다. 이 독립 계층은 다음과 같은 경우에도 애플리케이션을 계속 모니터링합니다.
-
Kubernetes 컨트롤 플레인 중단
-
프로브 실행 지연
-
kubelet과 포드 간의 네트워크 파티션
위에서 언급한 시나리오 중에 최대 가용성 가속화 복구가 필요한 중요한 워크로드의 경우 ELB 상태 확인은 Kubernetes의 기본 메커니즘 대신 작동하는 필수 안전망을 제공합니다.
ELB에서 상태 확인을 구성하고 미세 조정하려면 서비스 컨트롤러 또는 AWS Load Balancer 컨트롤러에서 조정할 Kubernetes 서비스 또는 수신 매니페스트의 주석을 사용해야 합니다.
가용성 및 포드 수명 주기
애플리케이션 업그레이드 중에 사용자가 가동 중지 시간을 경험하지 않도록 요청을 처리할 수 있도록 애플리케이션을 항상 사용할 수 있는지 확인해야 합니다. 이 시나리오의 일반적인 과제 중 하나는 Kubernetes 계층과 외부 로드 밸런서와 같은 인프라 간에 워크로드의 가용성 상태를 동기화하는 것입니다. 다음 몇 단원에서는 이러한 시나리오를 해결하기 위한 모범 사례를 강조합니다.
참고
아래 설명은 Kubernetes의 엔드포인트를 대체하는 것이 권장되므로 EndpointSlices
상태 확인 사용
Kubernetes는 기본적으로 프로세스 상태 확인을
포드 생성 프로세스의 이벤트 시퀀스를 다시 확인하려면 아래 부록 섹션의 포드 생성을 참조하세요.
준비 프로브 사용
기본적으로 포드 내의 모든 컨테이너가 실행success
. 반면 프로브가 라인에서 더 이상 실패하면 EndpointSlice 객체에서 포드가 제거됩니다. 각 컨테이너의 포드 매니페스트에서 준비 프로브를 구성할 수 있습니다. 각 노드의 kubelet
프로세스는 해당 노드의 컨테이너에 대해 준비 프로브를 실행합니다.
포드 준비 게이트 사용
준비 프로브의 한 가지 측면은 외부 피드백/영향 메커니즘이 없다는 것입니다. 노드의 kubelet 프로세스는 프로브를 실행하고 프로브의 상태를 정의합니다. EndpointSlice 컨트롤러는 엔드포인트(포드) 목록을 항상 최신 상태로 유지하기 때문에 Kubernetes 계층(동서 트래픽)의 마이크로서비스 자체 간 요청에 영향을 주지 않습니다. 외부 메커니즘이 필요한 이유와 시기는 무엇입니까?
Kubernetes Service 유형의 Load Balancer 또는 Kubernetes Ingress(북부 - 남부 트래픽의 경우)를 사용하여 애플리케이션을 노출하는 경우 로드 밸런서에 최신 목록 대상도 있도록 해당 Kubernetes Service의 포드 IPs 목록을 외부 인프라 로드 밸런서에 전파해야 합니다. AWS Load Balancer Controller는 여기에 격차를 해소합니다. AWS Load Balancer Controller를 사용하고 target group: IP
kube-proxy
를 활용하는 경우 AWS Load Balancer Controller도 업데이트를 수신한 다음(를 통해watch
) ELB API와 통신하여 ELB에서 포드 IP를 대상으로 등록을 구성하고 시작합니다.
배포의 롤링 업데이트를 수행하면 새 포드가 생성되고 새 포드의 조건이 "준비"가 되는 즉시 이전/기존 포드가 종료됩니다. 이 프로세스 중에 Kubernetes EndpointSlice 객체는 ELB가 새 포드를 대상으로 등록하는 데 걸리는 시간보다 빠르게 업데이트됩니다. 대상 등록을 참조하세요. 잠시 동안 Kubernetes 계층과 클라이언트 요청이 삭제될 수 있는 인프라 계층 간에 상태가 일치하지 않을 수 있습니다. Kubernetes 계층 내의이 기간 동안 새 포드는 요청을 처리할 준비가 되지만 ELB 관점에서는 그렇지 않습니다.
포드 준비 게이트
애플리케이션을 정상적으로 종료합니다.
애플리케이션은 클라이언트가 가동 중지 시간을 경험하지 않도록 정상적인 종료를 시작하여 SIGTERM 신호에 응답해야 합니다. 즉, 애플리케이션은 데이터 저장, 파일 설명자 닫기, 데이터베이스 연결 닫기, 진행 중인 요청 완료와 같은 정리 절차를 실행하고 적시에 종료하여 포드 종료 요청을 이행해야 합니다. 정리가 완료될 수 있도록 유예 기간을 충분히 길게 설정해야 합니다. SIGTERM 신호에 응답하는 방법을 알아보려면 애플리케이션에 사용하는 각 프로그래밍 언어의 리소스를 참조할 수 있습니다.
SIGTERM 신호를 수신할 때 애플리케이션이 정상적으로 종료되지 않거나 신호를 무시하거나 수신하지 않는
이벤트의 전체 순서는 아래 다이어그램에 나와 있습니다. 참고: 애플리케이션의 정상적인 종료 절차의 결과 또는 PreStop 후크의 결과에 관계없이 애플리케이션 컨테이너는 결국 SIGKILL을 통해 유예 기간이 끝날 때 종료됩니다.

포드 삭제 프로세스의 이벤트 시퀀스를 다시 확인하려면 아래 부록 섹션의 포드 삭제를 참조하세요.
클라이언트 요청을 원활하게 처리
포드 삭제의 이벤트 시퀀스는 포드 생성과 다릅니다. 포드가 생성되면 Kubernetes API에서 포드 IP가 kubelet
업데이트되고 EndpointSlice 객체만 업데이트됩니다. 반면 포드가 종료되면 Kubernetes API는 kubelet 컨트롤러와 EndpointSlice 컨트롤러 모두에 동시에 알립니다. 이벤트 시퀀스를 보여주는 다음 다이어그램을 주의 깊게 검사합니다.

상태가 API 서버에서 위에 설명된 노드의 iptables 규칙으로 완전히 전파되는 방식은 흥미로운 레이스 조건을 생성합니다. 컨테이너가 각 노드의 kube-proxy보다 훨씬 일찍 SIGKILL 신호를 수신할 가능성이 높기 때문에 로컬 iptables 규칙을 업데이트합니다. 이러한 경우 언급할 가치가 있는 두 가지 시나리오는 입니다.
-
애플리케이션이 SIGTERM을 수신할 때 진행 중인 요청 및 연결을 즉시 무딘 방식으로 삭제하는 경우 클라이언트는 전체 위치에서 50x 오류를 볼 수 있습니다.
-
애플리케이션이 SIGTERM 수신 시 모든 진행 중인 요청 및 연결이 완전히 처리되도록 하더라도 iptables 규칙이 아직 업데이트되지 않을 수 있으므로 유예 기간 동안 새 클라이언트 요청은 여전히 애플리케이션 컨테이너로 전송됩니다. 정리 절차가 컨테이너의 서버 소켓을 닫을 때까지 이러한 새 요청은 새 연결을 초래합니다. 유예 기간이 종료되면 SIGTERM 이후에 설정된 연결이 SIGKILL이 전송되기 때문에 무조건 삭제됩니다.
포드 사양에서 유예 기간을 충분히 길게 설정하면이 문제를 해결할 수 있지만 전파 지연 및 실제 클라이언트 요청 수에 따라 애플리케이션이 연결을 정상적으로 종료하는 데 걸리는 시간을 예상하기 어렵습니다. 따라서 여기서 완벽하지는 않지만 가장 실행 가능한 접근 방식은 PreStop 후크를 사용하여 iptables 규칙이 업데이트될 때까지 SIGTERM 신호를 지연시켜 새 클라이언트 요청이 애플리케이션에 전송되지 않고 기존 연결만 계속되도록 하는 것입니다. PreStop 후크는와 같은 간단한 Exec 핸들러일 수 있습니다sleep 10
.
위에서 언급한 동작과 권장 사항은 Kubernetes Service 유형의 Load Balancer를 사용하여 애플리케이션을 노출하거나 AWS Load Balancer Controller를 사용하여 Kubernetes Ingress(북부 - 남부 트래픽의 경우)를 노출하고 target group: IP
를 활용할 때 동일하게 적용됩니다. kube-proxy
AWS Load Balancer Controller는 EndpointSlice 객체에 대한 업데이트(시계를 통해)도 수신한 다음 ELB API와 통신하여 ELB에서 포드 IP 등록 취소를 시작하기 때문입니다. 그러나 Kubernetes API 또는 ELB API의 로드에 따라 시간이 걸릴 수 있으며 SIGTERM이 이미 애플리케이션으로 전송되었을 수 있습니다. ELB가 대상 등록 취소를 시작하면 애플리케이션이 새 요청을 수신하지 않도록 해당 대상에 대한 요청 전송을 중지하고 ELB는 기본적으로 300초인 등록 취소 지연도 시작합니다. 등록 취소 프로세스 중에 대상은 기본적으로 ELB가 해당 대상에 대한 진행 중인 요청/기존 연결이 드레이닝될 때까지 대기하는 draining
곳입니다. 등록 취소 지연이 만료되면 대상이 사용되지 않고 해당 대상에 대한 진행 중인 요청이 강제로 삭제됩니다.
포드 중단 예산 사용
애플리케이션에 대한 포드 중단 예산
참조
-
KubeCon Europe 2019 세션 - 준비되셨나요? 서비스 상태를 위한 포드 준비 게이트 심층 분석
-
도서 - 실행 중인 Kubernetes
부록
포드 생성
포드가 배포된 후 클라이언트 요청을 수신하고 처리할 준비가 된 시나리오에서 이벤트 시퀀스가 무엇인지 이해하는 것이 중요합니다. 이벤트 시퀀스에 대해 살펴보겠습니다.
-
포드는 Kubernetes 컨트롤 플레인에 생성됩니다(예: kubectl 명령, 배포 업데이트 또는 조정 작업).
-
kube-scheduler
는 클러스터의 노드에 포드를 할당합니다. -
할당된 노드에서 실행되는 kubelet 프로세스는 업데이트를 수신하고(를 통해
watch
) 컨테이너 런타임과 통신하여 포드 사양에 정의된 컨테이너를 시작합니다. -
컨테이너가 실행되기 시작하면 kubelet은 Kubernetes API의 포드 객체에서와 같이 포드 조건을
업데이트합니다. Ready
-
EndpointSlice 컨트롤러는
포드 조건 업데이트(를 통해 watch
)를 수신하고 포드 IP/포트를 해당 Kubernetes 서비스의 EndpointSlice객체(포드 IPs 목록)에 새 엔드포인트로 추가합니다. -
각 노드의 kube-proxy
프로세스는 EndpointSlice 객체에 대한 업데이트(를 통해 watch
)를 수신한 다음 새 포드 IP/포트로 각 노드의 iptables규칙을 업데이트합니다.
포드 삭제
포드 생성과 마찬가지로 포드 삭제 중에 이벤트 시퀀스가 무엇인지 이해해야 합니다. 이벤트 시퀀스에 대해 살펴보겠습니다.
-
포드 삭제 요청은 Kubernetes API 서버로 전송됩니다(예:
kubectl
명령, 배포 업데이트 또는 조정 작업). -
Kubernetes API 서버는 포드 객체에서 deletionTimestamp
필드를 설정하여 기본적으로 30초의 유예 기간을 시작합니다 . (Grace 기간은를 통해 포드 사양에서 구성할 수 있음 terminationGracePeriodSeconds
) -
노드에서 실행되는
kubelet
프로세스는 포드 객체에 대한 업데이트(감시를 통해)를 수신하고 해당 포드의 각 컨테이너 내에서 프로세스 식별자 1(PID 1)에 SIGTERM신호를 보냅니다. 그런 다음를 감시합니다 terminationGracePeriodSeconds
. -
또한 EndpointSlice 컨트롤러는
2단계에서 업데이트(를 통해 watch
)를 수신하고 각 Kubernetes 서비스의 EndpointSlice객체(포드 IPs 목록)에서 엔드포인트 조건을 "종료"로 설정합니다. -
각 노드의 kube-proxy
프로세스는 EndpointSlice 객체에 대한 업데이트(를 통해 watch
)를 수신한 다음 각 노드의 iptables규칙을 kube-proxy에 의해 업데이트하여 클라이언트 요청을 포드로 전달하는 것을 중지합니다. -
가
terminationGracePeriodSeconds
만료되면는 포드에 있는 각 컨테이너의 상위 프로세스에 SIGKILL신호를 kubelet
보내고 강제로 종료합니다. -
TheEndpointSlice 컨트롤러는
EndpointSlice 객체에서 엔드포인트를 제거합니다. -
API 서버는 포드 객체를 삭제합니다.