[Istio] NLB 의 Target Group 헬스 체크 실패

2025. 4. 30. 00:15·Service Mesh/Istio 운영 특이사항

들어가기 앞서

현재 운영 중인 서비스는 AWS Control Tower 구성으로 되어 있다. Security 계정에 3rd Party 보안 솔루션이 있다. 사용자의 트래픽은 각 계정의 보안 솔루션을 통과하고 최종적으로 Web 서버가 배포되어 있는 계정의 EKS에 먼저 도달한다. EKS 앞에는 NLB와 ALB(istio) 가 있다. 즉, NLB - ALB - EKS 구성으로 트래픽이 전달된다. 

문제는 8443 포트의 리스너에서 헬스체크 실패가 발생했다. 최상단의 NLB 에서 시작되는 헬스체크는 EKS 에 도달하여 결과를 반환한다. 즉, NLB의 헬스체크와 ALB의 헬스체크는 모두 EKS 에서 설정한 헬스체크 경로에서 반환한다는 것이다. 

Readiness Probe 경로 문제인가

제일 먼저 짚고 넘어가야 할 점은 Readiness Probe 의 경로이다. 기본적으로 Deployment 의 YAML 파일을 열어보면 각 Probe 를 정의할 수 있다. 특히 Readiness Probe 를 정의한다면 헬스 체크 파라미터와 경로 및 Port 를 정의할 수 있다. Probe 가 뭔지 모르겠다면 아래의 주인장이 예전에 포스팅한 블로그 글을 보자! 

https://hyukops.tistory.com/58

 

Kubernetes Pod 헬스 체크 (Probe)

들어가기 앞서 파드가 노드에 스케줄링되는 즉시 해당 노드의 kubelet 은 컨테이너를 실행하고, 그 이후부터는 파드가 존재하는한 컨테이너를 계속 실행한다. 컨테이너의 메인 프로세스가 충돌

hyukops.tistory.com

결론부터 말하자면 Load Balancer의 헬스체크와 Kubernetes의 Probe는 완전히 다른 메커니즘이다. Kubernetes의 liveness 또는 readiness probe는 kubelet이 직접 해당 파드에 접속하여 헬스체크를 수행하는 방식이다. 일반적으로 파드 내부의 컨테이너에서 localhost 기준의 포트나 경로(/health, /ready 등)로 체크하게 되며, 이는 클러스터 내부 통신이기 때문에 외부 의존성 없이 동작한다. 즉, 애플리케이션이 정상적으로 기동되어 있고 설정된 엔드포인트가 응답을 반환하면 정상(Healthy)으로 판단된다.

 

반면, Load Balancer의 헬스체크는 외부에서 네트워크를 통해 접근하는 방식이다. AWS의 NLB나 ALB를 예로 들면, Load Balancer는 등록된 타겟(예: 파드나 노드)으로 TCP 또는 HTTP(S) 요청을 보내고 응답을 기준으로 상태를 판단한다. 이때 대상 파드가 클러스터 내부에서만 접근 가능한 주소(localhost 등)로만 서비스하고 있다면, Load Balancer는 해당 엔드포인트에 접근할 수 없어 헬스체크가 실패하게 된다. 즉, Probe는 내부에서 바라보는 건강 상태, Load Balancer는 외부에서 바라보는 연결 가능성을 기준으로 한다. 이 차이로 인해 파드는 정상으로 보이지만, Load Balancer에서는 Unhealthy로 판단되는 상황이 발생할 수 있다.

*주의*
Istio에서 사용하는 Gateway와 VirtualService는 Kubernetes 기본 리소스가 아니다. 따라서 kubectl get all -A 명령어를 실행해도 이 두 리소스는 출력되지 않는다.

이유는 간단하다. Gateway와 VirtualService는 Istio가 정의한 Custom Resource Definition(CRD) 이기 때문이다. Kubernetes는 기본적으로 Pod, Service, Deployment 같은 표준 리소스만 get all에 포함해서 보여주므로, CRD 기반 리소스는 명시적으로 요청해야 한다.

따라서 Istio 리소스를 확인하려면 아래와 같은 명령어를 사용해야 한다:
kubectl get gateway -A
kubectl get virtualservice -A

문제점은 어디서?

Istio 에서 헬스 체크를 설정하는 방법 또한 다양하다. IngressGateway (service) 에서 수행할 수도 있고 실제 애플리케이션으로 보내 헬스체크를 수행할 수도 있다. 해당 방법 또한 나중에 포스팅 하도록 하자. 결론부터 말하면 문제점은 VirtualService 에서 찾았다. Istio에서 VirtualService를 구성할 때, hosts와 match 조건을 함께 사용하는 패턴은 특정 트래픽에 대한 정교한 라우팅을 가능하게 한다. 

  • hosts: 수신 요청의 Host 헤더가 web.application.com인 경우에만 적용.
  • match.uri.prefix: URI가 /web으로 시작하는 요청에만 라우팅 규칙을 적용.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: ibj-web-virtual-service
spec:
  hosts:
    - web.application.com
  gateways:
    - web-gateway
  http:
    - match:
        - uri:
            prefix: /web
      route:
        - destination:
            host: web-service
            port:
              number: 80

이 설정은 “Host 헤더가 web.application.com이고, URI가 /web로 시작하는 요청”만 web-service로 라우팅되도록 한다.
이러한 방식은 여러 서비스가 동일한 Gateway를 공유하면서도 트래픽을 구분하는 데 유용하다. 하지만 NLB(Network Load Balancer) 는 L4 로드밸런서로, 헬스체크 시 Host 헤더 없이 HTTP 요청을 보낸다.

따라서 VirtualService의 hosts 조건(web.application.com)과 일치하지 않아 요청이 라우팅되지 못하고, IngressGateway는 404 또는 503을 반환한다. 이로 인해 NLB는 해당 엔드포인트를 헬스체크 실패로 판단하게 된다.

 

NLB 가 헬스체크에 실패한 이유

  • NLB는 L4 로드밸런서로, Host 헤더 없이 HTTP 요청을 보냄
  • VirtualService는 Host와 URI 조건이 모두 맞아야 라우팅됨
  • Host 헤더가 없는 요청은 VirtualService에 매칭되지 않아 404 또는 503 반환
  • 따라서 NLB는 헬스 체크 실패로 간주함
Envoy Proxy는 VirtualService에 명시된 조건을 충족하지 못하는 요청에 대해 기본적으로 404 또는 503을 반환

ALB 가 헬스체크에 성공한 이유

  • ALB는 L7 로드밸런서로, HTTP 프로토콜 기반 헬스 체크를 보냄
  • ALB 헬스 체크는 다음과 같은 특징을 가짐
    • 기본적으로 GET / 또는 설정된 경로로 요청
    • Host 헤더는 ALB 자체 도메인(예: internal-alb-123.elb.amazonaws.com)으로 포함됨
  • Envoy는 VirtualService에 매칭되지 않더라도, 다음 중 하나의 이유로 200 OK를 반환할 수 있음:
    1. Istio Gateway에 연결된 VirtualService 중 하나가 해당 Host에 일부라도 대응
    2. Fallback 또는 Envoy 필터 설정이 있어 미매칭 시에도 200을 반환하도록 설정
    3. 다른 VirtualService에서 ALB의 Host를 처리하고 있을 가능성

즉, ALB는 기본적으로 Host 헤더가 포함되고, Envoy는 그 Host에 대해 기본적인 처리로 200을 반환하고 있을 가능성이 높음

 

 

'Service Mesh > Istio 운영 특이사항' 카테고리의 다른 글

[istio] Default Health Check Route and Port  (0) 2025.10.26
[istio] argo rollout + istio 를 통한 canary 배포 전략 도입  (0) 2025.10.26
[istio] istioOperator 커스텀  (0) 2025.08.20
[istio] istio proxy 의 Graceful Startup & Termination  (2) 2025.08.07
[istio] istio 의 Access Log 활성화  (3) 2025.08.06
'Service Mesh/Istio 운영 특이사항' 카테고리의 다른 글
  • [istio] argo rollout + istio 를 통한 canary 배포 전략 도입
  • [istio] istioOperator 커스텀
  • [istio] istio proxy 의 Graceful Startup & Termination
  • [istio] istio 의 Access Log 활성화
Hyukops
Hyukops
안녕하세요
  • Hyukops
    Hyukops 님의 Tech Blog
    Hyukops
    • 분류 전체보기 (141)
      • Introduction (1)
      • Kubernetes & EKS (43)
        • k8s in action (9)
        • k8s 공부 기록 (17)
        • k8s 운영 가이드 (10)
        • k8s 운영 특이사항 (7)
      • Service Mesh (29)
        • Istio 공부 기록 (20)
        • Istio 운영 특이사항 (9)
      • CICD (10)
        • argoCD 공부 기록 (6)
        • argoCD 운영 특이사항 (4)
      • Logging & Monitoring (5)
        • Prometheus 운영 특이사항 (0)
        • fluent bit 운영 특이사항 (5)
      • Infrastructure as Code (8)
        • terraform 공부 기록 (3)
        • terraform 운영 특이사항 (5)
      • AWS (40)
        • aws 공부 기록 (29)
        • 솔루션 사례 & 문제 해결 (11)
      • Database (5)
        • postgreSQL (5)
  • 태그

    k8s in action
    fluent bit
    canary
    Istio
    argocd
    PostgreSQL
    prometheus
    MSK
    kubernetes
    Terraform
    Database
    AWS
    eks
    fluentbit
    Logging
    aws saa
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Hyukops
[Istio] NLB 의 Target Group 헬스 체크 실패
상단으로

티스토리툴바