1

我很难理解 Istio 网关端口是如何使用的。我指的是下面示例中的第 14 行

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gateway
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 8169
        name: http-test1
        protocol: HTTP
      hosts:
        - '*'

从 Istio 文档中:

代理应侦听传入连接的端口。所以确实,如果你应用上面的 yaml 文件并检查 istio-ingressgateway pod 以监听 TCP 端口,你会发现端口 8169 实际被使用(见下面的输出)

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:*

但棘手的部分来了。如果在应用网关之前,您将 istio-ingressgateway 服务更改如下:

apiVersion: v1
kind: Service
metadata:
  name: istio-ingressgateway
...
  - name: http5
    nodePort: 31169
    port: 8169
    protocol: TCP
    targetPort: 8069
...

然后你应用网关,然后实际使用的端口不是 8169 而是 8069。似乎网关资源将首先检查 istio-ingressgateway 服务中的匹配端口,然后使用服务的 targetPort

kubectl -n=istio-system exec istio-ingressgateway-8577c57fb6-p8zl5 -- ss -nl | grep 8169
<empty result>
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:*

谁能解释为什么?预先感谢您的任何帮助

4

2 回答 2

1

您遇到了 Istio 的一个有趣方面 - 如何配置 Istio 以使用 Istio 网关在服务网格之外公开服务。

首先,请注意网关配置将应用于运行在 Pod 上的代理(在您的示例中是在带有标签的 Pod 上 istio: ingressgateway)。Istio 负责配置代理以侦听这些端口,但用户有责任确保允许到这些端口的外部流量进入网格。

让我举个例子。您遇到的是预期行为,因为这正是 Istio 的工作方式。


首先,我创建了一个简单的网关配置(为简单起见,我省略了虚拟服务和目标规则配置),如下所示:

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:
    - '*'

然后:

    $ kubectl apply -f gw.yaml
    gateway.networking.istio.io/gateway created

让我们检查一下我们的代理是否正在监听端口9091。我们可以直接从istio-ingressgateway-*pod 中检查它,也可以使用istioctl proxy-config listener命令检索指定 Pod 中 Envoy 实例的侦听器配置信息:

    $ 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:(("envoy",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

在 pod 上暴露这个端口并不意味着我们可以从外部访问它,但是可以从另一个 pod 内部访问这个端口:

    $ 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
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    ...

为了使它可以从外部访问,我们需要在istio-ingressgatewayService 上公开这个端口:

    ...
      ports:
      - name: http-test-1
        nodePort: 30017
        port: 9091
        protocol: TCP
        targetPort: 9091
    ...

修改后,我们就可以9091从外界到达端口了:

    $ curl http://<PUBLIC_IP>:9091
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    ...

请注意,从 Pod 的角度来看,没有任何变化:

    $ 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:(("envoy",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

现在让我们将 Service 配置中的targetPort: 9091to更改为,看看会发生什么:targetPort: 9092istio-ingressgateway

    ...
      ports:
      - name: http-test-1
        nodePort: 30017
        port: 9091
        protocol: TCP
        targetPort: 9092   <--- "9091" to "9092"
    ...
    
    $ 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:(("envoy",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

如您所见,到目前为止,从 Pod 的角度来看似乎没有任何变化,但我们还需要重新应用网关配置:

    $ kubectl delete -f gw.yaml && kubectl apply -f gw.yaml
    gateway.networking.istio.io "gateway" 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:(("envoy",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

我们的代理现在正在侦听端口9092( ),但只要我们的网关指定此端口并且它在服务上打开targetPort,我们仍然可以从外部访问端口。9091istio-ingressgateway

    $ kubectl describe gw gateway -n istio-system | grep -A 4 "Port"
        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://<PUBLIC_IP>:9091
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    ...
于 2021-12-31T10:33:32.647 回答
0

据我所知,网关是虚拟的,您可以定义多个网关并公开不同的端口。但是,这些端口仍然需要在istio-ingressgateway

因此,当您手动更改实际的端口配置时ingressgateway,在应用它后只有该特定端口是打开的是有意义的。您正在检查虚拟网关上的开放端口,ingressgateway而不是虚拟网关上的开放端口。

另外,我认为不鼓励直接编辑istio-ingressgateway服务。如果要自定义,ingressgateway可以定义IstioOperator并将其应用于安装 Istio。

于 2021-12-29T18:01:15.243 回答