Introduction to Istio, Part 12
Extending the Mesh
Mở rộng tính năng của Istio Service Mesh
Chương này giải thích một số cách để mở rộng tính năng của Istio Service Mesh. Chúng ta sẽ tìm hiểu về các khái niệm cơ bản của proxy Envoy, cách sử dụng tài nguyên EnvoyFilter để tùy chỉnh cấu hình của Envoy, và cách sử dụng các plugin Wasm để mở rộng tính năng của Envoy proxy.
Mục tiêu học tập
Đến cuối chương này, bạn sẽ có thể:
Hiểu các thành phần cơ bản của Envoy proxy.
Hiểu cách tùy chỉnh cấu hình của Envoy proxy bằng tài nguyên EnvoyFilter.
Hiểu cách xây dựng một plugin Wasm cơ bản bằng Go và Proxy-Wasm SDK.
Hiểu cách sử dụng tài nguyên WasmPlugin để triển khai plugin Wasm vào Istio Service Mesh.
Tổng quan về Envoy Proxy
Trước khi giải thích tài nguyên EnvoyFilter, chúng ta cần tìm hiểu tổng quan về cấu hình của Envoy và các thành phần cơ bản của nó.
Cấu hình Envoy là một file JSON được chia thành nhiều phần. Các thành phần cơ bản và các khái niệm cần hiểu được minh họa trong sơ đồ dưới đây:
Các thành phần chính của Envoy
Listeners:
Đây là nơi Envoy lắng nghe các kết nối đến (inbound traffic).
Mỗi listener định nghĩa các địa chỉ IP, cổng, và giao thức (HTTP, TCP, v.v.) mà Envoy sẽ sử dụng.
Filters:
- Các bộ lọc được áp dụng trên traffic, giúp thực hiện các nhiệm vụ như giải mã HTTP, nén dữ liệu, hay thực hiện kiểm tra bảo mật.
Clusters:
Một cluster đại diện cho một nhóm các dịch vụ backend mà Envoy có thể gửi traffic đến.
Envoy sử dụng các cluster để quản lý kết nối và cân bằng tải giữa các endpoint.
Routes:
Định nghĩa cách Envoy định tuyến các request.
Một route chỉ định URL nào nên được chuyển đến cluster nào.
Endpoints:
- Mỗi cluster chứa một danh sách endpoint — các địa chỉ IP và cổng thực tế nơi các dịch vụ backend chạy.
Virtual Hosts:
Các host ảo cho phép Envoy xử lý nhiều tên miền trên cùng một listener.
Chúng chứa các định nghĩa routes.
Những thành phần trên giúp Envoy thực hiện nhiệm vụ của một proxy hiện đại với khả năng cân bằng tải, mã hóa mTLS, và quản lý lưu lượng.
Listeners trong Envoy
Listeners là các vị trí mạng (network locations) được định danh, thường bao gồm địa chỉ IP và cổng (port). Envoy lắng nghe tại các vị trí này để nhận kết nối và xử lý các yêu cầu. Trong Istio, nhiều listener được tự động tạo cho mỗi sidecar proxy.
Ví dụ, có một listener được gắn với địa chỉ 0.0.0.0:15006
, nơi tất cả lưu lượng đi vào (incoming traffic) pod được định tuyến. Một ví dụ khác là listener 0.0.0.0:15001
, nơi lưu lượng đi ra (outgoing traffic) từ pod được định tuyến.
Giữa các listener và route, các yêu cầu trong Envoy đi qua một chuỗi các filter (bộ lọc). Các filter này có thể:
Xử lý và bổ sung thông tin vào yêu cầu,
Sinh ra số liệu thống kê,
Chuyển đổi giao thức,
Hoặc thay đổi nội dung của các yêu cầu.
Nhờ đó, Envoy không chỉ đóng vai trò như một proxy thông thường mà còn cung cấp các khả năng nâng cao như theo dõi hiệu suất, quản lý giao thức, và cải thiện bảo mật.
Envoy Filters
Khi một yêu cầu được gửi tới Envoy, nó bắt đầu tại listener và được xử lý qua một danh sách các filter theo thứ tự gọi là filter chain.
Mỗi filter trong chuỗi này có thể bổ sung thông tin cho yêu cầu và quyết định:
Chuyển yêu cầu đến filter tiếp theo hoặc
Dừng xử lý yêu cầu tại đó.
Filter cuối cùng trong chuỗi chịu trách nhiệm định tuyến yêu cầu đến đích của nó.
Ở mức tổng quan, Envoy chia filter thành ba loại chính:
1. Listener Filters
Các listener filter làm việc với dữ liệu thô (raw data) và có khả năng thao tác metadata của các kết nối ở tầng 4 (L4) của mô hình OSI trong giai đoạn kết nối ban đầu.
Ví dụ phổ biến là TLS inspector filter, dùng để:
Xác định xem kết nối có được mã hóa TLS hay không.
Trích xuất thông tin TLS cần thiết nếu kết nối sử dụng TLS.
2. Network Filters
Network filter xử lý dữ liệu thô ở dạng các gói TCP (TCP packets).
Filter phổ biến nhất trong nhóm này là HTTP connection manager filter (HCM), đóng vai trò quản lý các kết nối HTTP.
Các ví dụ khác về network filter bao gồm:
Rate limit filter: Giới hạn tốc độ yêu cầu.
Redis proxy filter: Proxy cho Redis.
Mongo proxy filter: Proxy cho MongoDB.
Connection limit filter: Giới hạn số lượng kết nối.
Bạn có thể xem danh sách đầy đủ các network filter tích hợp sẵn tại đây.
3. HTTP Filters
HTTP filter hoạt động ở tầng 7 (L7), làm việc với dữ liệu HTTP.
HTTP connection manager filter (HCM) có khả năng tạo ra các HTTP filter tùy chọn.
HCM filter chuyển đổi dữ liệu thô thành dữ liệu HTTP, giúp các HTTP filter có thể thao tác với các yêu cầu và phản hồi HTTP.
Nhờ sự phân tầng và khả năng mở rộng qua các loại filter trên, Envoy trở thành một proxy mạnh mẽ, linh hoạt, phục vụ tốt cho các nhu cầu về hiệu suất và bảo mật trong hệ thống dịch vụ mesh.
Envoy Routes
Khi định tuyến lưu lượng HTTP, filter cuối cùng trong filter chain phải là router filter. Filter này chịu trách nhiệm định tuyến lưu lượng đến đích, dẫn đến khối cấu hình thứ hai - routes.
Trong cấu hình route, chúng ta:
Định nghĩa virtual hosts (máy chủ ảo).
Viết các route để khớp với các yêu cầu đến dựa trên URI, header, v.v.
Chỉ định nơi gửi lưu lượng dựa trên route được khớp.
Trong mỗi route, chúng ta có thể định tuyến lưu lượng đến các cluster.
Envoy Clusters và Endpoints
Trong Envoy, một cluster là tập hợp các host upstream có khả năng nhận lưu lượng. Cluster tương tự với khái niệm Kubernetes Service.
Lưu ý:
Upstream: Đích hoặc máy chủ nhận lưu lượng (server).
Downstream: Nguồn gửi yêu cầu (client).
Endpoints là các phần tử của cluster, biểu thị địa chỉ mà lưu lượng có thể được gửi tới, ví dụ: một địa chỉ IP hoặc hostname.
Ví dụ cấu hình Envoy
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: hello_world
http_filters:
- name: envoy.filters.http.router
route_config:
name: my_first_route
virtual_hosts:
- name: my_vhost
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: hello_world_service
clusters:
- name: hello_world_service
connect_timeout: 5s
load_assignment:
cluster_name: hello_world_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8000
Phân tích cấu hình
Listener:
Tên:
listener_0
.Lắng nghe trên port 10000.
Filter chain:
- Chứa một HTTP Connection Manager (HCM) filter.
HTTP Filter:
- Sử dụng router filter để định tuyến lưu lượng.
Route Configuration:
Khớp với tất cả các virtual host (
*
trong mảngdomains
).Khớp các yêu cầu có prefix là
/
.Định tuyến lưu lượng đến cluster hello_world_service.
Cluster Configuration:
Tên cluster:
hello_world_service
.Có một endpoint tại
127.0.0.1:8000
.
Cấu hình trên minh họa cách Envoy proxy hoạt động từ việc nhận lưu lượng tại listener, xử lý qua filter chain, định tuyến qua router filter, và cuối cùng gửi lưu lượng đến các endpoint thuộc một cluster được định nghĩa.
Khi sử dụng EnvoyFilter, điều đầu tiên cần làm là xác định vị trí áp dụng patch. Điều này được mô tả trong trường applyTo
. Ví dụ, bạn có thể áp dụng patch vào:
Listener (
LISTENER
)Network filter (
NETWORK_FILTER
)HTTP filter (
HTTP_FILTER
)Virtual host (
VIRTUAL_HOST
)
Xác định vị trí chính xác với match
Ngoài việc chỉ định vị trí tổng quát với applyTo
, bạn có thể cung cấp vị trí cụ thể hơn thông qua trường match
. Trường này cho phép định nghĩa các điều kiện khớp mà patch phải đáp ứng trước khi được áp dụng.
Các điều kiện khớp phổ biến:
Trường | Mô tả |
context | Xác định loại proxy cần áp dụng patch: inbound (SIDECAR_INBOUND ), outbound (SIDECAR_OUTBOUND ), gateway (GATEWAY ), hoặc mọi proxy (ANY ). |
proxy | Khớp với các thuộc tính của proxy, như phiên bản proxy hoặc metadata node được thiết lập. |
listener | Khớp với các thuộc tính của listener trong Envoy (ví dụ: số port, tên listener, hoặc filter cụ thể trong chuỗi filter). |
routeConfiguration | Khớp với cấu hình route HTTP (ví dụ: tên route, số port, tên cổng, tên gateway, hoặc virtual host cụ thể). |
cluster | Khớp với các thuộc tính của cluster (ví dụ: tên cluster, subset, tên dịch vụ đầy đủ, hoặc số port). |
Ví dụ cấu hình
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
portNumber: 9000
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
Phân tích ví dụ
applyTo
:- Loại patch được áp dụng là HTTP_FILTER.
match.context
:- Chỉ định áp dụng patch cho sidecar inbound traffic (
SIDECAR_INBOUND
).
- Chỉ định áp dụng patch cho sidecar inbound traffic (
match.listener
:Khớp với một listener cụ thể:
portNumber: 9000.
filterChain: Chuỗi filter chứa một HTTP Connection Manager filter (
envoy.filters.network
.http_connection_manager
).
subFilter
:- Target vào router filter (
envoy.filters.http.router
) bên trong HCM.
- Target vào router filter (
Sau khi xác định vị trí cần áp dụng, bước tiếp theo là quyết định nội dung và cách áp dụng patch. Phần cấu hình của patch được mô tả qua hai thành phần chính:
operation
: Xác định cách thức áp dụng patch.value
: Mô tả nội dung thực tế của patch.
operation
: Cách áp dụng patch
operation
là trường xác định cách patch sẽ được thêm hoặc thay đổi trong cấu hình hiện tại của Envoy. Một số loại operation phổ biến:
ADD: Thêm mới cấu hình vào vị trí được chỉ định.
MERGE: Hợp nhất patch với cấu hình hiện tại.
REMOVE: Gỡ bỏ một phần của cấu hình.
INSERT_BEFORE/INSERT_AFTER: Chèn patch vào trước hoặc sau một đối tượng cụ thể.
value
: Giá trị của patch
Trường value
chứa nội dung cấu hình của patch, được viết dưới dạng YAML. Đây chính là phần thiết lập cụ thể mà bạn muốn áp dụng cho Envoy.
Ví dụ cấu hình patch
- applyTo: EXTENSION_CONFIG
patch:
operation: ADD
value:
name: my-wasm-extension
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
config:
root_id: my-wasm-root-id
vm_config:
vm_id: my-wasm-vm-id
runtime: envoy.wasm.runtime.v8
code:
remote:
http_uri:
uri: http://my-wasm-binary-uri
Phân tích ví dụ
applyTo
:- Patch được áp dụng vào phần EXTENSION_CONFIG trong cấu hình Envoy.
patch.operation
:- Thao tác được sử dụng là ADD, nghĩa là thêm một cấu hình mới vào phần EXTENSION_CONFIG.
patch.value
:name: Tên của extension là
my-wasm-extension
.typed_config:
Sử dụng filter
envoy.extensions.filters.http.wasm.v3.Wasm
.root_id và vm_id xác định plugin Wasm.
runtime: Sử dụng runtime
envoy.wasm.runtime.v8
.code.remote.http_uri: Định nghĩa URL từ xa chứa binary của Wasm plugin (
http://my-wasm-binary-uri
).
Không có
match
:- Patch này không sử dụng điều kiện khớp (
match
). Thay vào đó, cấu hình được áp dụng trực tiếp vào toàn bộ phần EXTENSION_CONFIG.
- Patch này không sử dụng điều kiện khớp (