Istio egress TLS Origination 구성 시 내부는 HTTP → 외부는 HTTPS 호출 문제

Kubernetes + Istio 환경에서, 내부에서 외부 도메인(external-service.otherdomain.com)으로 요청을 보내려고 합니다. ServiceEntryDestinationRule은 설정했는데, 여전히 내부 트래픽이 HTTP로 포트 443에 전송되며 외부 서비스가 에러를 반환합니다. 예:
The plain HTTP request was sent to HTTPS port

문제 해결을 위해 어떤 설정이 빠졌을까요?

[CloudBro AI Bot Response]
Kubernetes + Istio 환경에서 외부 도메인(external-service.otherdomain.com)으로 HTTPS(포트 443) 요청을 보낼 때 ServiceEntryDestinationRule을 설정했음에도 불구하고, 내부에서 HTTP로 요청이 보내져서 "The plain HTTP request was sent to HTTPS port" 오류가 발생하는 경우, 주로 TLS 설정 누락이 원인입니다.


문제 원인 분석

  • ServiceEntry는 외부 서비스 주소와 포트를 Istio가 인지하도록 해줍니다.
    • DestinationRule은 트래픽 정책을 정의하는데, 여기서 TLS 설정이 빠지면 Istio는 기본적으로 HTTP로 요청을 보냅니다.
    • HTTPS 포트(443)로 HTTP 요청을 보내면, 외부 서비스는 TLS 핸드셰이크 없이 평문 HTTP 요청을 받아 오류를 반환합니다.
      즉, DestinationRule에서 TLS 모드를 명시하지 않으면 HTTP로 요청을 보내는 기본 동작이 발생합니다.

해결 방법: DestinationRule에 TLS 설정 추가

1. DestinationRule 예시

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: external-service-destination
spec:
  host: external-service.otherdomain.com
  trafficPolicy:
    portLevelSettings:
    - port:
        number: 443
      tls:
        mode: SIMPLE  # TLS origination 활성화
        sni: external-service.otherdomain.com
  • mode: SIMPLE 은 Istio가 클라이언트 측 TLS를 시작하도록 지시합니다.
    • sni는 TLS 핸드셰이크에서 서버 이름 표시(Server Name Indication)를 설정하는 옵션입니다. 외부 서비스와 일치해야 합니다.

2. ServiceEntry 예시 (참고)

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: external-service-entry
spec:
  hosts:
  - external-service.otherdomain.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS
  location: MESH_EXTERNAL
  • protocol: HTTPS 로 명시해도 DestinationRule의 TLS 설정이 반드시 필요합니다.

추가 참고 사항

  • 만약 portLevelSettings를 사용하지 않고 trafficPolicy.tls를 바로 지정할 수도 있습니다. 다만, 포트별 설정이 명확해지는 portLevelSettings 권장.
    • mode 옵션 종류:
    • DISABLE: TLS 사용 안함
    • SIMPLE: 클라이언트 TLS origination (일반 HTTPS)
    • MUTUAL: 상호 TLS 인증
    • ISTIO_MUTUAL: Istio 내부 mTLS (외부에는 사용 안함)

참고 링크


요약

문제점 해결책
HTTPS 포트(443)에 HTTP 요청 전송 DestinationRule에 trafficPolicy.tls.mode: SIMPLE 설정 추가
SNI 미설정으로 TLS 핸드셰이크 실패 sni 필드에 외부 도메인명 설정

이렇게 DestinationRule에 TLS origination 설정을 추가하면 Istio가 외부 서비스로 HTTPS 요청을 올바르게 전송하여 문제를 해결할 수 있습니다.

  1. ServiceEntry에 targetPort: 443 지정 필요
    • HTTP 80 → 443 리다이렉션을 위해 아래처럼 설정해야 합니다.
  2. DestinationRule에 portLevelSettings 사용해 TLS 모드 명시
    • HTTP 80 요청을 TLS SIMPLE 모드로 암호화하여 외부로 전송할 수 있게 설정해야 합니다.

예시 재구성 설정:

yaml
Copy
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
spec:
  hosts:
    - external-service.otherdomain.com
  ports:
    - number: 80
      name: http
      protocol: HTTP
      targetPort: 443
    - number: 443
      name: https
      protocol: HTTPS
  location: MESH_EXTERNAL
  resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
spec:
  host: external-service.otherdomain.com
  trafficPolicy:
    portLevelSettings:
    - port:
        number: 80
      tls:
        mode: SIMPLE

이렇게 구성하면, 내부에서 http://external-service.otherdomain.com URL 그대로 호출해도, Istio가 자동으로 TLS 연결을 생성하여 외부 서비스와 HTTPS 통신이 가능해집니다.