ทักทาย! นี่เป็นบทความสั้น ๆ ที่ตอบคำถาม: “ทูตคืออะไร”, “ทำไมจึงจำเป็น” และ "จะเริ่มต้นที่ไหน?"
มันคืออะไร
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 กำลังลองทำสิ่งนี้
ในตอนนี้ ให้ใช้ 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) ก็เพียงพอแล้วสำหรับ
การกำหนดค่าใช้แบบฟอร์มต่อไปนี้:
การกำหนดค่าแบบไดนามิก 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