hashicorp / hashicorp/consul

CORS and gRPC web issue

Open
#10,216 9 comments 0 reactions 0 assignees View on GitHub
theme/connect theme/ingress-gw type/enhancement
Dominant language
Go
Stars
30.1k
Forks
4.6k
Avg merge
1d 18h
Merged PRs (30d)
39

Description

Hey everybody,

I have deployed consul on Kubernetes cluster via helm chart, and that part is working exactly as it is supposed to. On top of that, I have enabled Ingress Gateway with connect inject option and deployed my gRPC gateway behind that proxy. When I try to connect to that proxy, It works for everything except gRPC-web(https://github.com/grpc/grpc-web). I am facing a CORS issue now that I can't resolve. So it would be really helpful if someone has any idea how to resolve this issue.

I have configured my local envoy configuration, and It works fine. Here is the local envoy config:

```yaml
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: gateway_service
max_grpc_timeout: 0s
cors:
allow_origin_string_match:
- prefix: "*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: "1728000"
expose_headers: custom-header-1,grpc-status,grpc-message
http_filters:
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.cors
- name: envoy.filters.http.router
clusters:
- name: gateway_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
load_assignment:
cluster_name: cluster_0
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: host.docker.internal
port_value: 9990

```

Here is my gateway Kubernetes configuration:

ingress gateway:

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: IngressGateway
metadata:
name: ingress-gateway
spec:
listeners:
- port: 8080
protocol: grpc
services:
- name: gateway-service
hosts: 'my-host.com'
```

pod:

```yaml
apiVersion: v1
kind: Pod
metadata:
name: gateway-service
labels:
app: 'gateway-service'
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9102"
consul.hashicorp.com/connect-inject: "true"
consul.hashicorp.com/connect-service-upstreams: "search-service:9991, reservation-service:9997"
spec:
containers:
- name: gateway-service
image: my.image:latest
env:
- name: SERVER_PORT
value: "9990"
- name: SERVER_HOST
value: "127.0.0.1"
- name: SEARCH_CLIENT_PORT
value: "9991"
- name: SEARCH_CLIENT_HOST
value: "127.0.0.1"
- name: DEBUG
value: "true"
ports:
- containerPort: 9990
name: grpc
imagePullSecrets:
- name: gitlab-auth
serviceAccountName: gateway-service

```

service:

```yaml
apiVersion: v1
kind: Service
metadata:
name: gateway-service
spec:
type: ClusterIP
selector:
app: gateway-service
ports:
- name: grpc
port: 9990
targetPort: 9990

```

service account:

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: gateway-service

```

service defaults:

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: gateway-service
spec:
protocol: grpc
```

As much as I was able to understand from documentation and some other issues I have to add **ProxyDefaults** kind and `envoy_extra_static_listeners_json`. And I have tried to do so, but nothing has worked for me, here is the example of config I tried:

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ProxyDefaults
metadata:
name: ingress-gateway
spec:
config:
protocol: grpc
envoy_extra_static_listeners_json: '{"name":"listener_0","address":{"socket_address":{"address":"my-host.com","port_value":8080}},"filter_chains":[{"filters":[{"name":"envoy.filters.network.http_connection_manager","typed_config":{"@type":"type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager","codec_type":"auto","stat_prefix":"ingress_http","route_config":{"name":"local_route","virtual_hosts":[{"name":"local_service","domains":["*"],"routes":[{"match":{"prefix":"/"},"route":{"cluster":"gateway_service","max_grpc_timeout":"0s"}}],"cors":{"allow_origin_string_match":[{"prefix":"*"}],"allow_methods":"GET, PUT, DELETE, POST, OPTIONS","allow_headers":"keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout","max_age":"1728000","expose_headers":"custom-header-1,grpc-status,grpc-message"}}]},"http_filters":[{"name":"envoy.filters.http.grpc_web"},{"name":"envoy.filters.http.cors"},{"name":"envoy.filters.http.router"}]}}]}]}'

```

Thanks.

Contributor guide

Open the contributing guide

Research direction

Begin with the IngressGateway and ServiceDefaults manifests, then compare the working local Envoy configuration with the attempted ProxyDefaults configuration and its envoy_extra_static_listeners_json value. Reproduce the gRPC-web CORS request against the Kubernetes ingress gateway; done means the request succeeds without the reported CORS failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
grpc, helm, kubernetes
Domain
infrastructure, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.