네트워크는 애플리케이션에 투명해야하며 장애가 발생했을 시 어디에서 문제가 발생했는지 쉽게 파악할 수 있어야한다.
MSA 서비스들이 늘어나면서 서비스들이 네트워크를 통해 서로 통신해야했고 이러한 서비스에서 사용하는 핵심 네트워크 프로토콜은 HTTP, HTTP/2, gRPC, Kafka, MongoDB 등의 L7 프로토콜이다.
L3, L4 기반의 프록시들로는 다양한 요건들을 처리하기 어려워졌고 그에 따라 L7 기능을 갖춘 프록시의 필요성이 부각되기 시작했다.
Envoy Proxy 는 Serivice Mesh Architecture로 대표되는 Istio의 메인 프록시로 대형 MSA 의 단일 Application과 Service를 위해 설계된 고성능 분산 C++ 프록시이다. Lift 사에서 제작한 프로젝트로 (참고: https://www.cncf.io/projects/)
모듈화가 잘 되어있으면 테스트하기 쉽고, 플랫폼에 구애받지 않는 방식으로 기능을 제공하여 네트워크를 추상화한다.
L7단이기 때문에 L4 보다는 성능 감소가 다소 존재하지만 가능한 최고 성능을 목표로한다.
기존 프록시 l4 기능뿐 아니라 l7기능도 지원하면서 http뿐 아니라 http 2.0, tcp,. grpc 까지 다양한 프로토콜을 지원한다.
Envoy Proxy 배포 아키텍쳐
envoy 프록시는 배포 위치에 따라서 다양한 기능을 수행할 수 있는데, 크게 다음과 같이 4가지 구조에 배포 가능하다.
- Front envoy proxy
- 특정 서비스가 아니라 전체 시스템 앞의 위치하는 프록시로 클라이언트에서 들어오는 호출을 받아서 각각의 서비스로 라우팅한다.
- url 기반으로 라우팅하는 기능 이외에도 TLS(SSL)처리를 하는 역할들을 할 수 있다.
- 통상적으로 Nginx나 Apache httpd 가 리버스 프록시로 이 용도로 많이 사용되었다.
- Service to service ingress listener
- 특정 서비스 앞에 위치하는 배포 방식으로 서비스로 들어오는 트래픽에 대한 처리를 하는데 트래픽에 대한 버퍼링이나 circuit breaker 와 같은 역할을 수행한다.
- Service to serivec degress listener
- 특정 서비스 뒤에서 서비스로부터 나가는 트래픽을 통제하는데 서비스로부터 호출 대상이 되는 서비스에 대한 로드 밸런싱, 호출 횟 수 통제(Rate limiting)와 같은 기능을 수행한다.
- External servie egress listener
- 내부 서비스에서 외부 서비스로 나가는 트래픽을 관리하는 역할인데, 외부 서비스에 대한 일종의 대행자(Delegator)와 같은 역할을 한다.
시스템 앞 부붙이나 또는 시스템을 구성하는 서비스의 앞뒤에 배치할 수 있는 구조지만 서비스 앞뒤로 붙는다고 실제로 배포를 할 때 하나의 서비스 앞뒤로 두 개의 envoy proxy를 배치하지는 않는다.
다음과 같이 하나의 서비스에 하나의 envoy를 배치한 후 ingress/egress 두가지 용도로 겸용하여 사용한다.
Envoy Proxy 설정 구조
다음은 Envoy 설정 파일을 살펴 보자.
Envoy 의 설정은 크게 아래 그림과 같이 크게 Listener, Filter, Cluster 세가지 파트로 구성된다.
- Listener
- Listener는 클라이언트로부터 프로토콜을 받는 부분으로 TCP Listener, HTTP Listener 등이 있다.
- Filter
- Filter는 Listener로 부터 많은 메시지를 중간 처리하는 부분으로 압축이나 들어오는 Traffic에 대한 제한 작업등을 한 후, Router 를 통해서 적절한 클러스터로 메세지를 라우팅하는 역할을 한다.
- Cluster
- Cluster는 실제로 라우팅이 될 대상 서버(서비스)를 지정한다.
이렇게 Listener를 통해서 메세지를 받고 Filter를 이용하여 받은 메세지를 처리한 후, 라우팅 규칙에 따라서 적절한 Cluster로 라우팅하여 적절한 서비스로 메세지를 보내는 형식이다.
Advanced Load Balancing
자동 재시도, circuit break, 외부 속도 제한 서비스를 통한 글로벌 속도 제한, 이상치 탐지 등의 기능을 제공한다.
- circuit break:
- 전기의 회로차단기에서 차용한 개념으로 평소에는 정상적으로 동작하다가 오류가 발생하면 더이상 동작하지 않게 한다. 이렇게 문제가 되는 기능 자체를 동작하지 않게 하여 리소스 무한 점유를 막을 수 있다.
- health check 지원
- front / edge proxy 지원
- 관리용으로 다양한 통계 정보 제공
- MongoDB, DynamoDB L7을 지원
Envoy Proxy 설치
Envoy proxy를 빌드하고 설치하는 방법은 여러가지가 있다. 소스코드로부터 빌드하는 방법이나 이미 빌드된 바이너리를 사용해서 설치하는 방법, 이미 빌딩된 도커 이미지를 사용하는 방법이 있다.
- docker로 빌드
$ docker pull envoyproxy/envoy-dev:latest
$ docker run --rm -d -p 10000:10000 envoyproxy/envoy:latest
$ curl -v localhost:10000
Envoy Proxy 설정
- 용어 정리
- Downstream: Envoy에게 request를 보내고 response를 받는 host
- Upstream: Envoy로부터 request를 받고 response를 보내주는 host
- Listener: Downstream 호스트의 요청을 받는 부분
- Cluster: upstream 호스트의 그룹
디폴트 설정은 10000번 포트로 들어오는 모든 트래픽을 *.google.com으로 라우팅하도록 설정되어있다.
원본 설정 파일: https://github.com/envoyproxy/envoy/blob/main/configs/google_com_auto_http3_upstream_proxy.yaml
- admin
- envoyproxy의 admin 서버를 기동하는 부분
- 127.0.0.1:9901로 들어오는 요청은 admin 기능으로 라우팅하도록 설정
admin:
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 9901
- static_resources:
- Listener와 Filter 설정에 해당하는 부분으로 Listeners로 정의가 되어있고 socket_address 부분에 0.0.0.0에 포트 10000 으로 들어오는 요청을 처리하도록 설정
- 다음 filter_chain 부분에 filter 들을 연속해서 정의하는데 http_connection_manager를 이용하여 모든 트래픽을 service_google이라는 클러스터로 라우팅하도록 설정하였다.
static_resources:
listeners:
- name: listener_0
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 10000
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
scheme_header_transformation:
scheme_to_overwrite: https
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
host_rewrite_literal: www.google.com
cluster: service_google
http_filters:
- name: alternate_protocols_cache
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.alternate_protocols_cache.v3.FilterConfig
alternate_protocols_cache_options:
name: default_alternate_protocols_cache
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
- clusters:
- service_google 이라는 클러스터를 정의했으며 이 호스트의 URL은 google.com 443 포트로 설정
clusters:
- name: service_google
connect_timeout: 30s
type: LOGICAL_DNS
# Comment out the following line to test on v6 networks
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_google
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: www.google.com
port_value: 443
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
auto_config:
http3_protocol_options: {}
alternate_protocols_cache_options:
name: default_alternate_protocols_cache
common_http_protocol_options:
idle_timeout: 1s
transport_socket:
name: envoy.transport_sockets.quic
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicUpstreamTransport
upstream_tls_context:
sni: www.google.com
'Network > 로드밸런서' 카테고리의 다른 글
Service Mesh Architecture & Istio (0) | 2024.02.26 |
---|