This article introduces the protocol transcoding capability of ASM Ingress Gateway. This capability enables users and their clients to access Google Remote Procedure Call (gRPC) services in the service mesh through HTTP or JSON.
ASM Ingress Gateway can transcode HTTP and JSON requests to access gRPC services. The following figure shows the complete process of the HTTP request, gRPC transcoding, and gRPC request.
As a proxy component of the ASM data layer, Envoy provides multiple built-in HTTP filters. This article describes a transcoder among these filters that transcode HTTP requests to gRPC requests. Envoy defines the corresponding filter protocol called config.filter.http.transcoder.v2.GrpcJsonTranscoder to enable this filter. Therefore, in the ServiceMesh control layer, an EnvoyFilter must be defined to declare the phase and place where the filter is enabled. Then, the EnvoyFilter is delivered to enable the transcoder in a specified phase. The transcoder needs to know the specific protocol of gRPC services, including the Proto Descriptors file that describes gRPC services and the full name list of gRPC services.
Envoy is the core component of ASM Ingress Gateway. Therefore, for Ingress Gateway transcoding, the key is to generate the EnvoyFilter for gRPC transcoding.
It is time-consuming and error-prone to write an EnvoyFilter because its definition is complex. This article provides an automatic EnvoyFilter generation tool, grpc-transcoder. This tool can generate the correct EnvoyFilter and save time.
Normally, gRPC services of users begin with the definition of gRPC service protocol files in the protobuf format (.proto), as shown in the following figure. grpc-service-project implements gRPC services after encapsulating the gRPC interface. The subsequent steps include image building and Deployment writing. Finally, gRPC services are deployed to an ACK cluster as a pod through ASM.
A definition that supports transcoding in .proto needs to be confirmed to support gRPC transcoding. The following code is an example of the proto in hello-servicemesh-grpc.
import "google/api/annotations.proto";
service LandingService {
//Unary RPC
rpc talk (TalkRequest) returns (TalkResponse) {
option(google.api.http) = {
get: "/v1/talk/{data}/{meta}"
};
}
...
}
message TalkRequest {
string data = 1;
string meta = 2;
}
Code from Line 5 to 7 is an added declaration for supporting the transcoding, and Line 1 introduces the .proto declaration of corresponding capability. If there is no corresponding declaration in .proto, please add it. The addition of declaration aims to generate Proto Descriptors (PD) files but does not affect grpc-service-project and subsequent steps.
Take hello-servicemesh-grpc as an example. The protoc commands are used to generate the landing.proto-descriptor
file from landing.proto. If protoc is not installed, you can download it here.
# https://github.com/AliyunContainerService/hello-servicemesh-grpc
proto_path={path/to/hello-servicemesh-grpc}/proto
# https://github.com/grpc-ecosystem/grpc-gateway/tree/master/third_party/
proto_dep_path={path/to/third_party}
protoc \
--proto_path=${proto_path} \
--proto_path=${proto_dep_path} \
--include_imports \
--include_source_info \
--descriptor_set_out=landing.proto-descriptor \
"${proto_path}"/landing.proto
Now, the PD file "landing.proto-descriptor"
is generated. Next, generate EnvoyFilter through grpc-transcoder. The sample request for calling the interface is listed below:
grpc-transcoder \
--version 1.7 \
-- service_port 9996 \
-- service_name grpc-server-svc \
--proto_pkg org.feuyeux.grpc \
--proto_svc LandingService \
--descriptor landing.proto-descriptor
Parameter Description:
Use the request above to automatically generate EnvoyFilter (grpc-transcoder-envoyfilter.yaml)
as shown in the following code:
#Generated by ASM(http://servicemesh.console.aliyun.com)
#GRPC Transcoder EnvoyFilter[1.7]
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: grpc-transcoder-grpc-server-svc
spec:
workloadSelector:
labels:
app: istio-ingressgateway
configPatches:
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
portNumber: 9996
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
proxy:
proxyVersion: ^1\.7.*
patch:
operation: INSERT_BEFORE
value:
name: envoy.grpc_json_transcoder
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder
proto_descriptor_bin: Ctl4ChVnb29nbGUvYXBpL2h0dHAucHJ...
services:
- org.feuyeux.grpc.LandingService
print_options:
add_whitespace: true
always_print_primitive_fields: true
always_print_enums_as_ints: false
preserve_proto_field_names: false
After generating the EnvoyFilter using the tool, submit the generated EnvoyFilter (grpc-transcoder-envoyfilter.yaml)
on the ASM console. The transcoder takes effect immediately.
The preceding step is equivalent to running the "kubectl --kubeconfig mes_config -f grpc-transcoder-envoyfilter.yaml -n istio-system"
command. At this point, the configuration is completed. The complete flow diagram is shown below:
Next, check whether the Envoy configuration of Ingress Gateway is available. Run the following commands in sequence to check whether the configuration of transcoder GrpcJsonTranscoder
is contained in the Envoy dynamic configuration.
# Obtain the pod name of Ingress Gateway
ingressgateway_pod=$(kubectl get pod -l app="istio-ingressgateway" -n istio-system -o jsonpath='{.items[0].metadata.name}')
# Timestamp
timestamp=$(date "+%Y%m%d-%H%M%S")
# Obtain the Envoy dynamic configuration and save it to dynamic_listeners-"$timestamp".json
kubectl -n istio-system exec $ingressgateway_pod \
-c istio-proxy \
-- curl -s "http://localhost:15000/config_dump?resource=dynamic_listeners" >dynamic_listeners-"$timestamp".json
# Check whether GrpcJsonTranscoder exists in the configuration
grep -B3 -A7 GrpcJsonTranscoder dynamic_listeners-"$timestamp".json
Envoy dynamic configuration should contain the configuration similar to the following example:
{
"name": "envoy.grpc_json_transcoder",
"typed_config": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder",
"services": [
"org.feuyeux.grpc.LandingService"
],
"print_options": {
"add_whitespace": true,
"always_print_primitive_fields": true
},
...
The last step is to verify the function of requesting for the gRPC service in the mesh through HTTP.
The following statement is the definition of the gRPC service interface.
rpc talk (TalkRequest) returns (TalkResponse) {
option(google.api.http) = {
get: "/v1/talk/{data}/{meta}"
};
}
A response declaration defined in .proto to verify the response:
message TalkResponse {
int32 status = 1;
repeated TalkResult results = 2;
}
message TalkResult {
//timestamp
int64 id = 1;
//enum
ResultType type = 2;
// id:result uuid
// idx:language index
// data: hello
// meta: serverside language
map kv = 3;
}
enum ResultType {
OK = 0;
FAIL = 1;
}
Execute the following commands in sequence to verify whether the gRPC service interface can be called through the HTTP request in Ingress Gateway:
# Obtain the IP address of Ingress Gateway
INGRESS_IP=$(k -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
# HTTP requests for port 9996 and path /v1/talk/{data}/{meta} of Ingress Gateway
curl http://$INGRESS_IP:9996/v1/talk/0/java
The response should be like this:
{
"status": 200,
"results": [
{
"id": "699882576081691",
"type": "OK",
"kv": {
"data": "Hello",
"meta": "JAVA",
"id": "8c175d5c-d8a3-4197-a7f8-6e3e0ab1fe59",
"idx": "0"
}
}
]
}
Practice of Non-Intrusive A/B Testing in the Comprehensive Procedure Based on WASM
Flagger on ASM: Progressive Canary Release Based on Mixerless Telemetry (Part 1) – Telemetry Data
feuyeux - December 30, 2020
Alibaba Container Service - September 14, 2024
Alibaba Cloud Native - September 8, 2022
Alibaba Cloud Native Community - April 9, 2024
Xi Ning Wang(王夕宁) - August 7, 2023
Xi Ning Wang(王夕宁) - August 6, 2020
Alibaba Cloud Service Mesh (ASM) is a fully managed service mesh platform that is compatible with Istio.
Learn MoreHTTPDNS is a domain name resolution service for mobile clients. It features anti-hijacking, high accuracy, and low latency.
Learn MoreEMAS HTTPDNS is a domain name resolution service for mobile clients. It features anti-hijacking, high accuracy, and low latency.
Learn MoreA Web browser-based admin tool that allows you to use command line tools to manage Alibaba Cloud resources.
Learn MoreMore Posts by feuyeux