ทูต. 1. บทนำ

ทักทาย! นี่เป็นบทความสั้น ๆ ที่ตอบคำถาม: “ทูตคืออะไร”, “ทำไมจึงจำเป็น” และ "จะเริ่มต้นที่ไหน?"

มันคืออะไร

Envoy คือบาลานเซอร์ L4-L7 ที่เขียนด้วยภาษา C++ โดยเน้นที่ประสิทธิภาพและความพร้อมใช้งานสูง ในอีกด้านหนึ่งนี่เป็นอะนาล็อกของ nginx และ haproxy ในทางใดทางหนึ่งซึ่งเทียบเคียงได้ในด้านประสิทธิภาพ ในทางกลับกัน จะมุ่งเน้นไปที่สถาปัตยกรรมไมโครเซอร์วิสมากกว่า และมีฟังก์ชันการทำงานที่ไม่แย่ไปกว่าบาลานเซอร์ java และ go เช่น zuul หรือ traefik

ตารางเปรียบเทียบของ haproxy/nginx/envoy ไม่ได้อ้างว่าเป็นความจริงสัมบูรณ์ แต่ให้ภาพรวมทั่วไป

Nginx
haproxy
ส่ง
Traefik

ติดดาวบน GitHub
11.2k/กระจก
1.1k/กระจก
12.4k
27.6k

เขียนใน
C
C
C + +
go

API
ไม่
ช่องเสียบเท่านั้น/ดัน
ดาต้าเพลน/ดึง
ดึง

การตรวจสุขภาพที่ใช้งานอยู่
ไม่
ใช่
ใช่
ใช่

เปิดการติดตาม
ปลั๊กอินภายนอก
ไม่
ใช่
ใช่

จว
ปลั๊กอินภายนอก
ไม่
ใช่
ไม่

นามสกุล
ลัวะ/ซี
ลัวะ/ซี
ลัวะ/C++
ไม่

ทำไม

นี่เป็นโปรเจ็กต์ใหม่ มีหลายสิ่งที่ขาดหายไป บางอย่างอยู่ในอัลฟ่าตอนต้น แต่ ส่งเนื่องจากยังเยาว์วัยจึงมีการพัฒนาอย่างรวดเร็วและมีคุณสมบัติที่น่าสนใจมากมายอยู่แล้ว: การกำหนดค่าแบบไดนามิก, ตัวกรองสำเร็จรูปจำนวนมาก, อินเทอร์เฟซที่เรียบง่ายสำหรับการเขียนตัวกรองของคุณเอง
ขอบเขตการใช้งานต่อจากนี้ แต่อย่างแรกมี 2 รูปแบบที่ต่อต้าน:

  • การหดตัวแบบคงที่

ความจริงก็คือว่าในขณะนี้ใน ส่ง ไม่มีการสนับสนุนแคช พวก Google กำลังลองทำสิ่งนี้ เพื่อแก้ไข. แนวคิดนี้จะถูกนำไปใช้ทันที ส่ง รายละเอียดปลีกย่อยทั้งหมด (ส่วนหัวของสวนสัตว์) ของการปฏิบัติตาม RFC และสำหรับการใช้งานเฉพาะให้สร้างอินเทอร์เฟซ แต่สำหรับตอนนี้ยังไม่เป็นอัลฟ่า สถาปัตยกรรมอยู่ระหว่างการพิจารณา PR เปิด (ในขณะที่ฉันกำลังเขียนบทความ PR PR ก็ค้าง แต่ประเด็นนี้ยังคงเกี่ยวข้อง)

ในตอนนี้ ให้ใช้ nginx สำหรับสถิติ

  • การกำหนดค่าแบบคงที่

คุณสามารถใช้มันได้แต่ ส่ง นั่นไม่ใช่สิ่งที่ถูกสร้างขึ้นมาเพื่อ คุณลักษณะในการกำหนดค่าแบบคงที่จะไม่ถูกเปิดเผย มีหลายช่วงเวลา:

เมื่อแก้ไขการกำหนดค่าใน yaml คุณจะเข้าใจผิด ดุนักพัฒนาในเรื่องคำฟุ่มเฟือย และคิดว่าการกำหนดค่า nginx/haproxy แม้ว่าจะมีโครงสร้างน้อยกว่า แต่ก็กระชับมากกว่า นั่นคือประเด็น การกำหนดค่าของ Nginx และ Haproxy ถูกสร้างขึ้นสำหรับการแก้ไขด้วยมือและ ส่ง สำหรับการสร้างจากโค้ด การกำหนดค่าทั้งหมดมีอธิบายไว้ใน โปรโตบุฟการสร้างมันจากไฟล์โปรโตนั้นทำผิดพลาดได้ยากกว่ามาก

โดยปกติแล้วสถานการณ์การใช้งาน Canary, b/g และอื่นๆ อีกมากมายจะถูกนำไปใช้ในการกำหนดค่าแบบไดนามิกเท่านั้น ฉันไม่ได้บอกว่าสิ่งนี้ไม่สามารถทำได้แบบคงที่ เราทุกคนทำมัน แต่สำหรับสิ่งนี้คุณต้องใส่ไม้ค้ำยันในบาลานเซอร์ตัวใดก็ได้ ส่ง รวมทั้ง.

งานที่ทูตจะขาดไม่ได้:

  • การปรับสมดุลการรับส่งข้อมูลในระบบที่ซับซ้อนและไดนามิก ซึ่งรวมถึงโครงข่ายบริการด้วย แต่ไม่จำเป็นต้องมีเพียงโครงข่ายเดียวเท่านั้น
  • ความต้องการฟังก์ชันการติดตามแบบกระจาย การอนุญาตที่ซับซ้อน หรือฟังก์ชันอื่นๆ ที่มีอยู่ใน ส่ง นอกกรอบหรือใช้งานสะดวก แต่ใน nginx/haproxy คุณต้องถูกล้อมรอบด้วย lua และปลั๊กอินที่น่าสงสัย

ทั้งสองอย่างหากจำเป็นก็ให้ประสิทธิภาพสูง

Какэтоработает

Envoy กระจายในรูปแบบไบนารีเป็นอิมเมจนักเทียบท่าเท่านั้น รูปภาพมีตัวอย่างการกำหนดค่าแบบคงที่อยู่แล้ว แต่เราสนใจเพียงเพื่อทำความเข้าใจโครงสร้างเท่านั้น

การกำหนดค่าคงที่ envoy.yaml

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          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
    load_assignment:
      cluster_name: service_google
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: www.google.com
                port_value: 443
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext
        sni: www.google.com

การกำหนดค่าแบบไดนามิก

เรากำลังหาทางแก้ไขปัญหาอะไรอยู่? คุณไม่สามารถโหลดการกำหนดค่าตัวจัดสรรภาระงานใหม่ภายใต้ภาระงานได้ ปัญหา "เล็กน้อย" จะเกิดขึ้น:

  • การตรวจสอบการกำหนดค่า

การกำหนดค่าอาจมีขนาดใหญ่ อาจมีขนาดใหญ่มาก ถ้าเราโอเวอร์โหลดทั้งหมดในคราวเดียว โอกาสที่จะเกิดข้อผิดพลาดจะเพิ่มขึ้น

  • การเชื่อมต่อที่ยาวนาน

เมื่อเริ่มต้น Listener ใหม่ คุณจะต้องดูแลการเชื่อมต่อที่ทำงานบนอันเก่า หากมีการเปลี่ยนแปลงเกิดขึ้นบ่อยครั้งและมีการเชื่อมต่อที่ยาวนาน คุณจะต้องมองหาการประนีประนอม สวัสดี kubernetes เข้าสู่ nginx

  • การตรวจสุขภาพที่ใช้งานอยู่

หากเรามีการตรวจสอบประสิทธิภาพการทำงาน เราจำเป็นต้องตรวจสอบทั้งหมดอีกครั้งในการกำหนดค่าใหม่ก่อนที่จะส่งการรับส่งข้อมูล หากมีต้นน้ำมากก็ต้องใช้เวลา สวัสดี haproxy.

เรื่องนี้แก้ไขได้อย่างไรใน ส่งด้วยการโหลดการกำหนดค่าแบบไดนามิก ตามโมเดลพูล คุณสามารถแบ่งการกำหนดค่าออกเป็นส่วนๆ และไม่เริ่มต้นส่วนที่ไม่มีการเปลี่ยนแปลงอีกครั้ง ตัวอย่างเช่น Listener ซึ่งมีราคาแพงในการกำหนดค่าเริ่มต้นใหม่และไม่ค่อยมีการเปลี่ยนแปลง

องค์ประกอบ ส่ง (จากไฟล์ด้านบน) มีเอนทิตีดังต่อไปนี้:

  • ผู้ฟัง — Listener ค้างอยู่บน IP/พอร์ตเฉพาะ
  • โฮสต์เสมือน - โฮสต์เสมือนตามชื่อโดเมน
  • เส้นทาง - กฎความสมดุล
  • กลุ่ม — กลุ่มต้นน้ำที่มีพารามิเตอร์สมดุล
  • ปลายทาง — ที่อยู่อินสแตนซ์อัปสตรีม

แต่ละเอนทิตีเหล่านี้และเอนทิตีอื่นๆ สามารถกรอกแบบไดนามิกได้ สำหรับสิ่งนี้ การกำหนดค่าจะระบุที่อยู่ของบริการที่ที่จะได้รับการกำหนดค่า บริการอาจเป็น REST หรือ gRPC โดยควรใช้ gRPC

บริการมีชื่อตามลำดับ: LDS, VHDS, RDS, CDS และ EDS คุณสามารถรวมการกำหนดค่าแบบคงที่และไดนามิกเข้าด้วยกัน โดยมีข้อจำกัดว่าไม่สามารถระบุทรัพยากรแบบไดนามิกในแบบคงที่ได้

สำหรับงานส่วนใหญ่ การใช้งานสามบริการสุดท้ายเรียกว่า ADS (Aggregated Discovery Service) ก็เพียงพอแล้วสำหรับ ชวา และไปที่นั่นคือการใช้งานดาต้าเพลน gRPC สำเร็จรูปซึ่งคุณเพียงแค่ต้องกรอกออบเจ็กต์จากแหล่งที่มาของคุณ

การกำหนดค่าใช้แบบฟอร์มต่อไปนี้:

การกำหนดค่าแบบไดนามิก envoy.yaml

dynamic_resources:
  ads_config:
    api_type: GRPC
    grpc_services:
      envoy_grpc:
        cluster_name: xds_clr
  cds_config:
    ads: {}
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          rds:
            route_config_name: local_route
            config_source:
              ads: {}
          http_filters:
          - name: envoy.router
  clusters:
  - name: xds_clr
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: xds_clr
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: xds
                port_value: 6565

เมื่อเริ่มต้น ส่ง ด้วยการกำหนดค่านี้ มันจะเชื่อมต่อกับระนาบควบคุมและพยายามขอการกำหนดค่า RDS, CDS และ EDS มีการอธิบายกระบวนการโต้ตอบเกิดขึ้นอย่างไร ที่นี่.

ในระยะสั้น, ส่ง ส่งคำขอโดยระบุประเภทของทรัพยากรที่ต้องการ เวอร์ชัน และพารามิเตอร์ของโหนด ในการตอบสนอง ได้รับทรัพยากรและเวอร์ชัน หากเวอร์ชันบน Control Plane ไม่มีการเปลี่ยนแปลง ก็จะไม่ตอบสนอง
มีตัวเลือกการโต้ตอบ 4 แบบ:

  • สตรีม gRPC หนึ่งสตรีมสำหรับทรัพยากรทุกประเภท สถานะเต็มของทรัพยากรจะถูกส่งไป
  • แยกลำธาร สภาพสมบูรณ์
  • สตรีมหนึ่งสถานะที่เพิ่มขึ้น
  • แยกกระแส สถานะที่เพิ่มขึ้น

xDS ส่วนเพิ่มช่วยให้คุณสามารถลดการรับส่งข้อมูลระหว่างระนาบควบคุมและ ส่งซึ่งเกี่ยวข้องกับการกำหนดค่าขนาดใหญ่ แต่มันทำให้การโต้ตอบซับซ้อนขึ้น คำขอประกอบด้วยรายการทรัพยากรสำหรับการยกเลิกและสมัครสมาชิก

ตัวอย่างของเราใช้ ADS - หนึ่งสตรีมสำหรับ RDS, CDS, EDS และโหมดไม่เพิ่มหน่วย หากต้องการเปิดใช้งานโหมดส่วนเพิ่ม คุณต้องระบุ api_type: DELTA_GRPC

เนื่องจากคำขอมีพารามิเตอร์โหนด เราจึงสามารถส่งทรัพยากรที่แตกต่างกันไปยังระนาบควบคุมสำหรับอินสแตนซ์ที่แตกต่างกันได้ ส่งซึ่งสะดวกสำหรับการสร้างโครงข่ายบริการ

วอร์ม

На ส่ง เมื่อเริ่มต้นหรือเมื่อได้รับการกำหนดค่าใหม่จากระนาบควบคุม กระบวนการอุ่นเครื่องทรัพยากรจะเริ่มขึ้น แบ่งออกเป็นการวอร์มอัพผู้ฟังและการวอร์มอัพคลัสเตอร์ ครั้งแรกจะเปิดตัวเมื่อมีการเปลี่ยนแปลงใน RDS/LDS และครั้งที่สองเมื่อ CDS/EDS ซึ่งหมายความว่าหากมีการเปลี่ยนแปลงเฉพาะต้นทาง ผู้ฟังจะไม่ถูกสร้างขึ้นใหม่

ในระหว่างกระบวนการอุ่นเครื่อง ทรัพยากรที่ขึ้นต่อกันคาดว่าจะมาจากระนาบควบคุมในช่วงเวลาหมดเวลา หากการหมดเวลาเกิดขึ้น การเริ่มต้นจะไม่สำเร็จ และผู้ฟังใหม่จะไม่เริ่มการฟังบนพอร์ต
ลำดับการเริ่มต้น: EDS, CDS, การตรวจสุขภาพที่ใช้งานอยู่, RDS, LDS เมื่อเปิดใช้งานการตรวจสอบสภาพที่ใช้งานอยู่ การรับส่งข้อมูลจะไปที่ต้นทางหลังจากการตรวจสุขภาพสำเร็จเพียงครั้งเดียวเท่านั้น

หากตัวฟังถูกสร้างขึ้นใหม่ อันเก่าจะเข้าสู่สถานะ DRAIN และจะถูกลบหลังจากการเชื่อมต่อทั้งหมดถูกปิดหรือหมดเวลา --drain-time-s, ค่าเริ่มต้น 10 นาที

จะยังคง

ที่มา: will.com

เพิ่มความคิดเห็น