Dev/DevOps, Infra

[Service Mesh] Service Mesh와 Envoy 찍먹해보기..(도 전일 수도 있음)

HJChung 2022. 6. 12. 00:49
대표적으로
https://www.envoyproxy.io/
https://hackernoon.com/service-mesh-with-envoy-101-e6b2131ee30b 
https://www.suse.com/c/rancher_blog/stupid-simple-service-mesh-what-when-why/
을 통해 envoy와 service mesh를 알아본 후 정리하여 작성한 글입니다. 

Goal

  • 사이트 안정성
  • 장애 발생에 대한 대응/분석/부검 용이
  • Remove cloud dependency (Ex. Cloudwatch, AWS auto-scaling service)
  • Solves monitoring and logging problems efficiently and effectively
  • and use monitoring result as efficient and effective scaling policy. → Useful for scalability architectural design.

따라서

  • 서비스간 통신이 복잡해지는 것을 잘 관리하는게 중요하고, 
  • 장애 추적 및 모니터링이 용이하도록 서비스에 대해 전역적으로 쿼리할 수 있는 메트릭과 모니터링 시스템이 필요하다.
  • AWS가 해줬던 Health check, Load Balancing, Auto Scaling, Metric&Monitoring 등 안정성, 확장성, 모니터링 등의 기능을 이젠 우리가 설정,구현을 ‘잘' 해줘야한다. 

이를 위해 Service Mesh가 해주는 역할에 대해서 궁금해져서 Service Mesh와 Envoy에 대해 공부를 시작하였다. 

Technical Background

각 서비스에 대해 전역적으로 쿼리할 수 있는 메트릭과 모니터링 시스템의 필요성을 해결하기 위한 전통적인 방법은 API Gateway이다.

앞단에서 API Gateway가 client로 들어오는 모든 요청들을 API Gateway가 해결하고 중앙집중형으로 해결해보고자 했다.

하지만 API Gateway의 역할이 너무 무거워진다는 단점이 있다. API Gateway를 위한 팀이 따로 생겨나고, business logic이 엮이는 부분이다보니 인프라의 복잡도도 증가하고, API Gateway에 장애가 나면 전체 서비스에 장애가 생기기도 한다.

문제

  • 결국 긴박한 장애상황에 분석을 하는 것은 시간이 많이 걸림.
  • 마이크로서비스팀이 사용하는 프레임워크가 다 다르고 네트워크 설정이 다 다름.
  • 어떤 서비스가 문제야? 원인구간 특정하는 시간이 오래걸림(서비스 디스커버리 타임)
  • 서비스별 모니터링 도구도 다르고 로깅 정책도 다름.
  • 결과적으로 " 원인 추정이 느려진다. "

필요

  • 서비스간 통신이 복잡해지는 것을 잘 관리하는게 중요하고, 
  • 장애 추적 및 모니터링이 용이하도록 서비스에 대해 전역적으로 쿼리할 수 있는 메트릭과 모니터링 시스템이 필요하다.
  • AWS가 해줬던 안정성, 확장성, 모니터링 등의 기능을 이젠 우리가 설정,구현을 ‘잘' 해줘야한다. 

해결 전략

  • Service Mesh 아키텍쳐로 프록시 Sidecar Pattern을 따르자.

  • Service Mesh는 위의 <필요>에 적은 것들을 Application Layer에서 처리하는 것이 아닌 Infrastructure Layer에서 처리하는 방법이다. 따라서 MSA의 각 서비스는 핵심 비즈니스 로직에만 집중할 수 있고 MSA를 도입함으로써 발생하는 어려움을 Infrastructure Layer에서 처리할 수 있도록 한다. 
  • 이러한 Service Mesh는 일반적으로 Sidecar Pattern으로 구성된다.
  • Sidecar Pattern이란 애플리케이션의 비즈니스 로직이외에 별도로 필요한 로직을 수행하는 프로세스(여기선 서비스간 통신을 먼저 프록시로 networking-related rule을 처리해주는 proxy)를 함께 배포하는 방식을 의미한다. 
  • 이 Proxy인 Sidecar의 역할을 해주도록 우리가 사용해 볼 것이 Envoy이며, 최종적으로는 우리 서비스가 가진 문제점을 해결하기 위해 Envoy가 활용된 network architecture을 다시 디자인 해보는게 필요할 것이다. 

 

Service Mesh

what Service Mesh is

wikipedia에서는 아래와 같이 설명한다. 

In software architecture, a service mesh is a dedicated infrastructure layer for facilitating service-to-service communications between services or microservices, using a proxy.

 

In a microservice-based architecture, we have multiple services and each service has a proxy. Together, these proxies are called Service Mesh.

 

즉, 앞서 설명한 것과 같이 service mesh란 MSA에서 서비스간 통신을 담당하는 infrastructure layer이고 Service Mesh 의 구현체인 Proxy를 통해 다양한 Routing Rules등 공통기능을 설정할 수 있다.

서비스 코드에 separating networking-related logic과 business logic이 막 섞여있고 복잡한 MSA에 scaling까지 고려하게 되는 로직이 계속 생겨난다면 이런 service Mesh로 architecture level에서도 이 로직을 분리해 내는게 필요할 것이다. 

그리고 AWS를 사용하기 때문에 AWS가 알아서 해주지만 그게 코드로 configuration 되어있지 않아 발생하는 human error, cloud dependency 문제도 있을 수 있다. 
그래서 이 Service Mesh를 사용하면 서비스 간 통신에 연관된 기능 뿐만 아니라, 서비스의 배포 전략에도 도움을 준다.

 

Differences between the API Gateway, and Service Mesh

Service Mesh is responsible for the flow of requests between services. API Gateway is responsible for the flow of requests between the client and the services, aggregating multiple services and creating and sending the final response to the client.



 And some of the Service Mesh solutions use Envoy (in the background like Istio).

 

What is Envoy

Envoy is an open source and service proxy, designed for cloud-native applications.

Why Envoy

Envoy Architecture

The Structure of an Envoy Proxy Configuration

Downstream / Upstream

  • Downstream: Envoy에 연결되어있는 Entity. Anything in front of Envoy is Downstream. Requests come from Downstream.
  • Upstream: Envoy가 Request를 포워딩해서 연결하는 Backend 네트워크 노드. Anything in back of Envoy is Upstream. Responses come from Upstream.
    그래서 Sidecar일 때는 해당 application app이 Upstream이 된다. 
  • 그래서 이런 형태도 가능하다.(put Envoy as a side car , and put multiple Envoy that talk to each other.)

Clusters & Endpoint

  • Group of Backend hosts, endpoints(that gives us the address and port) are called a cluster.
  • 즉, 이 말은 우리는 difference host를 하나의 group(cluster)으로 묶을 수 있고, endpoint는 그 하나의 cluster에서 load balanced 될 수 있다.는 것이다.
  • Cluster has a load balancing policy

 

Listeners

  • Listeners where we configure the downstream client’s IP and the Port number that the Envoy proxy listens to. IP/Port에 바인딩하여 무엇을 받을지, 어떻게 처리할지 요청 처리 측면에서 다운스트림을 조정하는 역할.

  • Any traffic sent to the server (service) is called ingress.
  • Any traffic sent from the server (service) is called egress.
  • The Ingress and the Egress rules should be added to the configuration of the Envoy proxy, so the sidecar will take care of these. ​​This means that any traffic to the service will first go to the Envoy sidecar. Then the Envoy proxy redirects the traffic to the real service. 
  • Network Filters are applied to Listener

 

Routes

  • Route는 ingress, egress등 오는 것들에 대해서 어디로 트래픽을 보낼지 
  • the received request will be routed to a cluster based on rules. For example, we can have path matching rules and prefix rewrite rules to select the service that should handle a request for a specific path/subdomain. Actually, the route is just another type of filter, which is mandatory. Otherwise, the proxy doesn’t know where to route our request.

 

Filters

  • Network Filters are how Envoy maps Listeners to Cluster. Each listener can also have one or more network filters. For example, HTTP filters - Cors, JWT Authentication, MongoDB/MySQL Network Filter … more filters 
  • Filter Chain: 리스너로부터 서비스에 트래픽을 전달하기까지 요청 처리 파이프라인

 

Hands-on

Overview of the sample application

detailed architecture

Installation

Install Envoy on Mac OSX

brew update

brew install envoy

Install Envoy using Docker

  1. You can run Envoy using the official Docker images.
  2. The following commands will pull and show the Envoy version of current images.
docker pull envoyproxy/envoy-dev:416c6f5a1d85ceb5ed9cc173533eb36b2e2dcac0
docker run --rm envoyproxy/envoy-dev:416c6f5a1d85ceb5ed9cc173533eb36b2e2dcac0 --version

 

Envoy Edge Proxy configuration

--- # Edge proxy
admin: # configures the admin server which can be used to view configurations, change log levels, view stats, etc…
  access_log_path: "/tmp/admin_access.log"
  address: 
    socket_address: 
      address: "127.0.0.1"
      port_value: 9901
static_resources: 
  listeners: ## 1. Define Listeners
    - 
      name: "http_listener"
      address: 
        socket_address: 
          address: "0.0.0.0"
          port_value: 80
      filter_chains: ## 2. Define Filter chains
          filters: 
            - 
              name: "envoy.http_connection_manager"
              config:
                stat_prefix: "ingress" ## 3. Define Routes 
                codec_type: "AUTO"
                generate_request_id: true
                route_config:
                # if a service wants to call another service, it doesn’t call the destination service directly, 
                # it routes the request first to the local proxy and the proxy routes it to the destination service.
                  name: "local_route"
                  virtual_hosts: 
                    - 
                      name: "http-route"
                      domains:  # which domains you should accept the requests 
                        - "*"
                      routes: # route matcher which matches against each request and sends the request to the appropriate cluster.
                        - 
                          match: 
                            prefix: "/"
                          route:
                            cluster: "service_a"
                http_filters:
                  - 
                    name: "envoy.router"
  clusters: ## 4. Define clusters
    - 
      name: "service_a" # upstream services to which Envoy routes traffic to.
      connect_timeout: "0.25s" # time limit to get a connection to the upstream service before returning a 503.
      type: "strict_dns"
      lb_policy: "ROUND_ROBIN" # there will be more than one instance of “Service A”, and envoy supports multiple load balancing algorithms to route traffic. 
      hosts:  # “hosts” specify the instances of Service A to which we want to route traffic to
        - 
          socket_address: 
            address: "service_a_envoy" # do not talk to “Service A” directly, we talk to an instance of Service A’s Envoy proxy.
            port_value: 8786

for each services envoy configuration, see https://github.com/dnivra26/envoy_servicemesh

If you access to localhost:8080, 

and localhost:9901 is admin page



 

Next...,

다음으로 알아 보고자 하는 것들은 Envoy로 모니터링하기, 그리고 Kubernetes를 사용한 MSA에서 Service Mesh 사용하기 이다. 

1. Envoy access log

2.  k8s - Istio - Envoy

Based on Hands on sample app, we will touch more advanced topics, like Service Mesh in Kubernetes, and we will talk about some more advanced Service Mesh implementations Istio.

프록시 사이드카 패턴이 쿠버네티스이 Pod 개념과 잘 어우러진다.

 

 

 

Reference

Ex 1. 

Ex 2.