Envoy 빠 른 입문

21916 단어
마이크로 서비스의 서비스 간 통신 과 서비스 관리 에 있어 서 저 희 는 가리비 의 현재 Service Mesh 구 조 는 Envoy 를 바탕 으로 하 는 것 이 라 고 언급 했 습 니 다.
본문의 주인공 은 바로 이 신예 Envoy 입 니 다.
Nginx 를 버 리 고 Envoy 를 선 택 했 습 니 다.
사실 이전에 가리비 는 Nginx 를 대량으로 사 용 했 기 때문에 배치 든 배치 든 조정 이 든 모두 경험 이 있 었 다.가능 하 다 면, 우 리 는 서비스 Mesh 의 핵심 방안 으로 Nginx 를 선택 하 는 경향 이 있다.
그러나 몇 가지 얽 히 지 않 는 문제 에 부 딪 혔 다.
  • Nginx 의 역방향 대 리 는 http 2 / grpc 를 지원 하지 않 습 니 다 (올해 3 월 에 지원 한 것 같 습 니 다)
  • Envoy 와 달리 거의 모든 네트워크 설정 은 xdS API 를 이용 하여 동적 변경 을 실현 할 수 있 고 Nginx 는 효과 적 인 설정 열 변경 체제 가 부족 합 니 다 (깊이 개발 하거나 끊임없이 reload 를 하지 않 는 한).
  • Nginx 의 많은 마이크로 서비스 기능 은 Nginx Plus 를 사 야 한다
  • Envoy 는 Service Mesh 방안 을 위주 로 하 는 proxy 로 서 그 디자인 은 곳곳에서 Service Mesh 를 고려 하고 일정한 이 해 를 거 친 후에 우 리 는 과감하게 Envoy 의 구덩이 에 들 어 갔다.
    엔 보이 가 뭐야.
    우 리 는 홈 페이지 의 설명 을 인용 했다.
    Envoy is an L7 proxy and communication bus designed for large modern service oriented architectures. The project was born out of the belief that: "The network should be transparent to applications. When network and application problems do occur it should be easy to determine the source of the problem."
    Envoy 의 핵심 기능 / 판매 점
  • 비 침입 구조: Envoy 응용 서비스 와 병행 하여 운영 되 고 투명 하 게 응용 서비스 가 보 내 거나 받 는 데이터 입 니 다.응용 서 비 스 는 Envoy 와 만 통신 해 야 하 며 다른 마이크로 서비스 가 어디 에 응용 되 는 지 알 필요 가 없다.
  • Modern C + + 11 을 바탕 으로 성능 이 우수 합 니 다.
  • L3 / L4 필터 구조: Envoy 의 핵심 은 L3 / L4 에이전트 이 고 플러그 인 필터 network filters 체인 을 통 해 TCP / UDP 와 관련 된 작업 을 수행 합 니 다. 예 를 들 어 TCP 전송, TLS 인증 등 입 니 다.
  • HTTP L7 필터 구조: HTTP 는 현대 응용 시스템 에서 매우 특수 한 응용 층 프로 토 콜 이기 때문에 Envoy 매우 핵심 적 인 필 터 를 내장 했다. http_connection_managerhttp_connection_manager 자체 가 이렇게 특수 하고 복잡 하 며 풍부 한 설정 을 지원 하 며 그 자체 도 필터 구조 입 니 다. 일련의 http 필터 http filters 를 통 해 http 프로 토 콜 차원 의 임 무 를 실현 할 수 있 습 니 다. 예 를 들 어 http 경로, 재 설정, CORS 지원 등 입 니 다.
  • HTTP / 2 는 첫 번 째 시민 으로서 Envoy HTTP / 1.1 과 HTTP / 2 를 지원 하고 HTTP / 2 를 추천 합 니 다.
  • gRPC 지원: HTTP / 2 에 대한 좋 은 지원 으로 Envoy gRPC 를 편리 하 게 지원 할 수 있 습 니 다. 특히 부하 와 대리 에 있 습 니 다.
  • 서비스 발견: DNS, EDS 를 포함 한 다양한 서비스 발견 방안 을 지원 합 니 다.
  • 건강 검진: 건강 검진 서브 시스템 내장.
  • 고급 부하 균형 방안: 일반적인 부하 균형 을 제외 하고 Envoy 는 rate limit 서 비 스 를 바탕 으로 하 는 다양한 고급 부하 균형 방안 도 지원 한다. 이 는 automatic retries, circuit breaking, global rate limiting
  • 을 포함한다.
  • 추적: 오픈 추적 시스템 통합 이 편리 하고 추적 요청
  • 통계 와 모니터링: stats 모듈 을 내장 하여 prometheus / statsd 등 모니터링 방안
  • 을 쉽게 통합 할 수 있 습 니 다.
  • 동적 설정: '동적 설정 API' 를 통 해 설정 의 동적 조정 을 실현 하고 서 비 스 를 다시 시작 하지 않 아 도 됩 니 다 Envoy.

  • 핵심 용어 해석
    Host
    이곳 의 Host 는 IP, Port 의 유일한 서비스 인 스 턴 스 를 이해 할 수 있 습 니 다.
    Downstream
    Envoy 에 요청 한 Host 는 Downstream (하류) 입 니 다. 예 를 들 어 gRPC 의 client 입 니 다.
    Upstream
    Enovy 가 보 낸 요청 을 받 은 Host 는 Upstream (상위) 입 니 다. 예 를 들 어 gRPC 의 server 입 니 다.
    Listener
    Envoy 가 감청 한 주소, 예 를 들 어 ip: port, 유 닉 스 socket 등
    Cluster
    기능 이 일치 하 는 상류 Host 를 cluster 라 고 합 니 다.유사 k8sService, nginxupstreamHttp Route Table
    HTTP 의 경로 규칙, 예 를 들 어 요청 한 도 메 인 이름, Path 가 어떤 규칙 에 부합 되 는 지, 어떤 Cluster 에 전달 하 는 지 등 입 니 다.
    설정 (v2)
    Envoy 의 설정 인 터 페 이 스 는 proto 3 (Protocol Buffers v3) 형식 으로 정의 되 며, 완전한 정 의 는 data plane API reposcory 를 참조 합 니 다.
    구체 적 인 프로필 작성 지원: yaml, json, pb, pb_text 네 가지 형식.가 독성 을 고려 하여 우 리 는 모두 yaml 형식 을 예 로 들 자.
    먼저 간단 한 예 를 보 자.
    완전 정적 설정
    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: 127.0.0.1, 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: ["example.com"]
                  routes:
                  - match: { prefix: "/" }
                    route: { cluster: some_service }
              http_filters:
              - name: envoy.router
      clusters:
      - name: some_service
        connect_timeout: 0.25s
        type: STATIC
        lb_policy: ROUND_ROBIN
        hosts: [{ socket_address: { address: 127.0.0.2, port_value: 1234 }}]
    

    위의 예 에서, 우 리 는 127.0.0.1: 10000 을 감청 하고 http 프로 토 콜 접근 을 지원 하 는 envoy 실례 를 설 정 했 습 니 다. http 접근 도 메 인 이름 은: example. com 입 니 다.받 은 모든 http 트 래 픽 은 127.0.0.2: 1234 의 서비스 에 전 달 됩 니 다.
    곧 여러분 이 발견 한 문 제 는 바로 some 입 니 다.서비스 라 는 cluster 에서 hosts 는 고정 적 127.0.0.2:1234 이지 만 대응 하 는 host 는 변 할 가능성 이 높다.예 를 들 어 새로운 host (수평 확장) 를 추 가 했 고 k8s 환경 에서 새로운 코드 (pod 가 변 했 습 니 다) 를 보 냈 습 니 다.이 럴 때 우리 가 끊임없이 필요 한 이 cluster 의 hosts 는 아니 겠 지?안심 해, 만약 그렇다면 우 리 는 사용 하지 않 을 거 야 Envoy.EDS 을 통 해 cluster hosts 를 동적 으로 설정 합 니 다.
    다음 에 우 리 는 첫 번 째 동적 설정 의 예 를 만 날 것 이다. 바로 동적 설정 cluster 의 hosts 이다.
    우 리 는 먼저 이러한 A 이 있다 고 가정 합 니 다. 주 소 는: 127.0.0.3:5678 이 고 proto 3 인 코딩 의 부하 직원 응답 을 되 돌려 줍 니 다.
    version_info: "0"
    resources:
    - "@type": type.googleapis.com/envoy.api.v2.ClusterLoadAssignment
      cluster_name: some_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.2
                port_value: 1234
    

    그러면 우 리 는 envoy 의 설정 을 다음 과 같이 조정 합 니 다.
    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: 127.0.0.1, 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: ["example.com"]
                  routes:
                  - match: { prefix: "/" }
                    route: { cluster: some_service }
              http_filters:
              - name: envoy.router
      clusters:
      - name: some_service
        connect_timeout: 0.25s
        lb_policy: ROUND_ROBIN
        type: EDS
        eds_cluster_config:
          eds_config:
            api_config_source:
              api_type: GRPC
              cluster_names: [xds_cluster]
      - name: xds_cluster
        connect_timeout: 0.25s
        type: STATIC
        lb_policy: ROUND_ROBIN
        http2_protocol_options: {}
        hosts: [{ socket_address: { address: 127.0.0.3, port_value: 5678 }}]
    
    some_service 이 cluster 의 hosts 동적 설정 을 실현 할 수 있 습 니 다.새로운 설정 에서 some_service 이 cluster 의 hosts 는 EDS(Endpoint Discovery Service) 의 반환 값 이 결 정 됩 니 다. 즉, EDS 이 cluster 의 hosts 목록 을 되 돌려 줍 니 다.새 설정 에서 some_service 서비스의 주 소 는 EDS 이 cluster 에 정의 되 었 습 니 다. 주 소 는 바로 우리 가 처음에 가설 한 xds_cluster 주소 입 니 다.
    사실 Envoy 의 A, listener, cluster 등 은 모두 동적 으로 배치 할 수 있 습 니 다. 방법 은 http route 과 마찬가지 로 EDS, LDS, CDS 을 통 해 배치 할 수 있 습 니 다. 이 를 통칭 RDS 이 라 고 합 니 다.완전한 동적 설정 의 예 는 다음 과 같다.xDS 기반 동적 설정
    admin:
      access_log_path: /tmp/admin_access.log
      address:
        socket_address: { address: 127.0.0.1, port_value: 9901 }
    
    dynamic_resources:
      lds_config:
        api_config_source:
          api_type: GRPC
          cluster_names: [xds_cluster]
      cds_config:
        api_config_source:
          api_type: GRPC
          cluster_names: [xds_cluster]
    
    static_resources:
      clusters:
      - name: xds_cluster
        connect_timeout: 0.25s
        type: STATIC
        lb_policy: ROUND_ROBIN
        http2_protocol_options: {}
        hosts: [{ socket_address: { address: 127.0.0.3, port_value: 5678 }}]
    

    여기 서 우 리 는 127.0.0.3: 5678 이 완전한 xDS 를 제공한다 고 가정 합 니 다.xDS :
    version_info: "0"
    resources:
    - "@type": type.googleapis.com/envoy.api.v2.Listener
      name: listener_0
      address:
        socket_address:
          address: 127.0.0.1
          port_value: 10000
      filter_chains:
      - filters:
        - name: envoy.http_connection_manager
          config:
            stat_prefix: ingress_http
            codec_type: AUTO
            rds:
              route_config_name: local_route
              config_source:
                api_config_source:
                  api_type: GRPC
                  cluster_names: [xds_cluster]
            http_filters:
            - name: envoy.router
    
    LDS :
    version_info: "0"
    resources:
    - "@type": type.googleapis.com/envoy.api.v2.RouteConfiguration
      name: local_route
      virtual_hosts:
      - name: local_service
        domains: ["*"]
        routes:
        - match: { prefix: "/" }
          route: { cluster: some_service }
    
    RDS :
    version_info: "0"
    resources:
    - "@type": type.googleapis.com/envoy.api.v2.Cluster
      name: some_service
      connect_timeout: 0.25s
      lb_policy: ROUND_ROBIN
      type: EDS
      eds_cluster_config:
        eds_config:
          api_config_source:
            api_type: GRPC
            cluster_names: [xds_cluster]
    
    CDS :
    version_info: "0"
    resources:
    - "@type": type.googleapis.com/envoy.api.v2.ClusterLoadAssignment
      cluster_name: some_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.2
                port_value: 1234
    

    종결 어EDS 의 빠 른 입문 문 으로서 우 리 는 Envoy 의 핵심 기능, 용어, 그리고 설정 을 대충 알 게 되 었 다.더 깊이 있 는 맞 춤 형 설정 에 대해 서 는 Envoy 의 공식 문 서 를 더 읽 을 수 있 습 니 다.
    가리비 에서 엔 보 이 는 Envoy 의 핵심 구성 요소 로 마이크로 서비스 간 의 모든 직접 호출 트 래 픽 을 탑재 했다.
    우리 의 서로 다른 마이크로 서 비 스 는 하나의 Cluster 에 대응 하고 Service Mesh 를 통 해 Route Table 을 설정 합 니 다.
    Envoy 의 stats 데 이 터 를 이용 하여 서비스 호출 성능 모니터링 을 하고 Envoy 의 access log 는 데이터 로그 수집 을 하고 rate limit 는 서비스 보 호 를 합 니 다.

    좋은 웹페이지 즐겨찾기