Routing directly from ingress gateway to an external service via egress gateway

Hello everybody,

We’re quite new to Istio but have been through a lot of documentation and excellent questions on this board. Unfortunately we have not been able to get the following scenario to work:

External client --> Ingress Gateway --> Service Entry (to external service) --> Egress Gateway.

We need TLS origination for the outbound request.

We’re running on:
Microk8s v1.18.2

$ istioctl version
client version: 1.3.4
citadel version: release-1.3-20200214-10-15
egressgateway version: 1.3.4
galley version: release-1.3-20200214-10-15
ingressgateway version: release-1.3-20200214-10-15
pilot version: release-1.3-20200214-10-15
policy version: release-1.3-20200214-10-15
sidecar-injector version: release-1.3-20200214-10-15
telemetry version: release-1.3-20200214-10-15 

We’ve enabled Mesh Wide TLS both during install of Istio addon and via yaml configuration:

$ kubectl apply -f - <<EOF
apiVersion: "authentication.istio.io/v1alpha1"
kind: "MeshPolicy"
metadata:
  name: "default"
spec:
  peers:
  - mtls: {}
EOF

$ kubectl apply -f - <<EOF
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
  name: "default"
  namespace: "istio-system"
spec:
  host: "*.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
EOF

Our complete yaml containing gateways, virtual services, destination rules and service entry is here:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway # INGRESS GATEWAY
metadata:
  name: cnn-ingress
spec:
  selector:
    istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http-cnn
      protocol: HTTP
    hosts:
    - cnn.servicemesh-udv.atp.local
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService # VIRTUAL SERVICE REGARDING INGRESS GATEWAY
metadata:
  name: cnn-ingress-virtualservice
spec:
  hosts:
  - cnn.servicemesh-udv.atp.local
  gateways:
  - cnn-ingress
  http:
  - match:
    - uri:
      prefix: "/politics"
    rewrite:
      authority: edition.cnn.com
    route:
    - destination:
        host: edition.cnn.com
        subset: cnn-in
        port:
          number: 443
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egress-for-cnn
spec:
  host: edition.cnn.com
  trafficPolicy:
      portLevelSettings:
      - port:
          number: 443
        tls:
          mode: ISTIO_MUTUAL
  subsets:
  - name: cnn-in
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
      portLevelSettings:
      - port:
          number: 443
        tls:
          mode: ISTIO_MUTUAL
          #mode: SIMPLE
          sni: edition.cnn.com
  - name: cnn-out
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
      portLevelSettings:
      - port:
          number: 443
        tls:
          mode: SIMPLE
          sni: edition.cnn.com
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: cnn
spec:
  hosts:
  - edition.cnn.com
  ports:
  - number: 443
    name: tls
    protocol: TLS
  resolution: DNS
#  location: MESH_EXTERNAL
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 443
      name: tls-cnn
      protocol: TLS
    hosts:
    - edition.cnn.com
    tls:
      mode: ISTIO_MUTUAL
#     mode: MUTUAL
#      serverCertificate: /etc/certs/cert-chain.pem
#      privateKey: /etc/certs/key.pem
#      caCertificates: /etc/certs/root-cert.pem
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: cnn-egress-virtualservice
spec:
  hosts:
  - edition.cnn.com
  gateways:
  - mesh
  - istio-egressgateway
  tls:
  - match:
    - gateways:
      - mesh
      port: 443
      sni_hosts:
      - edition.cnn.com
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: cnn-middle
        port:
          number: 443
  tcp:
  - match:
    - gateways:
      - istio-egressgateway
      port: 443
    route:
    - destination:
        host: edition.cnn.com
        subset: cnn-out
        port:
          number: 443
      weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-cnn
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  trafficPolicy:
    portLevelSettings:
    - port:
        number: 443
      tls:
        mode: ISTIO_MUTUAL
  subsets:
  - name: cnn-middle
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
      portLevelSettings:
      - port:
          number: 443
        tls:
          mode: ISTIO_MUTUAL
          #mode: SIMPLE
          sni: edition.cnn.com
---

Any help would be much appriciated!

First of all, is this a normal scenario?
Our thought is that we use mesh to enforce routing, security etc.

Second, can anybody help to identify why it doesn’t work?

Third, being an open source platform and the fact that we’re running on “baremetal” do you guys know of any way to get some kind of (paid) support for Istio and our implementation?

Best regards
Jesper

Well, after many days of trial and error, I’ve finally abandoned the idea of a setup with ingress --> service entry --> egress.

Instead I’ve introduced an Nginx (with a sidecar), that has been set up as a reverse proxy. So now I have the following setup:
External client --> Ingress Gateway --> Nginx (reverse proxy) --> Service Entry (to external service) --> Egress Gateway.

This solves the routing problem.

We implemented a similar use case.

I ended up making the following work : Istio Ingress Gateway -> Virtual Service -> Service with no selector -> Endpoint Manually created pointing to external service.

Here is the detail of my implemetation.