<p>I have a hard time understand how exactly is the Istio Gateway port used. I am referring to line 14 in the below example</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gateway
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 8169
        name: http-test1
        protocol: HTTP
      hosts:
        - '*'
</code></pre>
<p>From the Istio documentation:</p>
<blockquote>
<p>The Port on which the proxy should listen for incoming connections. So
indeed if you apply the above yaml file and check the
istio-ingressgateway pod for listening TCP ports you will find that
the port 8169 is actually used (see below output)</p>
</blockquote>
<pre class="lang-sh prettyprint-override"><code>kubectl -n=istio-system exec istio-ingressgateway-8577c57fb6-p8zl5 -- ss -nl | grep 8169
tcp   LISTEN 0      4096               0.0.0.0:8169        0.0.0.0:*
</code></pre>
<p>But here comes the tricky part. If before you apply the Gateway you change the istio-ingressgateway service as follow:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata:
  name: istio-ingressgateway
...
  - name: http5
    nodePort: 31169
    port: 8169
    protocol: TCP
    targetPort: 8069
...
</code></pre>
<p>And then you apply the Gateway then the actual port used is not 8169 but 8069. It seems like that the Gateway resource will check first for a matching port in the istio-ingressgateway service and use the targetPort of the service instead</p>
<pre class="lang-sh prettyprint-override"><code>kubectl -n=istio-system exec istio-ingressgateway-8577c57fb6-p8zl5 -- ss -nl | grep 8169
&lt;empty result&gt;
kubectl -n=istio-system exec istio-ingressgateway-8577c57fb6-p8zl5 -- ss -nl | grep 8069
tcp   LISTEN 0      4096               0.0.0.0:8069        0.0.0.0:*
</code></pre>
<p>Can anybody explain why?
Thank you in advance for any help</p>

<p>You encountered an interesting aspect of Istio - how to configure Istio to expose a service outside of the service mesh using an Istio Gateway.</p>
<p>First of all, please note that the gateway configuration will be applied to the proxy running on a Pod (in your example on a Pod with labels  <code>istio: ingressgateway</code>). Istio is responsible for configuring the proxy to listen on these ports, however it is the user's responsibility to ensure that external traffic to these ports are allowed into the mesh.</p>
<p>Let me show you with an example. What you encountered is expected behaviour, because that is exactly how Istio works.</p>
<hr />
<p>First, I created a simple Gateway configuration (for the sake of simplicity I omit Virtual Service and Destination Rule configurations) like below:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 9091
      name: http-test-1
      protocol: HTTP
    hosts:
    - '*'
</code></pre>
<p>Then:</p>
<pre><code>    $ kubectl apply -f gw.yaml
    gateway.networking.istio.io/gateway created
</code></pre>
<p>Let's check if our proxy is listening on port <code>9091</code>. We can check it directly from the <code>istio-ingressgateway-*</code> pod or we can use the <code>istioctl proxy-config listener</code> command to retrieve information about listener configuration for the Envoy instance in the specified Pod:</p>
<pre><code>    $ kubectl exec istio-ingressgateway-8c48d875-lzsng -n istio-system -- ss -tulpn | grep 9091
    tcp     LISTEN   0        1024             0.0.0.0:9091           0.0.0.0:*      users:((&quot;envoy&quot;,pid=14,fd=35))
    
    $ istioctl proxy-config listener istio-ingressgateway-8c48d875-lzsng  -n istio-system
    ADDRESS PORT  MATCH DESTINATION
    0.0.0.0 9091  ALL   Route: http.9091
</code></pre>
<p>Exposing this port on the pod doesn't mean that we are able to reach it from the outside world, but it is possible to reach this port internally from another pod:</p>
<pre><code>    $ kubectl get pod -n istio-system -o wide
    NAME                                  READY   STATUS    RESTARTS   AGE   IP         
    istio-ingressgateway-8c48d875-lzsng   1/1     Running   0          43m   10.4.0.4
    
    $ kubectl exec -it test -- curl 10.4.0.4:9091
    &lt;!DOCTYPE html&gt;
    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;Welcome to nginx!&lt;/title&gt;
    ...
</code></pre>
<p>To make it accessible externally we need to expose this port on <code>istio-ingressgateway</code> Service:</p>
<pre><code>    ...
      ports:
      - name: http-test-1
        nodePort: 30017
        port: 9091
        protocol: TCP
        targetPort: 9091
    ...
</code></pre>
<p>After this modification, we can reach port <code>9091</code> from the outside world:</p>
<pre><code>    $ curl http://&lt;PUBLIC_IP&gt;:9091
    &lt;!DOCTYPE html&gt;
    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;Welcome to nginx!&lt;/title&gt;
    ...
</code></pre>
<p>Please note that nothing has changed from Pod's perspective:</p>
<pre><code>    $ kubectl exec istio-ingressgateway-8c48d875-lzsng -n istio-system -- ss -tulpn | grep 9091
    tcp     LISTEN   0        1024             0.0.0.0:9091           0.0.0.0:*      users:((&quot;envoy&quot;,pid=14,fd=35))
    
    $ istioctl proxy-config listener istio-ingressgateway-8c48d875-lzsng  -n istio-system
    ADDRESS PORT  MATCH DESTINATION
    0.0.0.0 9091  ALL   Route: http.9091
</code></pre>
<p>Now let's change the <code>targetPort: 9091</code> to <code>targetPort: 9092</code> in the <code>istio-ingressgateway</code> Service configuration and see what happens:</p>
<pre><code>    ...
      ports:
      - name: http-test-1
        nodePort: 30017
        port: 9091
        protocol: TCP
        targetPort: 9092   &lt;--- &quot;9091&quot; to &quot;9092&quot;
    ...
    
    $ kubectl exec istio-ingressgateway-8c48d875-lzsng -n istio-system -- ss -tulpn | grep 9091
    tcp     LISTEN   0        1024             0.0.0.0:9091           0.0.0.0:*      users:((&quot;envoy&quot;,pid=14,fd=35))
    
    $ istioctl proxy-config listener istio-ingressgateway-8c48d875-lzsng  -n istio-system
    ADDRESS PORT  MATCH DESTINATION
    0.0.0.0 9091  ALL   Route: http.9091
</code></pre>
<p>As you can see, it seems that nothing has changed from the Pod's perspective so far, but we also need to re-apply the Gateway configuration:</p>
<pre><code>    $ kubectl delete -f gw.yaml &amp;&amp; kubectl apply -f gw.yaml
    gateway.networking.istio.io &quot;gateway&quot; deleted
    gateway.networking.istio.io/gateway created
    
    $ kubectl exec istio-ingressgateway-8c48d875-lzsng -n istio-system -- ss -tulpn | grep 9092
    tcp     LISTEN   0        1024             0.0.0.0:9092           0.0.0.0:*      users:((&quot;envoy&quot;,pid=14,fd=35))
    
    $ istioctl proxy-config listener istio-ingressgateway-8c48d875-lzsng  -n istio-system
    ADDRESS PORT  MATCH DESTINATION
    0.0.0.0 9092  ALL   Route: http.9092
</code></pre>
<p>Our proxy is now listening on port <code>9092</code> (<code>targetPort</code>), but we can still reach port <code>9091</code> from the outisde as long as our Gateway specifies this port and it is open on the <code>istio-ingressgateway</code> Service.</p>
<pre><code>    $ kubectl describe gw gateway -n istio-system | grep -A 4 &quot;Port&quot;
        Port:
          Name:      http-test-1
          Number:    9091
          Protocol:  HTTP
          
    $ kubectl get svc -n istio-system -oyaml | grep -C 2 9091
        - name: http-test-1
          nodePort: 30017
          port: 9091
          protocol: TCP
          targetPort: 9092
          
    $ curl http://&lt;PUBLIC_IP&gt;:9091
    &lt;!DOCTYPE html&gt;
    &lt;html&gt;
    &lt;head&gt;
    &lt;title&gt;Welcome to nginx!&lt;/title&gt;
    ...
</code></pre>
