1
votes

I have an example istio cluster on AKS with the default ingress gateway. Everything works as expected I'm just trying to understand how. The Gateway is defined like so:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-gateway
  namespace: some-config-namespace
spec:
  selector:
    app: istio-ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - uk.bookinfo.com
    - eu.bookinfo.com
    tls:
      httpsRedirect: true # sends 301 redirect for http requests
  - port:
      number: 443
      name: https-443
      protocol: HTTPS
    hosts:
    - uk.bookinfo.com
    - eu.bookinfo.com
    tls:
      mode: SIMPLE # enables HTTPS on this port
      serverCertificate: /etc/certs/servercert.pem
      privateKey: /etc/certs/privatekey.pem

Reaching the site on https://uk.bookinfo.com works fine. However when I look at the LB and Service that goes to the ingressgateway pods I see this:

LB-IP:443 -> CLUSTER-IP:443 -> istio-ingressgateway:8443
kind: Service
spec:
  ports:
    - name: http2
      protocol: TCP
      port: 80
      targetPort: 8080
      nodePort: 30804
    - name: https
      protocol: TCP
      port: 443
      targetPort: 8443
      nodePort: 31843
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  clusterIP: 10.2.138.74
  type: LoadBalancer

Since the targetPort for the istio-ingressgateway pods is 8443 then how does the Gateway definition work which defines a port number as 443?

2

2 Answers

2
votes

As mentioned here

port: The port of this service

targetPort: The target port on the pod(s) to forward traffic to

As far as I know targetPort: 8443 points to envoy sidecar, so If I understand correctly envoy listen on 8080 for http and 8443 for https.

There is an example in envoy documentation.

So it goes like this:

LB-IP:443 -> CLUSTER-IP:443 -> istio-ingressgateway:443 -> envoy-sidecar:8443
LB-IP:80 -> CLUSTER-IP:80 -> istio-ingressgateway:80 -> envoy-sidecar:8080

For example, for http if you check your ingress-gateway pod with netstat without any gateway configured there isn't anything listening on port 8080:

kubectl exec -ti istio-ingressgateway-86f88b6f6-r8mjt -n istio-system -c istio-proxy -- /bin/bash
istio-proxy@istio-ingressgateway-86f88b6f6-r8mjt:/$ netstat -lnt | grep 8080

Let's create a http gateway now with below yaml.

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: istio-gw
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

And check with netstat again:

kubectl exec -ti istio-ingressgateway-86f88b6f6-r8mjt -n istio-system -c istio-proxy -- /bin/bash
istio-proxy@istio-ingressgateway-86f88b6f6-r8mjt:/$ netstat -lnt | grep 8080
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN

As you can see we have configured gateway on port 80, but inside the ingressgateway we can see that it's listening on port 8080.

0
votes

I think this mechanism of istio is a bit confusing.
In my understanding, the port defined by the gateway should be the port of listen in the pod, and then the service decides the exposed port.
althouth the current mechanism is convenient for users, there will be some confusion and uncertainty.
If istio wants to keep this mechanism, I suggest istio to improve it. When creating a gateway, it is associated with ingress-svc instead of pod, and then the port is clearly defined as the port of svc. If the port does not exist in svc, update the service to open it Or prohibit the creation of the gateway