1

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?

Chaos
  • 471
  • 4
  • 20

2 Answers2

2

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.

Jakub
  • 8,189
  • 1
  • 17
  • 31
  • As I pointed out though, the service targetPort is `8443` so how would the LB properly point to 443 on the ingress gateway pod? – Chaos Nov 23 '20 at 13:40
  • @Chaos There is a [comment](https://github.com/istio/istio/issues/24204#issuecomment-636008476) about that from istio dev john howard, port is used to make it externally visible and targetPort is used internally to avoid root. When the lb is created by any cloud it uses port, targetPort is the port on which the service will send requests to, that your pod will be listening on. So your request goes with lb:443, a service with port:443 and targetport:8443 to ingress-gateway-pod which listen on 8443, because there is envoy sidecar inside. That's how I understand it. – Jakub Nov 23 '20 at 16:21
  • 1
    Thanks @Jakub that's interesting. I wonder how it knows that requests on 8443 for example are actually from 443 then as in the Gateway definition. If you know how that works that would be appreciated but I'll mark your answer as correct regardless. – Chaos Nov 24 '20 at 00:41
  • 1
    AFAIK that's how it's configured with iptables. Something like this workaround [here](https://github.com/istio/istio/issues/24204#issuecomment-635997600). Take a look at [this](https://hackernoon.com/k8-istio-deep-dive-c0773a204e82) and [this](https://jpittis.ca/posts/tricking-istio-with-iptables.html) article about that. – Jakub Nov 24 '20 at 08:27
0

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

Jackie
  • 11
  • 1
  • Hello and welcome to SO! Please read the [tour](https://stackoverflow.com/tour), and [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer) Usually code snippets are really helpful. – Tomer Shetah Dec 31 '20 at 09:08