Ssoon

2주차 : Istio 데이터 플레인 > The Envoy proxy : Envoy in action 본문

Istio Hands-on Study [1기]

2주차 : Istio 데이터 플레인 > The Envoy proxy : Envoy in action

구구달스 2025. 4. 15. 13:27
CloudNet@ 가시다님이 진행하는 Istio Hands-on Study [1기]

🚀 Envoy와 Docker로 프록시 서비스 쉽게 시작하기

Envoy는 강력한 프록시 소프트웨어로, C++로 작성되어 특정 플랫폼에 맞게 컴파일됩니다. Docker를 사용하면 훨씬 간단하게 Envoy를 실행하고 테스트할 수 있습니다! 


🐳 Docker로 Envoy 환경 준비하기

Envoy를 시작하려면 먼저 Docker 환경이 필요합니다.

Docker가 준비되었다면, Envoy와 테스트에 필요한 세 가지 Docker 이미지를 다운로드합니다.

명령어는 다음과 같습니다:

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker pull envoyproxy/envoy:v1.19.0
v1.19.0: Pulling from envoyproxy/envoy
...
Digest: sha256:ec7228053c7e99bf481901960b9074528be407ede2363b6152fb93a1eee872cf
Status: Downloaded newer image for envoyproxy/envoy:v1.19.0
docker.io/envoyproxy/envoy:v1.19.0

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker pull curlimages/curl
Using default tag: latest
latest: Pulling from curlimages/curl
...
Digest: sha256:d43bdb28bae0be0998f3be83199bfb2b81e0a30b034b6d7586ce7e05de34c3fd
Status: Downloaded newer image for curlimages/curl:latest
docker.io/curlimages/curl:latest

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker pull mccutchen/go-httpbin
Using default tag: latest
latest: Pulling from mccutchen/go-httpbin
...
Digest: sha256:ff73c96c144506048b1357ada7015b3473adc1d5bebc7088bc389bf5e64e114f
Status: Downloaded newer image for mccutchen/go-httpbin:latest
docker.io/mccutchen/go-httpbin:latest

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker images
REPOSITORY             TAG        IMAGE ID       CREATED         SIZE
curlimages/curl        latest     e507f3e43db3   11 days ago     21.9MB
mccutchen/go-httpbin   latest     18fc7a0469d6   12 days ago     38.1MB
envoyproxy/envoy       v1.19.0    f48f130ac643   3 years ago     134MB
  • docker pull envoyproxy/envoy:v1.19.0
  • docker pull curlimages/curl
  • docker pull mccutchen/go-httpbin

이 이미지들은 각각 Envoy 프록시, HTTP 요청을 테스트할 curl 클라이언트, 그리고 테스트용 백엔드 서비스인 httpbin을 제공합니다.

Docker를 사용하면 Envoy와 테스트 환경을 빠르게 설정할 수 있습니다.

🌐 httpbin 서비스 이해하기

httpbin은 HTTP 요청을 테스트하기 위한 유용한 서비스입니다. 이 서비스는 요청한 헤더를 반환하거나, 요청을 지연시키거나, 의도적으로 에러를 발생시키는 등 다양한 엔드포인트를 제공합니다.

httpbin 서비스를 Docker 컨테이너로 실행한 뒤, Envoy를 설정해 모든 트래픽을 httpbin으로 프록시하도록 구성할 것입니다. 이후 curl 클라이언트를 사용Envoy를 통해 httpbin에 요청을 보내고 결과를 확인합니다.

httpbin은 HTTP 요청 테스트에 최적화된 서비스로, 다양한 엔드포인트를 통해 프록시 동작을 확인할 수 있습니다.

🛠 Envoy 프록시 설정과 테스트

httpbin 서비스를 실행하고, Envoy를 프록시로 설정합니다. Envoy는 클라이언트(curl)와 httpbin 사이에서 모든 트래픽을 중계합니다. 아래는 우리가 구축할 아키텍처의 간단한 흐름입니다:

  1. httpbin 서비스: 백엔드 역할을 하며 HTTP 요청을 처리.
  2. Envoy 프록시: 모든 트래픽을 httpbin으로 전달.
  3. curl 클라이언트: Envoy를 통해 httpbin에 요청을 보냄.

이 아키텍처는 Envoy의 트래픽 라우팅과 관리 기능을 탐색합니다. 설정이 완료되면 curl로 Envoy에 요청을 보내고, httpbin이 반환하는 응답을 확인할 수 있습니다.

Envoy는 클라이언트와 백엔드 사이에서 트래픽을 중계하며, 간단한 설정으로 프록시 기능을 테스트할 수 있습니다.

🎯 핵심 포인트

Docker를 사용해 Envoy, httpbin, curl 이미지를 준비하고, httpbin 서비스를 실행한 뒤, Envoy를 프록시로 설정해 트래픽을 중계
주요 단계: Docker 이미지 다운로드 → httpbin 서비스 실행 → Envoy 프록시 설정 → curl로 테스트

🐳 Docker로 httpbin 서비스 실행하기


🚀 httpbin 컨테이너 실행하기

첫 번째 명령어는 httpbin 서비스를 Docker 컨테이너로 실행하는 과정입니다:

  • 명령어:  docker run -d -e PORT=8000 --name httpbin mccutchen/go-httpbin
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker run -d -e PORT=8000 --name httpbin mccutchen/go-httpbin
8104ccc7642e3c5790f44146ed9557605b051b5ea0eba192bc3524c7a58e55d7

 

  • docker run: 새 컨테이너를 생성하고 실행합니다.
  • -d: 컨테이너를 백그라운드에서 실행(Detached 모드).
  • -e PORT=8000: 환경 변수 PORT를 8000으로 설정해 httpbin이 8000번 포트에서 실행되도록 지정.
  • --name httpbin: 컨테이너 이름을 httpbin으로 지정.
  • mccutchen/go-httpbin: 사용할 Docker 이미지 이름.
이 명령어는 httpbin 서비스를 8000번 포트에서 실행하는 컨테이너를 백그라운드에서 띄웁니다.

🔍 실행 중인 컨테이너 확인하기

현재 실행 중인 Docker 컨테이너를 확인합니다:

  • 명령어:  docker ps

 

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS         PORTS                                                             NAMES
8104ccc7642e   mccutchen/go-httpbin    "/bin/go-httpbin"        4 seconds ago   Up 3 seconds   8080/tcp                                                          httpbin
  • CONTAINER ID: 컨테이너의 고유 ID (8104ccc7642e).
  • IMAGE: 사용된 이미지 (mccutchen/go-httpbin).
  • COMMAND: 컨테이너 시작 시 실행된 명령어 (/bin/go-httpbin).
  • CREATED: 컨테이너 생성 시점 (4 seconds ago).
  • STATUS: 컨테이너 상태 (Up 3 seconds).
  • PORTS: 컨테이너가 사용하는 포트 (8080/tcp). 참고로, 명령어에서 PORT=8000을 설정했지만, 출력에는 기본 포트 8080/tcp가 표시됨.
  • NAMES: 컨테이너 이름 (httpbin).

이 결과는 httpbin 컨테이너가 정상적으로 실행 중임을 보여줍니다.

docker ps 명령어로 실행 중인 컨테이너의 상태와 세부 정보를 확인할 수 있습니다.

🎯 핵심 포인트

Docker를 사용해 httpbin 서비스를 실행하고 확인하는 두 가지 명령어
첫 번째로, docker run 명령어로 httpbin 컨테이너를 8000번 포트에서 백그라운드 실행
두 번째로 docker ps 명령어로 컨테이너의 실행 상태를 확인
주요 단계: httpbin 컨테이너 실행 → 실행 상태 확인.

🌐 Docker로 curl을 사용해 httpbin 테스트하기


🚀 curl 컨테이너로 httpbin에 요청 보내기

이 명령어는 curl 컨테이너를 실행해 httpbin 서비스의 /headers 엔드포인트에 GET 요청을 보내는 과정입니다.

  • docker run -it --rm --link httpbin curlimages/curl curl -X GET http://httpbin:8000/headers

각 옵션의 의미를 살펴보면:

  • docker run: 새 컨테이너를 생성하고 실행.
  • -it: 인터랙티브 모드로 터미널과 상호작용 가능.
  • --rm: 컨테이너 실행 후 자동으로 삭제.
  • --link httpbin: curl 컨테이너를 httpbin 컨테이너와 연결해 이름(httpbin)으로 통신 가능.
  • curlimages/curl: 사용할 curl 이미지.
  • curl -X GET http://httpbin:8000/headers: httpbin의 8000번 포트 /headers 엔드포인트에 GET 요청을 보냄.

이 명령은 curl을 통해 httpbin에 요청을 보내고, 요청에 포함된 헤더 정보를 반환받습니다.

curl 컨테이너를 사용해 httpbin 서비스에 GET 요청을 보내 헤더 정보를 확인할 수 있습니다.

📋 httpbin의 응답 확인하기

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker run -it --rm --link httpbin curlimages/curl curl -X GET http://httpbin:8000/headers
{
  "headers": {
    "Accept": [
      "*/*"
    ],
    "Host": [
      "httpbin:8000"
    ],
    "User-Agent": [
      "curl/8.13.0"
    ]
  }
}

 

명령어 실행 후 httpbin은 JSON 형식으로 응답을 반환합니다. 응답은 요청에 포함된 헤더 정보를 보여줍니다:

  • "Accept": "*/*": 모든 콘텐츠 타입을 수락.
  • "Host": "httpbin:8000": 요청 대상 호스트와 포트.
  • "User-Agent": "curl/8.13.0": 요청을 보낸 클라이언트(curl)의 정보.

이 응답은 httpbin이 요청을 올바르게 처리했으며, curl 컨테이너와 httpbin 컨테이너 간 통신이 성공적으로 이루어졌음을 나타냅니다. --link 옵션을 통해 두 컨테이너가 네트워크상에서 서로 연결되었기 때문에, curl이 httpbin이라는 이름으로 httpbin 서비스에 접근할 수 있었습니다.

httpbin은 요청 헤더를 JSON으로 반환하며, 컨테이너 간 통신이 성공했음을 확인할 수 있습니다.

🎯 핵심 포인트

Docker에서 curl 컨테이너를 실행해 httpbin 서비스에 HTTP GET 요청을 보내고, 응답을 확인
curl 컨테이너는 --link 옵션으로 httpbin과 연결되어 이름 기반 통신을 가능하게 했고, /headers 엔드포인트는 요청 헤더를 JSON으로 반환
주요 단계: curl 컨테이너 실행 → httpbin에 GET 요청 → 헤더 정보 확인

🚀 Docker로 Envoy 프록시 실행 및 옵션 탐색하기


🛠 Envoy의 명령줄 옵션 확인하기

첫 번째로, Envoy 컨테이너를 실행해 --help 플래그를 사용해 지원하는 옵션들을 확인합니다:

  • 명령어: docker run -it --rm envoyproxy/envoy:v1.19.0 envoy --help

이 명령어는 다음과 같은 일을 합니다:

  • docker run -it: 인터랙티브 모드로 컨테이너를 실행해 터미널과 상호작용.
  • --rm: 컨테이너 실행 후 자동 삭제.
  • envoyproxy/envoy:v1.19.0: 사용할 Envoy 이미지.
  • envoy --help: Envoy의 도움말을 출력해 사용 가능한 플래그와 파라미터를 표시.

도움말에서 주목할 만한 플래그는 다음과 같습니다:

  • -c: 설정 파일의 경로를 지정.
  • --service-zone: 프록시가 배포된 가용 영역(availability zone)을 지정.
  • --service-node: 프록시에 고유한 이름을 부여.
  • --log-level: 프록시의 로그 출력 수준(verbosity)을 조정.

이 옵션들은 Envoy를 실제 환경에 맞게 커스터마이징할 때 유용합니다.

--help 플래그로 Envoy의 다양한 설정 옵션을 확인할 수 있으며, 주요 플래그를 통해 프록시를 유연하게 구성할 수 있습니다.

🏃‍♂️ Envoy 프록시 실행 시도하기

이제 Envoy 컨테이너를 실행해 프록시를 띄워봅니다:

  • 명령어: docker run -it --rm envoyproxy/envoy:v1.19.0 envoy

이 명령은 Envoy를 기본 설정으로 실행하려고 시도합니다. 하지만 실행하면 다음과 같은 에러 메시지가 출력됩니다:

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker run -it --rm envoyproxy/envoy:v1.19.0 envoy
...
[2025-04-17 05:17:48.929][1][info][main] [source/server/server.cc:855] exiting
At least one of --config-path or --config-yaml or Options::configProto() should be non-empty

 

이 에러는 Envoy가 실행되기 위해 필수적인 설정 정보가 누락되었음을 알려줍니다.

Envoy는 최소한 다음 중 하나를 제공해야 합니다:

  • --config-path: 설정 파일의 경로.
  • --config-yaml: YAML 형식의 설정 내용.
  • Options::configProto(): 프로그램 내 설정.

즉, Envoy는 단순히 실행 명령만으로는 동작하지 않고, 프록시의 동작 방식을 정의한 설정 파일이나 YAML이 필요합니다.

Envoy를 실행하려면 반드시 설정 파일이나 YAML을 제공해야 하며, 이를 생략하면 에러가 발생합니다.

🎯 핵심 포인트

--help 플래그로 주요 옵션(-c, --service-zone, --service-node, --log-level)을 확인
Envoy 실행 시도 시 설정 파일이 없으면 에러가 발생함
주요 단계: Envoy 옵션 확인 → 프록시 실행 시도 → 설정 누락 에러 확인.

🚀 Envoy 설정 파일로 httpbin 프록시 구성하기


Envoy 프록시를 실행하려면 설정 파일이 필수입니다.

simple.yaml 파일을 통해 Envoy를 구성하여 httpbin 서비스로 트래픽을 프록시합니다.

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master/ch3$ cat simple.yaml

admin:
  address:
    socket_address: { address: 0.0.0.0, port_value: 15000 }

static_resources:
  listeners:
  - name: httpbin-demo
    address:
      socket_address: { address: 0.0.0.0, port_value: 15001 }
    filter_chains:
    - filters:
      - name:  envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          http_filters:
          - name: envoy.filters.http.router
          route_config:
            name: httpbin_local_route
            virtual_hosts:
            - name: httpbin_local_service
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route:
                  auto_host_rewrite: true
                  cluster: httpbin_service
  clusters:
    - name: httpbin_service
      connect_timeout: 5s
      type: LOGICAL_DNS
      dns_lookup_family: V4_ONLY
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: httpbin
        endpoints:
        - lb_endpoints:
          - endpoint:
              address:
                socket_address:
                  address: httpbin
                  port_value: 8000

🛠 Envoy 관리 인터페이스 설정하기

설정 파일의 첫 번째 부분은 Envoy의 관리 인터페이스(admin interface)입니다. 이 인터페이스는 Envoy의 상태를 모니터링하거나 관리 명령을 실행할 때 사용됩니다.

admin:
  address:
    socket_address: { address: 0.0.0.0, port_value: 15000 }
  • 설정 내용:
    • admin: 관리 인터페이스를 정의.
    • address: 관리 인터페이스가 수신 대기할 IP와 포트를 지정.
    • socket_address: 0.0.0.0:15000으로 설정해 모든 IP에서 15000번 포트로 접근 가능.

이 설정을 통해 Envoy는 15000번 포트에서 관리 요청을 받아 상태 정보를 제공하거나 설정을 변경할 수 있습니다.

관리 인터페이스는 Envoy의 상태를 모니터링하고 관리하기 위해 15000번 포트에서 동작합니다.

🌐 리스너 설정으로 트래픽 수신 준비하기

다음은 Envoy가 외부 트래픽을 수신하도록 설정하는 listeners 섹션입니다.

이 부분은 Envoy가 클라이언트 요청을 받아들이는 진입점(entry point)을 정의합니다.

static_resources:
  listeners:
  - name: httpbin-demo
    address:
      socket_address: { address: 0.0.0.0, port_value: 15001 }
    filter_chains:
    - filters:
      - name:  envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          http_filters:
          - name: envoy.filters.http.router
          route_config:
            name: httpbin_local_route
            virtual_hosts:
            - name: httpbin_local_service
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route:
                  auto_host_rewrite: true
                  cluster: httpbin_service
  • 설정 내용:
    • name: httpbin-demo: 리스너의 이름.
    • address: 0.0.0.0:15001으로 설정해 모든 IP에서 15001번 포트로 요청 수신.
    • filter_chains: 요청을 처리할 필터 체인을 정의.
    • filters: HTTP 트래픽을 처리하기 위해 envoy.filters.network.http_connection_manager 사용.
    • http_filters: envoy.filters.http.router를 사용해 요청을 라우팅.
    • route_config: 모든 요청(prefix: "/")을 httpbin_service 클러스터로 라우팅.

이 설정은 Envoy가 15001번 포트로 들어오는 HTTP 요청을 받아 httpbin_service로 전달하도록 만듭니다.

리스너는 Envoy가 클라이언트 요청을 수신하는 포트를 설정하며, HTTP 요청을 처리하고 라우팅합니다.

🔗 클러스터 설정으로 백엔드 연결하기

마지막으로, clusters 섹션은 Envoy가 요청을 전달할 백엔드 서비스(httpbin)를 정의합니다.

  clusters:
    - name: httpbin_service
      connect_timeout: 5s
      type: LOGICAL_DNS
      dns_lookup_family: V4_ONLY
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: httpbin
        endpoints:
        - lb_endpoints:
          - endpoint:
              address:
                socket_address:
                  address: httpbin
                  port_value: 8000
  • 설정 내용:
    • name: httpbin_service: 클러스터의 이름.
    • connect_timeout: 5s: 백엔드 연결 시도 시간 제한.
    • type: LOGICAL_DNS: DNS를 사용해 백엔드 주소를 확인.
    • dns_lookup_family: V4_ONLY: IPv4 주소만 사용.
    • lb_policy: ROUND_ROBIN: 부하 분산 정책으로 라운드 로빈 선택.
    • load_assignment: 백엔드 엔드포인트를 정의.
    • endpoint: httpbin 서비스의 주소(httpbin:8000) 지정.

이 설정은 Envoy가 httpbin 서비스(8000번 포트)로 요청을 전달하도록 연결을 구성합니다.

클러스터는 Envoy가 요청을 전달할 백엔드 서비스의 위치와 연결 방식을 정의합니다.

🎯 핵심 포인트

simple.yaml 설정 파일을 통해 Envoy 프록시를 구성
관리 인터페이스(admin)로 모니터링 포트를 설정하고, 리스너(listeners)로 클라이언트 요청을 수신하며, 클러스터(clusters)로 httpbin 서비스와 연결
주요 단계: 관리 인터페이스 설정 → 리스너로 요청 수신 → 클러스터로 백엔드 연결

🚀 Envoy 프록시를 설정 파일로 실행하기


🌐 Envoy 프록시 실행하기

simple.yaml 설정 파일을 사용해 Envoy 프록시를 실행하는 과정입니다:

  • 명령어: docker run --name proxy --link httpbin envoyproxy/envoy:v1.19.0 --config-yaml "$(cat ch3/simple.yaml)"
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master/ch3$ docker run --name proxy --link httpbin envoyproxy/envoy:v1.19.0 --config-yaml "$(cat simple.yaml)"

 

이 명령어는 다음과 같은 일을 합니다:

  • docker run: 새 컨테이너를 생성하고 실행.
  • --name proxy: 컨테이너 이름을 proxy로 지정.
  • --link httpbin: Envoy 컨테이너를 httpbin 컨테이너와 연결해 이름(httpbin)으로 통신 가능.
  • envoyproxy/envoy:v1.19.0: 사용할 Envoy 이미지.
  • --config-yaml "$(cat ch3/simple.yaml)": simple.yaml 파일의 내용을 YAML 형식으로 Envoy에 전달.

이 설정은 Envoy가 15001번 포트에서 리스너를 열고, 모든 트래픽을 httpbin 서비스(8000번 포트)로 라우팅하도록 만듭니다.

simple.yaml 설정 파일을 사용해 Envoy 프록시를 실행하면 httpbin으로 트래픽을 프록시할 준비가 됩니다.

📋 Envoy 실행 상태 확인하기

Envoy가 정상적으로 실행되었는지 확인하기 위해 컨테이너 로그를 살펴봅니다:

  • 명령어: docker logs proxy

로그 출력은 다음과 같습니다:

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker logs proxy
...
[2025-04-17 05:38:43.411][1][info][main] [source/server/server.cc:785] all clusters initialized. initializing init manager
[2025-04-17 05:38:43.411][1][info][config] [source/server/listener_manager_impl.cc:834] all dependencies initialized. starting workers
[2025-04-17 05:38:43.423][1][info][main] [source/server/server.cc:804] starting main dispatch loop

 

로그의 의미는 다음과 같습니다:

  • all dependencies initialized. starting workers: Envoy가 필요한 모든 의존성을 초기화하고 워커 프로세스를 시작했음을 나타냄.
  • starting main dispatch loop: Envoy의 메인 이벤트 루프가 시작되어 트래픽을 처리할 준비가 완료됨.

이 로그는 Envoy가 설정 파일을 성공적으로 읽고, 프록시로서 정상적으로 동작 중임을 보여줍니다.

docker logs 명령어로 Envoy의 실행 상태를 확인할 수 있으며, 로그는 프록시가 정상적으로 시작되었음을 알려줍니다.

🎯 핵심 포인트

simple.yaml 설정 파일을 사용해 Envoy 프록시를 실행하고, 실행 상태를 로그로 확인
Envoy는 15001번 포트에서 트래픽을 수신해 httpbin 서비스로 라우팅하며, 로그를 통해 초기화와 실행이 성공했음을 확인
주요 단계: Envoy 프록시 실행 → 로그로 실행 상태 확인

🌐 Envoy 프록시를 통해 httpbin 서비스 테스트하기


🚀 curl로 Envoy 프록시 호출하기

Envoy 프록시는 15001번 포트에서 트래픽을 수신하고, 이를 httpbin 서비스로 라우팅하도록 설정되었습니다. 다음 명령어로 curl을 사용해 프록시를 테스트합니다:

  • 명령어: docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15001/headers

이 명령어는 다음과 같은 일을 합니다:

  • docker run -it: 인터랙티브 모드로 curl 컨테이너를 실행.
  • --rm: 컨테이너 실행 후 자동 삭제.
  • --link proxy: curl 컨테이너를 Envoy 프록시 컨테이너와 연결해 proxy 이름으로 접근.
  • curl -X GET http://proxy:15001/headers: Envoy 프록시의 15001번 포트로 GET 요청을 보내 /headers 엔드포인트를 호출.

이 요청은 Envoy를 통해 httpbin 서비스로 전달되며, httpbin은 요청에 포함된 헤더 정보를 JSON으로 반환합니다.

curl로 Envoy 프록시를 호출하면 요청이 httpbin 서비스로 라우팅되어 헤더 정보를 반환받습니다.

📋 httpbin 응답과 Envoy의 추가 헤더 확인하기

명령어 실행 후, httpbin은 다음과 같은 JSON 응답을 반환합니다:

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15001/headers
{
  "headers": {
    "Accept": [
      "*/*"
    ],
    "Host": [
      "httpbin"
    ],
    "User-Agent": [
      "curl/8.13.0"
    ],
    "X-Envoy-Expected-Rq-Timeout-Ms": [
      "15000"
    ],
    "X-Forwarded-Proto": [
      "http"
    ],
    "X-Request-Id": [
      "a130384a-8534-47bc-9c85-636ec301ea8c"
    ]
  }
}
  • "Accept": "*/*": 모든 콘텐츠 타입 수락.
  • "Host": "httpbin": 요청 대상 호스트.
  • "X-Envoy-Expected-Rq-Timeout-Ms": "15000": 요청 타임아웃 15초.
  • "X-Request-Id": 요청 고유 ID.

응답을 보면, Envoy가 추가한 두 개의 헤더가 눈에 띕니다:

  • X-Request-Id: 각 요청에 고유한 ID를 부여해, 클러스터 내 여러 서비스를 거치는 요청을 추적하고 연관 짓는 데 사용. 이는 디버깅과 로깅에 매우 유용합니다.
  • X-Envoy-Expected-Rq-Timeout-Ms: 요청이 15,000ms(15초) 후 타임아웃될 것임을 상위 서비스에 알림. 이 값은 상위 시스템이 타임아웃을 고려해 처리 중단 시점을 결정하도록 돕습니다.

이 헤더들은 Envoy가 단순히 트래픽을 전달하는 것을 넘어, 요청 관리와 최적화를 위한 부가 기능을 제공함을 보여줍니다.

Envoy는 요청에 X-Request-Id와 X-Envoy-Expected-Rq-Timeout-Ms 헤더를 추가해 추적과 타임아웃 관리를 지원합니다.

🎯 전체 과정의 핵심 포인트

curl을 사용해 Envoy 프록시를 호출하고, httpbin 서비스로 트래픽이 올바르게 전달되는지 확인
Envoy는 요청을 httpbin으로 라우팅하며, X-Request-Id와 X-Envoy-Expected-Rq-Timeout-Ms 헤더를 추가해 요청 추적과 타임아웃 관리를 지원
주요 단계: curl로 프록시 호출 → httpbin 응답 확인 → Envoy 추가 헤더 분석

⏰ Envoy 설정 변경으로 타임아웃 조정하기


🔧 타임아웃 설정 변경하기

기존 simple.yaml 설정 파일에서 요청 타임아웃을 변경해 새로운 설정 파일(simple_change_timeout.yaml)을 준비했습니다. 변경된 부분은 route 섹션에 timeout: 1s를 추가한 것입니다:

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master/ch3$ cat simple_change_timeout.yaml
...
              routes:
              - match: { prefix: "/" }
                route:
                  auto_host_rewrite: true
                  cluster: httpbin_service
                  timeout: 1s
 ...
  • 변경 내용:
    • match: { prefix: "/" }: 모든 경로(/)에 대한 요청을 매칭.
    • route:
      • auto_host_rewrite: true: 호스트 헤더를 자동으로 백엔드에 맞게 재작성.
      • cluster: httpbin_service: 요청을 httpbin_service 클러스터로 라우팅.
      • timeout: 1s: 요청 타임아웃을 1초로 설정.

이 변경은 Envoy가 httpbin 서비스로 보내는 요청이 1초 내에 응답하지 않으면 타임아웃되도록 만듭니다. 이를 통해 서비스 응답 시간을 제어하고, 느린 응답으로 인한 자원 낭비를 방지할 수 있습니다.

timeout: 1s를 추가해 요청 타임아웃을 1초로 설정하면, Envoy는 더 빠르게 요청을 관리합니다.

🛑 기존 프록시 종료하고 재실행하기

새로운 설정 파일을 적용하려면 기존 Envoy 프록시를 종료하고 새 설정으로 재실행해야 합니다. 다음 명령어로 이 과정을 수행합니다:

  1. 기존 프록시 종료:
    • 명령어: docker rm -f proxy
      (⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master/ch3$ docker rm -f proxy
      proxy
    • 설명: 실행 중인 proxy 컨테이너를 강제로 삭제(-f)합니다. 이 명령은 컨테이너를 즉시 종료하고 제거하며, 출력으로 컨테이너 이름(proxy)이 반환됩니다.
  2. 새 설정으로 프록시 재실행:
    • 명령어: docker run --name proxy --link httpbin envoyproxy/envoy:v1.19.0 --config-yaml "$(cat ch3/simple_change_timeout.yaml)"
      (⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master/ch3$ docker run --name proxy --link httpbin envoyproxy/envoy:v1.19.0 --config-yaml "$(cat simple_change_timeout.yaml)"
      
      (⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker ps
      CONTAINER ID   IMAGE                      COMMAND                  CREATED          STATUS          PORTS                                                             NAMES
      b24a1c64c533   envoyproxy/envoy:v1.19.0   "/docker-entrypoint.…"   23 seconds ago   Up 22 seconds   10000/tcp                                                         proxy
    • 설명:
      • docker run: 새 컨테이너를 실행.
      • --name proxy: 컨테이너 이름을 proxy로 지정.
      • --link httpbin: httpbin 컨테이너와 연결해 이름(httpbin)으로 통신.
      • envoyproxy/envoy:v1.19.0: Envoy 이미지.
      • --config-yaml "$(cat ch3/simple_change_timeout.yaml)": simple_change_timeout.yaml 파일을 YAML 형식으로 Envoy에 전달.

이 명령은 Envoy를 새로운 타임아웃 설정(1초)으로 실행하며, httpbin 서비스로 트래픽을 프록시할 준비를 완료합니다.

기존 프록시를 종료하고 새로운 설정 파일로 재실행하면 Envoy가 업데이트된 타임아웃 설정을 적용합니다.

🎯 핵심 포인트

Envoy 설정 파일을 수정해 요청 타임아웃을 1초로 변경하고, 새로운 설정으로 프록시를 재실행 simple_change_timeout.yaml 파일에 timeout: 1s를 추가해 요청 처리 시간을 제어했으며, 기존 프록시를 종료한 뒤 새 설정으로 Envoy를 실행
주요 단계: 타임아웃 설정 변경 → 기존 프록시 종료 → 새 설정으로 재실행

🚀 Envoy 프록시 타임아웃 변경 테스트하기


🌐 curl로 업데이트된 Envoy 프록시 호출하기

이전 실습에서 simple_change_timeout.yaml 설정 파일로 Envoy의 요청 타임아웃을 1초로 변경했습니다. 이제 curl을 사용해 프록시를 호출하고 변경된 설정이 적용되었는지 확인합니다:

  • 명령어: docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15001/headers

이 명령어는 다음과 같은 일을 합니다:

  • docker run -it: 인터랙티브 모드로 curl 컨테이너를 실행.
  • --rm: 컨테이너 실행 후 자동 삭제.
  • --link proxy: curl 컨테이너를 Envoy 프록시 컨테이너와 연결해 proxy 이름으로 접근.
  • curl -X GET http://proxy:15001/headers: Envoy 프록시의 15001번 포트로 GET 요청을 보내 /headers 엔드포인트를 호출.

이 요청은 Envoy를 통해 httpbin 서비스로 전달되며, httpbin은 요청에 포함된 헤더 정보를 JSON으로 반환합니다.

curl로 Envoy 프록시를 호출해 변경된 타임아웃 설정이 반영되었는지 확인할 수 있습니다.

📋 응답 확인과 타임아웃 헤더 변화

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15001/headers
{
  "headers": {
    "Accept": [
      "*/*"
    ],
    "Host": [
      "httpbin"
    ],
    "User-Agent": [
      "curl/8.13.0"
    ],
    "X-Envoy-Expected-Rq-Timeout-Ms": [
      "1000"
    ],
    "X-Forwarded-Proto": [
      "http"
    ],
    "X-Request-Id": [
      "019d3041-2f21-49d4-86ff-3a0767ee320f"
    ]
  }
}

 

명령어 실행 후, httpbin은 다음과 같은 JSON 응답을 반환합니다:

  • "Accept": "*/*": 모든 콘텐츠 타입 수락.
  • "Host": "httpbin": 요청 대상 호스트.
  • "User-Agent": "curl/8.13.0": curl 클라이언트 정보.
  • "X-Envoy-Expected-Rq-Timeout-Ms": "1000": 요청 타임아웃이 1000ms(1초)로 설정됨.
  • "X-Forwarded-Proto": "http": 요청 프로토콜(http).
  • "X-Request-Id": 요청 고유 ID.

가장 주목할 점은 "X-Envoy-Expected-Rq-Timeout-Ms": "1000"입니다. 이전에는 15,000ms(15초)였던 타임아웃이 새로운 설정(timeout: 1s)에 따라 1,000ms(1초)로 변경되었습니다. 이는 Envoy가 업데이트된 설정 파일을 성공적으로 적용했음을 보여줍니다. 또한, X-Forwarded-Proto와 X-Request-Id 같은 헤더는 Envoy가 요청을 처리하며 추가한 정보로, 프로토콜과 요청 추적을 돕습니다.

응답에서 X-Envoy-Expected-Rq-Timeout-Ms가 1000ms로 변경된 것을 확인하며, Envoy의 설정 변경이 성공적으로 적용되었음을 알 수 있습니다.

🎯 핵심 포인트

Envoy 프록시의 타임아웃 설정 변경을 테스트
curl로 프록시를 호출해 httpbin 서비스의 응답을 확인했으며, X-Envoy-Expected-Rq-Timeout-Ms 헤더가 1,000ms로 업데이트된 것을 통해 새로운 타임아웃 설정(1초)이 적용되었음을 확인
주요 단계: curl로 프록시 호출 → 응답에서 타임아웃 헤더 확인 → 설정 변경 효과 검증

🔍 Envoy Admin API로 프록시 상태 탐색하기


🌐 Envoy Admin API로 프록시 메트릭 확인하기

Envoy의 Admin API는 프록시의 동작 상태를 모니터링하고, 메트릭 및 설정 정보를 제공하는 강력한 도구입니다. 기본적으로 15000번 포트에서 동작하며, 다양한 엔드포인트를 통해 프록시의 내부 정보를 조회할 수 있습니다. 먼저 /stats 엔드포인트를 호출해 프록시의 메트릭을 확인해봅니다:

  • 명령어: docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/stats
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/stats

 

이 명령어는 다음과 같은 일을 합니다:

  • docker run -it: 인터랙티브 모드로 curl 컨테이너를 실행.
  • --rm: 컨테이너 실행 후 자동 삭제.
  • --link proxy: curl 컨테이너를 Envoy 프록시와 연결해 proxy 이름으로 접근.
  • curl -X GET http://proxy:15000/stats: Envoy의 Admin API /stats 엔드포인트로 GET 요청을 보내 메트릭 데이터를 조회.

응답은 리스너, 클러스터, 서버에 대한 방대한 통계 데이터를 포함합니다. 이 데이터는 프록시의 성능과 상태를 분석하는 데 유용합니다.

Admin API의 /stats 엔드포인트를 호출하면 Envoy의 리스너, 클러스터, 서버 메트릭을 확인할 수 있습니다.

🛠 메트릭 필터링으로 원하는 데이터 추출하기

/stats 엔드포인트는 많은 데이터를 반환하므로, 원하는 정보만 추출하려면 필터링이 필요합니다. 예를 들어, retry라는 단어가 포함된 메트릭만 확인해보겠습니다:

  • 명령어: docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/stats | grep retry
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/stats | grep retry
cluster.httpbin_service.circuit_breakers.default.rq_retry_open: 0
cluster.httpbin_service.circuit_breakers.high.rq_retry_open: 0
cluster.httpbin_service.retry_or_shadow_abandoned: 0
cluster.httpbin_service.upstream_rq_retry: 0
cluster.httpbin_service.upstream_rq_retry_backoff_exponential: 0
cluster.httpbin_service.upstream_rq_retry_backoff_ratelimited: 0
cluster.httpbin_service.upstream_rq_retry_limit_exceeded: 0
cluster.httpbin_service.upstream_rq_retry_overflow: 0
cluster.httpbin_service.upstream_rq_retry_success: 0
vhost.httpbin_local_service.vcluster.other.upstream_rq_retry: 0
vhost.httpbin_local_service.vcluster.other.upstream_rq_retry_limit_exceeded: 0
vhost.httpbin_local_service.vcluster.other.upstream_rq_retry_overflow: 0
vhost.httpbin_local_service.vcluster.other.upstream_rq_retry_success: 0

 

이 명령은 /stats 엔드포인트의 응답을 받아 grep retry로 필터링해 retry 관련 메트릭만 출력합니다. 결과는 다음과 같습니다:

  • cluster.httpbin_service.retry_or_shadow_abandoned: 0
  • cluster.httpbin_service.upstream_rq_retry: 0
  • cluster.httpbin_service.upstream_rq_retry_overflow: 0
  • cluster.httpbin_service.upstream_rq_retry_success: 0

이 메트릭들은 httpbin 클러스터의 재시도(retry) 관련 상태를 보여주며, 현재는 재시도가 발생하지 않았음을 나타냅니다.

grep을 사용해 /stats 응답에서 원하는 메트릭(예: retry)을 필터링하면 필요한 정보만 쉽게 확인할 수 있습니다.

📋 Admin API의 주요 엔드포인트 탐색하기

Admin API는 /stats 외에도 다양한 엔드포인트를 제공합니다. 루트 경로(http://proxy:15000/)를 호출하면 사용 가능한 엔드포인트 목록을 확인할 수 있습니다. 주요 엔드포인트는 다음과 같습니다:

  • /certs: 프록시가 사용하는 인증서 정보.
  • /clusters: 설정된 클러스터 정보.
  • /config_dump: Envoy의 전체 설정을 덤프.
  • /listeners: 설정된 리스너 정보.
  • /logging: 로깅 설정 조회 및 변경.
  • /stats: 프록시 통계 데이터.
  • /stats/prometheus: Prometheus 포맷으로 통계 데이터 제공.

이 엔드포인트들은 프록시의 설정, 상태, 성능을 세밀히 관리하고 모니터링할 수 있도록 돕습니다.

Admin API는 다양한 엔드포인트를 통해 Envoy의 설정, 인증서, 클러스터, 로깅 등을 관리할 수 있는 강력한 인터페이스입니다.

🎯 핵심 포인트

Envoy의 Admin API를 사용해 프록시의 상태와 메트릭을 탐색
/stats 엔드포인트로 메트릭을 조회하고, grep으로 retry 관련 데이터를 필터링
주요 단계: /stats로 메트릭 조회 → retry 메트릭 필터링 → 주요 엔드포인트 탐색

🔄 Envoy 재시도 정책으로 요청 복구 테스트하기


🛠 재시도 정책으로 Envoy 설정 업데이트하기

먼저, Envoy 설정 파일에 retry_policy를 추가해 요청 실패 시 재시도를 활성화합니다. 업데이트된 설정은 simple_retry.yaml 파일에 준비되어 있습니다. 변경된 부분은 route 섹션에 추가된 재시도 정책입니다:

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master/ch3$ cat simple_retry.yaml
...
              routes:
              - match: { prefix: "/" }
                route:
                  auto_host_rewrite: true
                  cluster: httpbin_service
                  retry_policy:
                      retry_on: 5xx
                      num_retries: 3
...
  • 설정 내용:
    • match: { prefix: "/" }: 모든 경로(/)에 대한 요청을 매칭.
    • route:
      • auto_host_rewrite: true: 호스트 헤더를 백엔드에 맞게 재작성.
      • cluster: httpbin_service: 요청을 httpbin_service 클러스터로 라우팅.
      • retry_policy:
        • retry_on: 5xx: HTTP 5xx 에러(서버 에러) 발생 시 재시도.
        • num_retries: 3: 최대 3번 재시도.

이 설정은 httpbin 서비스가 5xx 에러(예: 500 Internal Server Error)를 반환할 때 Envoy가 최대 3번 요청을 재시도하도록 만듭니다. 이는 서비스 장애 상황에서도 신뢰성을 높이는 데 유용합니다.

retry_policy를 추가해 5xx 에러 발생 시 최대 3번 재시도하도록 Envoy를 설정합니다.

🔄 기존 프록시 종료 후 새 설정으로 재실행하기

새로운 retry_policy를 적용하려면 기존 Envoy 프록시를 종료하고 simple_retry.yaml 설정으로 재실행합니다. 다음 명령어로 이 과정을 수행합니다:

  1. 기존 프록시 종료:
    • 명령어: docker rm -f proxy
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master/ch3$ docker rm -f proxy
proxy
  • 설명: 실행 중인 proxy 컨테이너를 강제로 삭제(-f). 출력으로 컨테이너 이름(proxy)이 반환됩니다.
  1. 새 설정으로 프록시 재실행:
    • 명령어: docker run --name proxy --link httpbin envoyproxy/envoy:v1.19.0 --config-yaml "$(cat ch3/simple_retry.yaml)"
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master/ch3$ docker run -p 15000:15000 --name proxy --link httpbin envoyproxy/envoy:v1.19.0 --config-yaml "$(cat simple_retry.yaml)"
  • 설명:
    • docker run: 새 컨테이너 실행.
    • --name proxy: 컨테이너 이름을 proxy로 지정.
    • --link httpbin: httpbin 컨테이너와 연결해 httpbin 이름으로 통신.
    • envoyproxy/envoy:v1.19.0: Envoy 이미지.
    • --config-yaml "$(cat ch3/simple_retry.yaml)": simple_retry.yaml 파일을 YAML 형식으로 Envoy에 전달.

이 명령은 Envoy를 재시도 정책이 포함된 새 설정으로 실행하며, httpbin 서비스로 트래픽을 프록시할 준비를 완료합니다.

기존 프록시를 종료하고 simple_retry.yaml로 재실행해 재시도 정책을 적용합니다.

⚡ 에러 유발 및 재시도 동작 확인하기

이제 httpbin의 /status/500 엔드포인트를 호출해 의도적으로 500 에러를 유발하고, Envoy의 재시도 동작을 확인합니다:

  • 명령어: docker run -it --rm --link proxy curlimages/curl curl -v http://proxy:15001/status/500
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15001/status/500
  • 설명:
    • curl -v http://proxy:15001/status/500: Envoy 프록시를 통해 httpbin의 /status/500 엔드포인트로 요청을 보냄. 이 엔드포인트는 항상 500 에러를 반환.
    • 요청은 Envoy를 거쳐 httpbin으로 전달되며, httpbin이 500 에러를 반환.

실행 결과, 응답이 없으며 요청이 실패한 것처럼 보입니다. 이는 httpbin이 500 에러를 반환했고, Envoy가 재시도를 시도했지만 성공하지 못했기 때문입니다.

/status/500 엔드포인트를 호출해 500 에러를 유발하면 Envoy가 재시도하지만, 지속적인 에러로 응답이 실패합니다.

📊 Admin API로 재시도 통계 확인하기

Envoy가 재시도를 수행했는지 확인하기 위해 Admin API의 /stats 엔드포인트를 호출하고 retry 관련 메트릭을 필터링합니다:

  • 명령어: docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/stats | grep retry
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~$ docker run -it --rm --link proxy curlimages/curl curl -X GET http://proxy:15000/stats | grep retry
cluster.httpbin_service.circuit_breakers.default.rq_retry_open: 0
cluster.httpbin_service.circuit_breakers.high.rq_retry_open: 0
cluster.httpbin_service.retry.upstream_rq_500: 3
cluster.httpbin_service.retry.upstream_rq_5xx: 3
cluster.httpbin_service.retry.upstream_rq_completed: 3
cluster.httpbin_service.retry_or_shadow_abandoned: 0
cluster.httpbin_service.upstream_rq_retry: 3
cluster.httpbin_service.upstream_rq_retry_backoff_exponential: 3
cluster.httpbin_service.upstream_rq_retry_backoff_ratelimited: 0
cluster.httpbin_service.upstream_rq_retry_limit_exceeded: 1
cluster.httpbin_service.upstream_rq_retry_overflow: 0
cluster.httpbin_service.upstream_rq_retry_success: 0
vhost.httpbin_local_service.vcluster.other.upstream_rq_retry: 0
vhost.httpbin_local_service.vcluster.other.upstream_rq_retry_limit_exceeded: 0
vhost.httpbin_local_service.vcluster.other.upstream_rq_retry_overflow: 0
vhost.httpbin_local_service.vcluster.other.upstream_rq_retry_success: 0
  • 결과:
    • cluster.httpbin_service.retry.upstream_rq_500: 3
    • cluster.httpbin_service.retry.upstream_rq_5xx: 3
    • cluster.httpbin_service.retry_or_shadow_abandoned: 0
    • cluster.httpbin_service.upstream_rq_retry: 3
    • cluster.httpbin_service.upstream_rq_retry_overflow: 0
    • cluster.httpbin_service.upstream_rq_retry_success: 0

이 메트릭은 다음과 같은 정보를 보여줍니다:

  • upstream_rq_500: 3, upstream_rq_5xx: 3: httpbin이 500 에러를 3번 반환.
  • upstream_rq_retry: 3: Envoy가 요청을 3번 재시도.
  • upstream_rq_retry_success: 0: 재시도가 성공하지 않음(모두 500 에러 반환).

이는 Envoy가 설정된 retry_policy(최대 3번 재시도)에 따라 500 에러 발생 시 요청을 자동으로 3번 재시도했지만, httpbin이 계속 에러를 반환해 성공하지 못했음을 나타냅니다.

Admin API의 retry 메트릭을 통해 Envoy가 500 에러에 대해 3번 재시도했음을 확인할 수 있습니다.

🎯 핵심 포인트

Envoy의 재시도 정책을 설정하고 테스트
simple_retry.yaml에 retry_policy를 추가해 5xx 에러 발생 시 최대 3번 재시도하도록 설정했으며, httpbin의 /status/500 엔드포인트로 에러를 유발해 재시도 동작을 확인
Admin API를 통해 재시도 통계를 조회하며 Envoy가 3번 재시도했지만 성공하지 못했음
주요 단계: 재시도 정책 설정 → 프록시 재실행 → 에러 유발 → Admin API로 재시도 확인
Comments