Amazon EKS의 로드 밸런서에 대한 상태 확인 실패를 해결하려면 어떻게 해야 하나요?

최종 업데이트 날짜: 2021년 12월 13일

내 로드 밸런서가 Amazon Elastic Kubernetes Service(Amazon EKS)에서 상태 확인에 계속 실패합니다.

간략한 설명

Amazon EKS의 로드 밸런서와 관련된 상태 확인 문제를 해결하려면 다음 단원의 단계를 완료합니다.

  • 포드 상태 확인
  • 포드 및 서비스 레이블 선택기 확인
  • 누락된 엔드포인트 확인
  • Application Load Balancer에 대한 서비스 트래픽 정책 및 클러스터 보안 그룹 확인
  • EKS가 targetPort에 대해 구성되었는지 확인
  • AWS 로드 밸런서 컨트롤러에 올바른 권한이 있는지 확인
  • 인그레스 어노테이션에서 Application Load Balancer 문제 확인
  • Kubernetes 서비스 어노테이션에서 Network Load Balancer 문제 확인
  • 수동으로 상태 확인 테스트
  • 네트워킹 확인
  • kube-proxy 다시 시작

해결 방법

포드 상태 확인

포드가 Running 상태이고 포드의 컨테이너가 준비되었는지 확인합니다.

$ kubectl get pod -n YOUR_NAMESPACE

참고: YOUR_NAMESPACE를 Kubernetes 네임스페이스로 바꿉니다.

출력 예:

NAME                           READY   STATUS    RESTARTS   AGE
podname                        1/1     Running   0          16s

참고: 포드의 애플리케이션 컨테이너가 실행되고 있지 않으면 로드 밸런서 상태 확인에 응답하지 않고 실패합니다.

포드 및 서비스 레이블 선택기 확인

포드 레이블의 경우 다음 명령을 실행합니다.

$ kubectl get pod -n YOUR_NAMESPACE --show-labels

출력 예:

NAME                           READY   STATUS    RESTARTS   AGE     LABELS
alb-instance-6cc5cd9b9-prnxw   1/1     Running   0          2d19h   app=alb-instance,pod-template-hash=6cc5cd9b9

Kubernetes 서비스가 포드 레이블을 사용하고 있는지 확인하려면 다음 명령을 실행하여 출력이 포드 레이블과 일치하는지 확인합니다.

$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath='{.spec.selector}{"\n"}'

참고: SERVICE_NAME을 Kubernetes 서비스로 바꾸고 YOUR_NAMESPACE를 Kubernetes 네임스페이스로 바꿉니다.

출력 예:

{"app":"alb-instance"}

누락된 엔드포인트 확인

서비스 선택기용 Kubernetes 컨트롤러는 선택기와 일치하는 포드를 지속적으로 스캔한 다음, 엔드포인트 객체에 대한 업데이트를 게시합니다. 잘못된 레이블을 선택한 경우 엔드포인트가 나타나지 않습니다.

다음 명령을 실행합니다.

$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE

출력 예:

Name:                     alb-instance
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=alb-instance-1      
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.100.44.151
IPs:                      10.100.44.151
Port:                     http  80/TCP
TargetPort:               80/TCP
NodePort:                 http  32663/TCP
Endpoints:                <none>                 
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

엔드포인트가 누락되었는지 확인합니다.

$ kubectl get endpoints SERVICE_NAME -n YOUR_NAMESPACE

출력 예:

NAME           ENDPOINTS                                AGE
alb-instance   <none>                                   2d20h

서비스 트래픽 정책 및 클러스터 보안 그룹에서 Application Load Balancer 관련 문제를 확인합니다.

Application Load Balancer 대상 그룹의 비정상 대상은 두 가지 이유로 발생합니다. 서비스 트래픽 정책인 spec.externalTrafficPolicyCluster 대신 Local로 설정되어 있습니다. 또는 클러스터의 노드 그룹이 여러 클러스터 보안 그룹과 연결되어 있어 노드 그룹 간에 트래픽이 자유롭게 흐를 수 없습니다.

트래픽 정책이 올바르게 구성되었는지 확인합니다.

$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath='{.spec.externalTrafficPolicy}{"\n"}'

출력 예:

Local

설정을 Cluster로 변경합니다.

$ kubectl edit svc SERVICE_NAME -n YOUR_NAMESPACE

클러스터 보안 그룹 확인

1.    Amazon EC2 콘솔을 엽니다.

2.    정상 인스턴스를 선택합니다.

3.    보안(Security) 탭을 선택하고 보안 그룹 인그레스 규칙을 확인합니다.

4.    비정상 인스턴스를 선택합니다.

5.    보안(Security) 탭을 선택하고 보안 그룹 인그레스 규칙을 확인합니다.

각 인스턴스의 보안 그룹이 서로 다르면 보안 그룹 콘솔에서 보안 인그레스 규칙을 수정해야 합니다.

1.    보안(Security) 탭에서 보안 그룹 ID를 선택합니다.

2.    인바운드 규칙 편집(Edit inbound rules) 버튼을 선택하여 인그레스 규칙을 수정합니다.

3.    클러스터의 다른 노드 그룹으로부터의 트래픽을 허용하는 인바운드 규칙을 추가합니다.

서비스가 TargetPort용으로 구성되어 있는지 확인합니다.

TargetPort는 서비스가 트래픽을 전송하는 포드의 ContainerPort와 일치해야 합니다.

TargetPort가 무엇으로 구성되어 있는지 확인하려면 다음 명령을 실행합니다.

$ kubectl get svc  SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath="{.items[*]}{.metadata.name}{'\t'}{.spec.ports[].targetPort}{'\t'}{.spec.ports[].protocol}{'\n'}"

출력 예:

alb-instance 8080 TCP

앞의 예시 출력에서 targetPort는 8080으로 구성되어 있습니다. 하지만 containerPort가 80으로 설정되어 있으므로 targetPort를 80으로 구성해야 합니다.

AWS 로드 밸런서 컨트롤러에 올바른 권한이 있는지 확인

AWS 로드 밸런서 컨트롤러에는 로드 밸런서에서 인스턴스 또는 포드로의 트래픽을 허용하도록 보안 그룹을 업데이트할 수 있는 올바른 권한이 있어야 합니다. 컨트롤러에 올바른 권한이 없으면 오류가 발생합니다.

AWS 로드 밸런서 컨트롤러 배포 로그에서 오류를 확인합니다.

$ kubectl logs deploy/aws-load-balancer-controller -n kube-system

개별 컨트롤러 포드 로그에서 오류를 확인합니다.

$ kubectl logs CONTROLLER_POD_NAME -n YOUR_NAMESPACE

참고: CONTROLLER_POD_NAME을 컨트롤러 포드 이름으로 바꾸고 YOUR_NAMESPACE를 Kubernetes 네임스페이스로 바꿉니다.

인그레스 어노테이션에서 Application Load Balancer 문제 확인

Kubernetes 인그레스 어노테이션에서 Application Load Balancer와 관련된 문제를 확인합니다.

$ kubectl describe ing INGRESS_NAME -n YOUR_NAMESPACE

참고: INGRESS_NAME을 Kubernetes 인그레스의 이름으로 바꾸고 YOUR_NAMESPACE를 Kubernetes 네임스페이스로 바꿉니다.

출력 예:

Name:             alb-instance-ingress
Namespace:        default
Address:          k8s-default-albinsta-fcb010af73-2014729787.ap-southeast-2.elb.amazonaws.com
Default backend:  alb-instance:80 (192.168.81.137:8080)
Rules:
  Host          Path  Backends
  ----          ----  --------
  awssite.cyou
                /   alb-instance:80 (192.168.81.137:8080)
Annotations:    alb.ingress.kubernetes.io/scheme: internet-facing        
                kubernetes.io/ingress.class: alb                         
Events:
  Type    Reason                  Age                  From     Message
  ----    ------                  ----                 ----     -------
  Normal  SuccessfullyReconciled  25m (x7 over 2d21h)  ingress  Successfully reconciled

사용 사례와 관련된 인그레스 어노테이션을 찾으려면 인그레스 어노테이션(Kubernetes 웹 사이트에서)을 참조하세요.

Kubernetes 서비스 어노테이션에서 Network Load Balancer 문제 확인

Kubernetes 서비스 어노테이션에서 Network Load Balancer와 관련된 문제를 확인합니다.

$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE

출력 예:

Name:                     nlb-ip
Namespace:                default
Labels:                   <none>
Annotations:              service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip              
                          service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing          
                          service.beta.kubernetes.io/aws-load-balancer-type: external                   
Selector:                 app=nlb-ip
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.100.161.91
IPs:                      10.100.161.91
LoadBalancer Ingress:     k8s-default-nlbip-fff2442e46-ae4f8cf4a182dc4d.elb.ap-southeast-2.amazonaws.com
Port:                     http  80/TCP
TargetPort:               80/TCP
NodePort:                 http  31806/TCP
Endpoints:                192.168.93.144:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

참고: APPLICATION_POD_IP를 기록해 두세요. 상태 확인 명령을 실행하는 데 필요합니다.

사용 사례와 관련된 Kubernetes 서비스 어노테이션을 찾으려면 서비스 어노테이션(Kubernetes 웹 사이트에서)을 참조하세요.

수동으로 상태 확인 테스트

애플리케이션 포드 IP 주소를 확인합니다.

$ kubectl get pod -n YOUR_NAMESPACE -o wide

테스트 포드를 실행하여 HTTP 상태 확인을 위해 클러스터 내에서 상태 확인을 수동으로 테스트합니다.

$ kubectl run -n YOUR_NAMESPACE troubleshoot -it --rm --image=amazonlinux -- /bin/bash

HTTP 상태 확인의 경우:

# curl -Iv APPLICATION_POD_IP/HEALTH_CHECK_PATH

참고: APPLICATION_POD_IP를 애플리케이션 포드 IP로 바꾸고 HEALTH_CHECK_PATH를 ALB 대상 그룹 상태 확인 경로로 바꿉니다.

명령 예시:

# curl -Iv 192.168.81.137

출력 예:

* Trying 192.168.81.137:80...
* Connected to 192.168.81.137 (192.168.81.137) port 80 (#0)
> HEAD / HTTP/1.1
> Host: 192.168.81.137
> User-Agent: curl/7.78.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.21.3
Server: nginx/1.21.3
< Date: Tue, 26 Oct 2021 05:10:17 GMT
Date: Tue, 26 Oct 2021 05:10:17 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 615
Content-Length: 615
< Last-Modified: Tue, 07 Sep 2021 15:21:03 GMT
Last-Modified: Tue, 07 Sep 2021 15:21:03 GMT
< Connection: keep-alive
Connection: keep-alive
< ETag: "6137835f-267"
ETag: "6137835f-267"
< Accept-Ranges: bytes
Accept-Ranges: bytes

< 
* Connection #0 to host 192.168.81.137 left intact

HTTP 응답 상태 코드를 확인합니다. 응답 상태 코드가 200 OK이면 애플리케이션이 상태 확인 경로에서 올바르게 응답하고 있음을 의미합니다.

HTTP 응답 상태 코드가 3xx 또는 4xx인 경우 상태 확인 경로를 변경할 수 있습니다. 다음 어노테이션은 200 OK로 응답할 수 있습니다.

alb.ingress.kubernetes.io/healthcheck-path: /ping

또는

인그레스 리소스에 대한 다음 어노테이션을 사용하여 성공적인 상태 확인 응답 상태 코드 범위를 추가할 수 있습니다.

alb.ingress.kubernetes.io/success-codes: 200-399

TCP 상태 확인의 경우 다음 명령을 사용하여 netcat 명령을 설치합니다.

# yum update -y && yum install -y nc

TCP 상태 확인을 테스트합니다.

# nc -z -v APPLICATION_POD_IP CONTAINER_PORT_NUMBER

참고: APPLICATION_POD_IP를 애플리케이션 포드 IP로 바꾸고 CONTAINER_PORT_NUMBER를 컨테이너 포트로 바꿉니다.

명령 예:

# nc -z -v 192.168.81.137 80

출력 예:

Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 192.168.81.137:80.
Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds.

네트워킹 확인

네트워킹 문제의 경우 다음을 확인합니다.

  • EKS 클러스터의 여러 노드 그룹은 서로 자유롭게 통신할 수 있습니다.
  • 포드가 실행 중인 서브넷과 연결된 네트워크 액세스 제어 목록(네트워크 ACL)은 로드 밸런서 서브넷 CIDR 범위의 트래픽을 허용합니다.
  • 로드 밸런서 서브넷과 연결된 네트워크 ACL은 포드가 실행 중인 서브넷의 임시 포트 범위에 대한 반환 트래픽을 허용해야 합니다.
  • 라우팅 테이블은 VPC CIDR 범위 내에서의 로컬 트래픽을 허용합니다.

kube-proxy 다시 시작

각 노드에서 실행되는 kube-proxy가 올바르게 동작하지 않으면 서비스와 엔드포인트에 대한 iptables 규칙을 업데이트하지 못할 수 있습니다. kube-proxy를 다시 시작하여 iptables 규칙을 다시 확인하고 업데이트하도록 강제합니다.

kubectl rollout restart daemonset.apps/kube-proxy -n kube-system

출력 예:

daemonset.apps/kube-proxy restarted

이 문서가 도움이 되었나요?


결제 또는 기술 지원이 필요합니까?