Hannes Lohmander
Hannes Lohmander

Reputation: 51

Dealing with CORS using the Contour Kubernetes Ingress

What is the best way to allow CORS requests at this time? (Given that CORS support in the Contour Ingress currently is in the "parking lot")

My particular use case is hosting a GRPC service, which envoy reverse proxies. Conveniently, contour also supports grpc-web out-of-the-box, which we'd like to use for our web service.

However, given that CORS are not supported, we cannot do cross-domain requests.

Apart from making our web app use the same domain as the GRPC api, is there any other solution that could fill our need at the moment?

Basically, we'd want the envoy to be configured very similarly to the GRPC web example config.

Upvotes: 5

Views: 1119

Answers (1)

fsb2023
fsb2023

Reputation: 23

For anyone that stumbles upon this question trying to setup Controur, gRPC, and TLS;

you want to use HTTPProxy instead. Working configuration with TLS:

apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: service-proxy 
spec:
  virtualhost:
    fqdn: service.example.com 
    corsPolicy:
      allowCredentials: true
      allowOrigin:
        - "*" 
      allowMethods:
        - GET
        - POST
        - OPTIONS
      allowHeaders:
        - authorization
        - cache-control
        - x-grpc-web
        - User-Agent
        - x-accept-content-transfer-encoding
        - x-accept-response-streaming
        - x-user-agent
        - x-grpc-web
        - grpc-timeout
        - Grpc-Message
        - Grpc-Status
        - content-type
    tls:
      secretName: service-secret
  routes:
    - conditions:
      - prefix: /
      services:
        - name: my-service
          port: 80
---
apiVersion: apps/v1
kind: Deployment metadata:
  labels:
    app: my-app
    run: my-service
  name: my-service
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: my-app
      run: my-service
  template:
    metadata:
      labels:
        app: my-app
        run: my-service
    spec:
      containers:
        - image: image:latest
          name: my-service
          resources: {}
          imagePullPolicy: Always
          readinessProbe:
            initialDelaySeconds: 10
            periodSeconds: 2
            httpGet:
              path: /health-check
              port: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app: my-app
    run: my-service
  annotations:
    projectcontour.io/upstream-protocol.h2c: "80"
spec:
  ports:
  - port: 80
    targetPort: 50051
    protocol: TCP
  selector:
    run: my-service

A Couple notes

  1. My understanding from the documentation is that the projectcontour.io/upstream-protocol.h2c should actually be projectcontour.io/upstream-protocol.h2, but doing that I get a TLS error: 268435703:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER error in the response. This configuration, with h2c, seems to be working and actually employing TLS to transport request/response data.
  2. I haven't gone through and groomed the allowHeadrs, this is just a set that's working for me right now using grpcurl and a web application frontend built with React using the awesome nice-grpc-web library.
  3. Obligatory - you should not use "*" as an allow origin in production because it is a security concern - warning (really... don't do it).
  4. The TLS secret service-secret was actually manually generated, I haven't tested the cert-manager stuff yet.

Upvotes: 1

Related Questions