Search code examples
kubernetesistioenvoyproxy

How does the Gateway port definition work?


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?


Solution

  • 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.