Istio #2 - Envoy Proxy
Envoy Proxy
먼저 istio에 사용되는 envory proxy를 살펴보자. Envoy 프록시는 Lyft사에서 개발되었으면 오픈소스로 공개되었다.
기존 프록시 L4기능 뿐 아니라 L7 기능도 지원하면서 HTTP 뿐아니라 HTTP 2.0,TCP,gRPC까지 다양한 프로토콜을 지원한다.
성능 지표를 보면 아래 Twillo에서 2017년에 테스트 한 자료를 참고할만 한데, (원본 https://www.twilio.com/blog/2017/10/http2-issues.html) HAProxy 보다 약간 느린것을 확인할 수 있다. 아무래도 L4가 아닌 L7단의 로드밸런서이다 보니 다소 성능 감소는 부담해야 한다.
(참고. 위의 문서를 보면 Envoy HTTP2 의 성능이 낮게 나오는데, 이는 Envory 자체 문제라가 보다는 HTTP/2가 Connection을 reuse하는 특성에서 온다고 볼 수 있는데, 성능에 대한 이슈가 있는 만큼 HTTP/2를 사용할 경우에는 별도의 검증 등이 필요하리라 본다.)
주요 기능적인 특성을 보면 다음과 같다.
HTTP, TCP, gRPC 프로토콜을 지원
TLS client certification 지원
HTTP L7 라우팅 지원을 통한 URL 기반 라우팅, 버퍼링, 서버간 부하 분산량 조절등
HTTP2 지원
Auto retry, circuit breaker, 부하량 제한등 다양한 로드밸런싱 기능 제공
다양한 통계 추적 기능 제공 및 Zipkin 통합을 통한 MSA 서비스간의 분산 트렌젝션 성능 측정 제공함으로써 서비스에 대한 다양한 가시성 (visibility)을 제공
Dynamic configuration 지원을 통해서, 중앙 레파지토리에 설정 정보를 동적으로 읽어와서 서버 재시작없이 라우팅 설정 변경이 가능함
MongoDB 및 AWS Dynamo 에 대한 L7 라우팅 기능 제공
등 매우 다양한 기능을 제공한다.
Envoy 배포 아키텍처
Envoy 프록시는 배포 위치에 따라서 다양한 기능을 수행할 수 있는데, 크게 다음과 같이 4가지 구조에 배포가 가능하다.
<그림. Envoy 배포 방식>
Front envoy proxy
특정 서비스가 아니라, 전체 시스템 앞의 위치하는 프록시로, 클라이언트에서 들어오는 호출을 받아서 각각의 서비스로 라우팅을 한다. URL 기반으로 라우팅을 하는 기능 이외에도, TLS(SSL) 처리를 하는 역할들을 할 수 있다. 통상적으로 nginx나 apache httpd가 리버스프록시로 이 용도로 많이 사용되었다.
Service to service ingress listener
특정 서비스 앞에 위치하는 배포 방식으로 서비스로 들어오는 트래픽에 대한 처리를 하는데, 트래픽에 대한 버퍼링이나 Circuit breaker 와 같은 역할을 수행한다.
Service to service egress listener
특정 서비스 뒤에서 서비스로부터 나가는 트래픽을 통제 하는데, 서비스로 부터 호출 대상이 되는 서비스에 대한 로드 밸런싱, 호출 횟수 통제 (Rate limiting)와 같은 기능을 수행한다.
External service egress listener
내부서비스에서 외부 서비스로 나가는 트래픽을 관리하는 역할인데, 외부 서비스에 대한 일종의 대행자(Delegator)와 같은 역할을 한다.
시스템 앞 부분이나 또는 시스템을 구성하는 서비스의 앞뒤에 배치할 수 있는 구조지만, 서비스 앞뒤로 붙는다고 실제로 배포를 할때 하나의 서비스 앞뒤로 두개의 envoy proxy를 배치하지는 않는다.
다음과 같이 하나의 서비스에 하나의 Envoy를 배치 한후, ingress/egress 두 가지 용도로 겸용해서 사용한다.
Envoy 설정 구조
다음은 Envoy 설정 파일을 살펴 보자
Envoy의 설정은 크게 아래 그림과 같이 크게 Listener, Filter, Cluster 세가지 파트로 구성된다.
Listener
Listener는 클라이언트로 부터 프로토콜을 받는 부분으로, TCP Listener, HTTP Listener 등이 있다.Filter
Filter는 Listener 로 부터 많은 메시지를 중간 처리하는 부분으로, 압축이나 들어오는 Traffic 에 대한 제한 작업등을 한후, Router를 통해서 적절한 클러스터로 메시지를 라우팅 하는 역할을 한다.Cluster
Cluster는 실제로 라우팅이 될 대상 서버(서비스)를 지정한다.
이렇게 Listener를 통해서 메시지를 받고, Filter를 이용하여 받은 메시지를 처리한 후에, 라우팅 규칙에 따라서 적절한 Cluster로 라우팅을 해서 적절한 서비스로 메시지를 보내는 형식이다.
Envoy 설치
Envoyproxy를 빌드하고 설치하는 방법은 여러가지가 있다. 소스코드로 부터 빌드를 하는 방법이나 이미 빌드된 바이너리를 사용해서 설치하는 방법 그리고 이미 빌딩된 도커 이미지를 사용하는 방법이 있다.
소스코드로 빌드하는 방법의 경우에는 bazel (make와 같은 빌드 도구) 빌드를 이용해서 빌드해야 하고, 빌드된 바이너리는 특정 플랫폼에 대해서만 미리 빌드가 되어 있기 때문에, 모든 플랫폼에 사용하기가 어렵다.
마지막으로는 도커 이미지 방식이 있는데, 이 방식이 배포면에서 여러모로 편리하기 때문에 도커 이미지를 이용한 배포 방식을 설명하도록 하겠다.
다음 명령어 처럼
docker pull을 이용하여 envoyproxy 도커 이미지 최신 버전을 가지고 오고, 다음 docker run 명령을 이용하여, 해당 이미지 (envoyproxy/envoy:latest)를 기동한다. 이때 -p 10000:10000 포트를 도커의 10000번 포트를 VM의 10000포트로 포워딩하도록 설정한다.
$ docker pull envoyproxy/envoy:latest
$ docker run --rm -d -p 10000:10000 envoyproxy/envoy:latest
$ curl -v localhost:10000
배포가 끝났으면, curl을 이용하여 localhost:10000번에 호출 하는 테스트를 하도록 한다.
설정에는 디폴트로, 10000 번 포트로 들어오는 모든 트래픽을 *.google.com으로 라우팅 하도록 설정되어 있다.
원본 설정 파일은 https://github.com/envoyproxy/envoy/blob/master/configs/google_com_proxy.v2.yaml 에 있고, 상세 내용을 보면 아래와 같다.
admin:
이 부분은 envoyproxy의 admin 서버를 기동하는 부분으로, envoy 서버의 각종 설정이나 상태 정보를 127.0.0.1:9901로 들어오는 요청은 admin 기능으로 라우팅하도록 한다.static_resources:
Listener와 Filter 설정에 해당하는 부분으로, 아래 부면, listeners로 정의가 되어 있고 socket_address 부분에 0.0.0.0에 포트 10000 으로 들어오는 요청을 처리하도록 하였다.
다음 filter_chain 부분에 filter들을 연속해서 정의하는데, http_connection_manager를 이용하여 모든 트래픽을 service_google이라는 클러스터로 라우팅 하도록 설정하였다.clusters:
마지막으로 clusters 부분에는 “service_google”이라는 클러스터를 정의했으며, 이 호스트의 URL은 google.com 443 포트로 정의하였다.
admin: |
access_log_path: /tmp/admin_access.log |
address: |
socket_address: { address: 127.0.0.1, port_value: 9901 } |
static_resources: |
listeners: |
- name: listener_0 |
address: |
socket_address: { address: 0.0.0.0, port_value: 10000 } |
filter_chains: |
- filters: |
- name: envoy.http_connection_manager |
config: |
stat_prefix: ingress_http |
route_config: |
name: local_route |
virtual_hosts: |
- name: local_service |
domains: ["*"] |
routes: |
- match: { prefix: "/" } |
route: { host_rewrite: www.google.com, cluster: service_google } |
http_filters: |
- name: envoy.router |
clusters: |
- name: service_google |
connect_timeout: 0.25s |
type: LOGICAL_DNS |
# Comment out the following line to test on v6 networks |
dns_lookup_family: V4_ONLY |
lb_policy: ROUND_ROBIN |
hosts: [{ socket_address: { address: google.com, port_value: 443 }}] |
tls_context: { sni: www.google.com } |
다음글에서는 Istio에 대해서 알아보도록 하겠다.
'클라우드 컴퓨팅 & NoSQL > 도커 & 쿠버네티스' 카테고리의 다른 글
Istio #4 - Istio 설치와 BookInfo 예제 (3) | 2018.11.25 |
---|---|
Istio #3- Istio에 대한 소개 (2) | 2018.11.23 |
Istio #1 - 마이크로 서비스와 서비스 매쉬 (4) | 2018.11.20 |
쿠버네티스 #21 - 리소스(CPU/Memory) 할당과 관리 (2) | 2018.11.05 |
쿠버네티스 #20 - Security Best Practice (0) | 2018.11.03 |