kubernetes 在istio ingress-gateway中,Istio Proxy如何计算出所使用的服务端口?

c9qzyr3d  于 2022-11-02  发布在  Kubernetes
关注(0)|答案(2)|浏览(254)

我的问题与How are the various Istio Ports used?相关或有点相同,但我会尽量简化它。
假设我有以下istio操作符配置:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
...
spec:
...
  components:
...
    ingressGateways:
...
service:
          - port: 80
            targetPort: 8080
            nodePort: 30080 
            name: http2
            protocol: TCP

我有一个入口已经转发到端口80的流量。
我的问题是关于这里的目标端口,因此请求将通过例如端口80上的入口,它将通过节点nodePort、端口,然后是targetPort 8080,在那里它将到达入口控制器的Istio代理。
用于网状处理此请求的网关的正确配置是80而不是8080,如下所示:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
---
spec: 
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80

问题是,假设ingressgateway在端口8080上接收流量,它如何计算出所使用的服务端口最初是80?请注意,此示例工作正常,没有任何问题。
它是否像代理查询kube-api关于我接收请求的端口号的服务端口是什么,基于此将决定此请求属于哪个网关?

jhiyze9q

jhiyze9q1#

我的问题是关于这里的目标端口,因此请求将通过例如端口80上的入口,它将通过节点nodePort、端口,然后是targetPort 8080,在那里它将到达入口控制器的Istio代理。
将来自外部的传入请求路由到入口网关pod。端口和目标端口与入口网关服务和入口网关pod相关。请运行以下命令以检查入口网关服务

kubectl get svc istio-ingressgateway -n istio-system

问题是,假设ingressgateway在端口8080上接收流量,它如何计算出所使用的服务端口最初是80?请注意,此示例工作正常,没有任何问题。
当应用程序特定网关和虚拟服务对象与其中提到的特定主机一起创建时,其虚拟服务负责转发到达特定主机或网关端口的流量。有关gatewayvirtualservice的更多详细信息,请参阅其文档。

ddrv8njm

ddrv8njm2#

在回答您提到的问题时,我描述了kubernetes如何使用k8s.service定义在集群中设置路由。
你的问题更多地集中在istio部分,所以让我们在这里更深入地讨论这个部分,但是你可能想先读另一个答案。
因此,您向端口80发送一个请求,该请求在内部被路由到端口8080上的ingressgateway端口,但该请求仍然是“针对端口80”,因此您需要配置ingressgateway应用程序以监听该端口。
在vanilla minikube上安装istio之后,您可以通过运行istioctl pc all pod/istio-ingressgateway-<randomstring>.istio-system -o json > /tmp/init来获得ingressgateway pod的初始配置,并将其保存以供以后使用。
现在添加一个简单的Gateway,如

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gateway
  namespace: default
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "nginx.example.com"
EOF

再次获取配置stioctl pc all pod/istio-ingressgateway-<randomstring>.istio-system -o json > /tmp/with-gw,并将其与/tmp/init文件进行比较。
您将看到创建了一个侦听器,其地址为port_value 8080和默认的filter_chains(因为它很长,所以我将其删除),还有一个“黑洞”路由:

+      dynamic_listeners: [
+        {
+          name: "0.0.0.0_8080"
+          active_state: {
+            listener: {
+              @type: "type.googleapis.com/envoy.config.listener.v3.Listener"
+              name: "0.0.0.0_8080"
+              address: {
+                socket_address: {
+                  address: "0.0.0.0"
+                  port_value: 8080
+                }
+              }
[...]
+      dynamic_route_configs: [
+        {
+          route_config: {
+            @type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
+            name: "http.8080"
+            virtual_hosts: [
+              {
+                name: "blackhole:80"
+                domains: [
+                  "*"
+                ]
+              }
+            ]
+            validate_clusters: false
+          }
+        }
+      ]

现在添加一个VirtualService,并进行一些简单的配置,例如:

$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: vs-nginx
  namespace: default
spec:
  gateways:
  - gateway
  hosts:
  - "nginx.example.com"
  http:
  - match:
    - uri:
        prefix: /
    headers:
      response:
        add:
          My-Custom-Header1: "abc-123"
    route:
    - destination:
        port:
          number: 8080
        host: nginx-test.default.svc.cluster.local
EOF

获取配置istioctl pc all pod/istio-ingressgateway-<randomstring>.istio-system -o json > /tmp/with-vs,并再次与/tmp/with-gw文件进行diff比较。现在,route_config发生了变化,添加了到nginx-test.default.svc.cluster.local的路由(我的nginx应用程序在默认名称空间中运行的fqdn)、添加头的指令、重试策略和添加的域nginx.example.com

route_config: {
             virtual_hosts: [
               {
+                routes: [
+                  {
+                    match: {
+                      prefix: "/"
+                      case_sensitive: true
+                    }
+                    route: {
+                      cluster: "outbound|8080||nginx-test.default.svc.cluster.local"
+                      timeout: "0s"
+                      retry_policy: {
+                        retry_on: "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes"
+                        num_retries: 2
+                        retry_host_predicate: [
+                          {
+                            name: "envoy.retry_host_predicates.previous_hosts"
+                          }
+                        ]
+                        host_selection_retry_max_attempts: "5"
+                        retriable_status_codes: [
+                          503
+                        ]
+                      }
+                      max_stream_duration: {
+                        max_stream_duration: "0s"
+                        grpc_timeout_header_max: "0s"
+                      }
+                    }
+                    metadata: {
+                      filter_metadata: {
+                        istio: {
+                          config: "/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/vs-nginx"
+                        }
+                      }
+                    }
+                    decorator: {
+                      operation: "nginx-test.default.svc.cluster.local:8080/*"
+                    }
+                    response_headers_to_add: [
+                      {
+                        header: {
+                          key: "My-Custom-Header1"
+                          value: "abc-123"
+                        }
+                        append: true
+                      }
+                    ]
+                  }
+                ]
+                include_request_attempt_count: true
-                name: "blackhole:80"
+                name: "nginx.example.com:80"
                 domains: [
-                  "*"
+                  "nginx.example.com"
+                  "nginx.example.com:*"
                 ]
               }
             ]
           }
         }
       ]
     }

有关如何调试envoy配置的更多信息,请查看solo.io提供的youtube session

相关问题