Skip to main 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
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

istioctl proxy-config listener podname.namespace
dev
ADDRESSES PORT  MATCH                    DESTINATION
0.0.0.0   8080  ALL                      Route: http.8080
0.0.0.0   8443  SNI: one.test.example.com Route: https.443.https.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||code-pilot-ssh.one-sit.svc.cluster.local
0.0.0.0   30005 ALL                      Cluster: outbound|2222||code-pilot-ssh.pipe-dev.svc.cluster.local
0.0.0.0   30006 ALL                      Cluster: outbound|2222||code-pilot-ssh.pipe-uat.svc.cluster.local
0.0.0.0   32234 ALL                      Cluster: outbound|2222||code-pilot-ssh.sit.svc.cluster.local
0.0.0.0   33333 ALL                      Route: http.33333

Enter ingressgateway pod, show port listening.

netstat -tul
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
http-alt   8080/tcp    webcache    # WWW caching service

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

netstat -tuln

istioctl 1.6.5

Get LDS

istioctl proxy-config listener podname.namespace
tomato
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
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