Overview
Consul is a service mesh solution that provides service discovery, health checking, and load balancing for distributed applications. When working with gRPC services in Consul, it is essential to configure service defaults and set up an Ingress Gateway to enable communication between services. This knowledge base article guides you through accessing gRPC services in Consul using service defaults and Ingress Gateway with the help of the gRPC Curl utility.
Prerequisites
- Consul installed and running.
- A gRPC service registered with the Consul.
- A basic understanding of gRPC.
Steps to perform service mesh for grpc service using ingress gateway
Step 1: Register a "fake-service" gRPC Service with Consul using Service Defaults
-
On the VM1, run the fake-service docker container using the command -
docker run -d -p 8085:9090 nicholasjackson/fake-service:dev
. -
On the same VM1, register a consul service using the below file.
service {
name = "fake-service"
port = 8085
connect {
sidecar_service {}
}
}
-
Started the sidecar service for fake-service using command -
consul connect envoy -sidecar-for fake-service
. -
Implement Service Default on
fake-service
usingProtocol = grpc
. Below is the configuration file for the reference.
$ cat fake-service-grpc-sd.hcl
Kind = "service-defaults"
Name = "fake-service"
Namespace = "default"
Protocol = "grpc"
-
Run the Consul CLI Command -
consul config write fake-service-grpc-sd.hcl
-
After implemented above, validated the same using command -
consul config read -kind service-defaults -name fake-service
.
{
"Kind": "service-defaults",
"Name": "fake-service",
"Partition": "default",
"Namespace": "default",
"Protocol": "grpc",
"TransparentProxy": {},
"MeshGateway": {},
"Expose": {},
"CreateIndex": 1158071,
"ModifyIndex": 1158071
}
Step 2: Deploy an Ingress Gateway
-
On VM2, deploy Ingress Gateway using the below configuration file for
Protocol = "grpc"
Kind = "ingress-gateway"
Name = "fake-ingress-service"
Listeners = [
{
Port = 8090
Protocol = "grpc"
Services = [
{
Name = "fake-service"
}
]
}
]
-
To validate the same, you can use command -
consul config read -kind ingress-gateway -name fake-ingress-service
. You will get output like below -
{
"Kind": "ingress-gateway",
"Name": "fake-ingress-service",
"Partition": "default",
"Namespace": "default",
"TLS": {
"Enabled": false
},
"Listeners": [
{
"Port": 8090,
"Protocol": "grpc",
"Services": [
{
"Name": "fake-service",
"Hosts": null,
"Namespace": "default",
"Partition": "default"
}
]
}
],
"CreateIndex": 1157844,
"ModifyIndex": 1157844
}
-
Start the ingress gateway using the command -
consul connect envoy -gateway=ingress -register -service fake-ingress-service -address '{{ GetInterfaceIP "eth0" }}:8888'
Step 3: Discover the external service
Once started, the ingress gateway services can be discovered via the Consul DNS interface using the pattern <service>.ingress.<datacenter>.<domain>
.
dig @localhost -p 8600 fake-service.ingress.default.dc1.consul A
; <<>> DiG 9.16.1-Ubuntu <<>> @localhost -p 8600 fake-service.ingress.default.dc1.consul A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14249
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;fake-service.ingress.default.dc1.consul. IN A
;; ANSWER SECTION:
fake-service.ingress.default.dc1.consul. 0 IN A 172.31.84.101
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Sat Nov 11 11:41:48 UTC 2023
;; MSG SIZE rcvd: 84
Step 4: Allow access between the services (fake-service and ingress-gateway)
By default, if zero-trust networking is configured as a recommended best practice, the user will not be able to use the ingress gateway until he explicitly enables connectivity from the ingress to the services represented by it. This is one extra layer of security to prevent services being exposed externally until ready.
To enable communication between two services, in Consul service mesh, you need to create an intention that explicitly allows traffic between a source service (downstream) and a destination service (upstream).
Create the intention to allow communication to the fake-service
service.
- First, create a file for a config entry definition named
intention-config.hcl
.
Kind = "service-intentions"
Name = "fake-service"
Sources = [
{
Name = "fake-ingress-service"
Action = "allow"
}
]
- From the same directory where
intention-config.hcl
saved this file, run the following command in the terminal to initialize these intention rules.
consul config write intention-config.hcl
Step 5: Access the service using "grpcurl" utility
- Ingress Gateway hostname (by adding a host entry) is used to access the service as the route that is generated matches on that.
curl -s 0:19000/config_dump\?include_eds | jq '.configs[] | select(."@type" == "type.googleapis.com/envoy.admin.v3.RoutesConfigDump") | .dynamic_route_configs'
[
{
"version_info": "0fda1bb8d5e2a52c65ad41623970d4dc4eda5c7a033911def30608948bb545f2",
"route_config": {
"@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
"name": "8090",
"virtual_hosts": [
{
"name": "fake-service",
"domains": [
"fake-service.ingress.*",
"fake-service.ingress.*:8090"
],
"routes": [
{
"match": {
"prefix": "/"
},
"route": {
"cluster": "fake-service.default.dc1.internal.c35323ab-1759-e8f6-eafb-663ca7bcfeaf.consul"
}
}
]
}
],
"validate_clusters": true
},
"last_updated": "2023-12-05T00:56:34.182Z"
}
]
- Alternatively, set the Ingress Gateway Listener.Services.Hosts to
localhost:8090
if user want to access it using the localhost URL. - A sample output of this scenario is below after running the command -
grpcurl -plaintext fake-service.ingress.dc1.consul:8090 FakeService.Handle
{
"Message": "{\n \"name\": \"Service\",\n \"type\": \"gRPC\",\n \"ip_addresses\": [\n \"192.168.18.11\",\n \"192.168.65.1\"\n ],\n \"start_time\": \"2023-12-05T12:43:39.440731\",\n \"end_time\": \"2023-12-05T12:43:39.441760\",\n \"duration\": \"1.02853ms\",\n \"body\": \"Hello World\",\n \"code\": 0\n}\n"
}
Conclusion
Accessing gRPC services in Consul using service defaults and an Ingress Gateway in a service mesh enhances the reliability and scalability of microservice based architecture. By following these steps, the user can efficiently configure the environment and use the gRPC Curl utility to interact with gRPC services through the Ingress Gateway.
Reference
Consul Ingress Gateway Overview