Skip to content

Ingress Gateway Routing

When traffic goes into the istio-ingressgateway, how does the pod know which Gateway it should use to route the traffic?

Match Gateway

  1. Envoy is the real gateway

    • The Istio IngressGateway is a pod running Envoy proxy.
    • It is configured by Istio control plane (istiod) with a set of Gateway and VirtualService resources.
  2. Gateway objects define listeners

    • A Gateway object in Istio defines:
      • selector: Which gateway pod(s) it applies to (via label selector)
      • servers: Which ports and protocols the gateway listens to (e.g., port 80 or 443)
      • hosts: Which domains (e.g., example.com, *.foo.com) it should serve
  3. When traffic comes in:

    • Envoy receives the request at a certain port (e.g., 80 or 443).
    • It examines the Host header of the request (e.g., Host: example.com).
  4. Matching logic:

    • Istio matches the incoming request to a Gateway based on:
      • Port number (must match one defined in gateway.spec.servers.port)
      • Host header (must match one of the gateway.spec.servers.hosts)
    • Once a matching Gateway is found, Istio continues to match the request against VirtualService objects that refer to this Gateway.
  5. VirtualService routing

    • The matched VirtualService defines:
      • Matching paths/headers/etc.
      • Where to route the traffic (e.g., to a Kubernetes service in the mesh)
Gateway Example
yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: my-gateway
spec:
  selector:
    istio: ingressgateway  # matches the ingressgateway pod
  servers:
  - port:
      number: 80      # matches the ingressgateway port
      name: http      # only an identifier
      protocol: HTTP
    hosts:
    - "example.com"

Envoy xDS

Dynamic Port Listener

TIP

Istio ingressgateway Pod 中监听的端口是由 istiod 根据 gateway 的端口配置动态生成的

istiod will turn the Gateway to envoy configuration(LDS, RDS, ...)

  • LDS(Listener Discovery Service):定义 Envoy 监听的端口和协议
  • CDS(Cluster Discovery Service):定义目标服务的集群信息
  • EDS(Endpoint Discovery Service):定义目标服务的具体 Endpoint
  • RDS(Route Discovery Service):定义路由规则,将流量转发到指定的后端服务

Target Port Not Exist

Question

为什么 istio svc 有 targetPort: 80,但在 deployment 中没有 containerPort: 80。

在 Istio 中,ingressgateway(本质上就是一个运行了 Envoy 的容器)会:

  • 通过 Envoy 配置监听多个端口(包括 80, 443, 39000, 39001 等)。
  • 这些端口是在 istiod 给 ingressgateway 下发的配置中指定的。
  • 虽然在 Deployment 里的 containerPort 没有写出这些端口,但 Envoy 确实通过内部配置监听了它们。

所以即使 Deployment 看不到 containerPort: 80,只要 Envoy 在运行并监听了 80 端口,Kubernetes 的 Service 也能把请求通过 targetPort: 80 送到容器中。

Listen to A New Port

  • Add a new port in Gateway
  • Expose the new port in ingressgateway service.
  • Check LDS by istioctl proxy-config listener
  • Check port by netstat -tuln

istioctl 1.19.8

Get LDS

bash
istioctl proxy-config listener podname.namespace
dev
bash
ADDRESSES PORT  MATCH                    DESTINATION
0.0.0.0   8080  ALL                      Route: http.8080
0.0.0.0   8443  SNI: one.test.foobar.work Route: https.443.https.foobar-gateway.one-test
0.0.0.0   15021 ALL                      Inline Route: /healthz/ready*
0.0.0.0   15090 ALL                      Inline Route: /stats/prometheus*
0.0.0.0   30004 ALL                      Cluster: outbound|2222||foobar-code-pilot-ssh.one-sit.svc.cluster.local
0.0.0.0   30005 ALL                      Cluster: outbound|2222||foobar-code-pilot-ssh.pipe-dev.svc.cluster.local
0.0.0.0   30006 ALL                      Cluster: outbound|2222||foobar-code-pilot-ssh.pipe-uat.svc.cluster.local
0.0.0.0   32234 ALL                      Cluster: outbound|2222||foobar-code-pilot-ssh.sit.svc.cluster.local
0.0.0.0   33333 ALL                      Route: http.33333

Enter ingressgateway pod, show port listening.

bash
netstat -tul
bash
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:15021           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:15021           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:http-alt        0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:http-alt        0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:30004           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:30004           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:33333           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:33333           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:30005           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:30005           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:30006           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:30006           0.0.0.0:*               LISTEN
tcp        0      0 localhost:15000         0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN
tcp        0      0 localhost:15004         0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:32234           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:32234           0.0.0.0:*               LISTEN
tcp6       0      0 [::]:15020              [::]:*                  LISTEN

http-alt is 8080

[/etc/services]

/etc/services 是一个文本文件,用于将常用的网络端口号映射为服务名称。 这个文件由操作系统或网络工具(如 netstat, ss, lsof, nmap 等)用来把数字端口显示成更人类可读的名字。

grep http-alt /etc/services
bash
http-alt   8080/tcp    webcache    # WWW caching service

Use -tuln to show numeric ports(no alias names)

bash
netstat -tuln

istioctl 1.6.5

Get LDS

bash
istioctl proxy-config listener podname.namespace
tomato
bash
ADDRESS     PORT      TYPE
0.0.0.0     39002     HTTP
0.0.0.0     80        HTTP
0.0.0.0     5503      TCP
0.0.0.0     443       HTTP
0.0.0.0     39000     HTTP
0.0.0.0     15090     HTTP
0.0.0.0     15021     HTTP
bash
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:15021           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:39000           0.0.0.0:*               LISTEN
tcp        0      0 localhost:15000         0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:39002           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:5503            0.0.0.0:*               LISTEN
tcp6       0      0 [::]:15020              [::]:*                  LISTEN