Skip to content

Instantly share code, notes, and snippets.

@Ranjandas
Created August 29, 2024 08:23
Show Gist options
  • Save Ranjandas/14f3d94dc1ce6ff4603e6cb65ef935af to your computer and use it in GitHub Desktop.
Save Ranjandas/14f3d94dc1ce6ff4603e6cb65ef935af to your computer and use it in GitHub Desktop.
Consul API Gateway - Header Based Routing to multiple subsets of same Service using Service-Resolvers

Disclaimer: The information provided in this technical solution is for general informational purposes only. It is provided "as is" without any warranties of any kind, either express or implied. The use of this solution is at your own risk, and I do not assume any responsibility or liability for any errors, omissions, or results obtained from the use of this information. Additionally, I disclaim any and all responsibility or liability for any damages or losses, including but not limited to, direct, indirect, incidental, special, or consequential damages arising out of or in connection with the use of or reliance on this technical solution. Users are encouraged to verify any information before relying on it and to consult with appropriate professionals or experts as needed.

This is a demo of how the Consul API gateway can be used with Service-Resolvers to route traffic based on headers to different subsets of the same backend service. This is a workaround as this is not supported natively using API Gateway.

Pre-requisites

Demo

asciicast

Steps

The consul.hcl has all the required config-entries and service registrations (with meta).

  1. Start Consul Agent
consul agent -dev -config-file consul.hcl
  1. Start Consul API Gateway
consul connect envoy -gateway api -service jeff-apigw0 -register
  1. Start the blue instance of DMZ service
LISTEN_ADDR=127.0.0.1:9090 MESSAGE=BLUE fake-service
  1. Start the sidecar for blue instance of DMZ service
consul connect envoy -sidecar-for dmz-blue -admin-bind localhost:19001
  1. Start the green instance of DMZ service
LISTEN_ADDR=127.0.0.1:9091 MESSAGE=GREEN fake-service
  1. Start the sidecar for blue instance of DMZ service
consul connect envoy -sidecar-for dmz-green -admin-bind localhost:19002

Verify

curl -H "color: blue" localhost:8443
{
  "name": "Service",
  "uri": "/",
  "type": "HTTP",
  "ip_addresses": [
    "192.168.104.6",
    "172.17.0.1",
    "172.21.0.1"
  ],
  "start_time": "2024-08-29T17:46:56.915651",
  "end_time": "2024-08-29T17:46:56.915853",
  "duration": "202.629µs",
  "body": "BLUE",
  "code": 200
}
curl -H "color: green" localhost:8443                                                                                                                                            17:46:54 [0/0]
{
  "name": "Service",
  "uri": "/",
  "type": "HTTP",
  "ip_addresses": [
    "192.168.104.6",
    "172.17.0.1",
    "172.21.0.1"
  ],
  "start_time": "2024-08-29T17:46:51.854916",
  "end_time": "2024-08-29T17:46:51.855124",
  "duration": "207.396µs",
  "body": "GREEN",
  "code": 200
}
config_entries {
bootstrap = [
{
Kind = "proxy-defaults"
Name = "global"
Config = {
protocol = "http"
}
},
{
Kind = "api-gateway"
Name = "jeff-apigw0"
Listeners = [
{
Name = "jeff-apigw0-listener"
Port = 8443
Protocol = "http"
}
]
},
{
Kind = "http-route"
Name = "my-http-route"
Rules = [
{
Matches = [
{
Headers = {
Match = "exact"
Name = "color"
value = "blue"
}
}
],
Services = [
{
Name = "dmz-blue"
}
]
},
{
Matches = [
{
Headers = {
Match = "exact"
Name = "color"
value = "green"
}
}
],
Services = [
{
Name = "dmz-green"
}
]
}
]
Parents = [
{
Kind = "api-gateway"
Name = "jeff-apigw0"
SectionName = "jeff-apigw0-listener"
}
]
},
{
Kind = "service-resolver"
Name = "dmz"
Subsets = {
blue = {
Filter = "Service.Meta.color == blue"
}
green = {
Filter = "Service.Meta.color == green"
}
}
DefaultSubset = "green"
},
{
Kind = "service-resolver"
Name = "dmz-blue"
Redirect = {
Service = "dmz"
ServiceSubset = "blue"
}
},
{
Kind = "service-resolver"
Name = "dmz-green"
Redirect = {
Service = "dmz"
ServiceSubset = "green"
}
}
]
}
services {
name = "dmz"
id = "dmz-blue"
port = 9090
meta = {
color = "blue"
}
connect = {
sidecar_service = {
proxy = {
local_service_address = "127.0.0.1"
}
}
}
checks = [
{
id = "check-dmz-blue"
name = "dmz blue health check"
http = "http://localhost:9090/health"
interval = "1s"
timeout = "1s"
}
]
}
services {
name = "dmz"
id = "dmz-green"
port = 9091
meta = {
color = "green"
}
connect = {
sidecar_service = {
proxy = {
local_service_address = "127.0.0.1"
}
}
}
checks = [
{
id = "check-dmz-green"
name = "dmz green health check"
http = "http://localhost:9091/health"
interval = "1s"
timeout = "1s"
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment