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
- Configure a route in the gateway edge proxy to watch for the path “/cnn”
- Configure an egress gateway to originate TLS for our request to CNN
- Call out to CNN’s site
- 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