Wanted to validate an assumption about Istio configuration options

I just wanted to validate an assumption I was making about one configuration that I am thinking Istio will be able to handle.

For a POC, I would like to set up an edge proxy to serve as a gateway that maps route prefixes to legacy services that are not in Kubernetes. The legacy services do their own TLS termination. For the scope of the POC, I’d like to be able to do something like this:

The focus of the POC is on rate limiting, and I have already succeeded in getting the above setup to work with Envoy. But I’m having trouble working through the config needed to get Istio to allow it. And that made me want to verify that having this kind of routing to a backend service using TLS will be possible.

In a production setup, after the POC, the edge proxy would not allow http/port 80. But for now I’m just trying to get any kind of gateway routing working, which will let me get on to looking at rate limiting.

Any help is appreciated.

After doing a little more digging around, I’m able to confirm that this setup is possible. Getting it to work is a bit convoluted, but I’ll include an example for anyone who runs into this question in the future.

This example assumes Istio 1.12.2, and it assumes that you’ve got ingress and egress deployments set up in the istio-sysetm namespace. See this link for getting started.

Here is a config that will configure the path /cnn on the edge proxy to route to edition.cnn.com, a destination that requires TLS to work:

---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: proxy
spec:
  selector:
    istio: ingressgateway # use istio default ingress gateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - '*'

---
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: cnn
  namespace: default
spec:
  hosts:
  - edition.cnn.com
  ports:
  - name: http
    number: 80
    protocol: HTTP
  - name: https
    number: 443
    protocol: HTTPS
  resolution: DNS

---
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: istio-egressgateway
  namespace: default
spec:
  selector:
    istio: egressgateway
  servers:
  - hosts:
    - edition.cnn.com
    port:
      name: https-port-for-tls-origination
      number: 80
      protocol: HTTPS
    tls:
      mode: ISTIO_MUTUAL

---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: direct-cnn-through-egress-gateway-proxy
  namespace: default
spec:
  gateways:
  - proxy
  hosts:
  - '*'
  http:
  - match:
    - gateways:
      - proxy
      port: 80
    - uri:
        prefix: /cnn
    headers:
      request:
        set:
          Host: edition.cnn.com
    rewrite:
      uri: /
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        port:
          number: 80
        subset: cnn

---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: direct-cnn-through-egress-gateway
  namespace: default
spec:
  gateways:
  - istio-egressgateway
  hosts:
  - edition.cnn.com
  http:
  - match:
    - gateways:
      - istio-egressgateway
      port: 80
    route:
    - destination:
        host: edition.cnn.com
        port:
          number: 443

---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: originate-tls-for-edition-cnn-com
  namespace: istio-system
spec:
  host: edition.cnn.com
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
    portLevelSettings:
    - port:
        number: 443
      tls:
        mode: SIMPLE
        caCertificates: /etc/ssl/certs/ca-certificates.crt

---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: egressgateway-for-cnn
  namespace: istio-system
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
  - name: cnn
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
      portLevelSettings:
      - port:
          number: 80
        tls:
          mode: ISTIO_MUTUAL
          sni: edition.cnn.com

To see this in action, save the above config as gateway.yaml and run:

$ kubectl apply -f gateway.yaml
$ curl -I http://<gateway-hostname>/cnn
HTTP/1.1 200 OK     
...
$ kubectl delete -f gateway.yaml

In this setup, we

  1. Configure a route in the gateway edge proxy to watch for the path “/cnn”
  2. Configure an egress gateway to originate TLS for our request to CNN
  3. Call out to CNN’s site
  4. Return the result

See this tutorial and this tutorial for more information.

To anyone looking to this thread for a solution, I have since discovered that TLS can be originated in the destination rule. It is not necessary to set up an egress gateway to originate TLS for connecting to external services that require TLS. This can be done in the destination rule set up for the external service, e.g.:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: some-external-service
spec:
  host: some.external.service.com
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
    portLevelSettings:
    - port:
        number: 443
      tls:
        mode: SIMPLE