2、Gateway和VirtualService原理分析
Gateway和VirtualService原理分析
目录
[toc]
本节实战
| 实战名称 |
|---|
分析 Gateway 和 VirtualService
前面我们创建了一个 Gateway 和 VirtualService 对象,用来对外暴露应用,然后我们就可以通过 ingressgateway 来访问 Bookinfo 应用了。那么这两个资源对象是如何实现的呢?
Gateway 资源是用来配置允许外部流量进入 Istio 服务网格的流量入口,用于接收传入的 HTTP/TCP 连接。它会配置暴露的端口、协议等,但与 Kubernetes Ingress 资源不同,不会包括任何流量路由配置,真正的路由规则是通过 VirtualService 来配置的。
🍀
我们再查看一下前面创建的 Gateway 对象的定义:
1# samples/bookinfo/networking/bookinfo-gateway.yaml
2apiVersion: networking.istio.io/v1alpha3
3kind: Gateway
4metadata:
5 name: bookinfo-gateway
6spec:
7 selector: # 如果使用的是 Helm 方式安装,则默认应该是 istio=ingress 标签
8 istio: ingressgateway # 匹配 ingress gateway pod 的标签(kubectl get pods -l istio=ingressgateway -n istio-system)
9 servers:
10 - port:
11 number: 8080
12 name: http
13 protocol: HTTP
14 hosts:
15 - "*"
这里定义的 Gateway 对象中有一个 selector 标签选择器,它会匹配 istio=ingressgateway 标签的 Pod,其实就是 istio-ingressgateway 这个组件。
1[root@master1 ~]#kubectl get po -nistio-system
2NAME READY STATUS RESTARTS AGE
3istio-egressgateway-8477dd44c4-jgpcg 1/1 Running 0 12h
4istio-ingressgateway-5c58fcb646-df7rz 1/1 Running 0 12h
5istiod-5d9595449c-8tt97 1/1 Running 0 12h
6[root@master1 ~]#kubectl get po -l istio=ingressgateway -nistio-system
7NAME READY STATUS RESTARTS AGE
8istio-ingressgateway-5c58fcb646-df7rz 1/1 Running 0 12h
1# samples/bookinfo/networking/bookinfo-gateway.yaml
2apiVersion: networking.istio.io/v1alpha3
3kind: Gateway
4metadata:
5 name: bookinfo-gateway
6spec:
7 selector: # 如果使用的是 Helm 方式安装,则默认应该是 istio=ingress 标签
8 istio: ingressgateway # 匹配 ingress gateway pod 的标签(kubectl get pods -l istio=ingressgateway -n istio-system)
9 servers:
10 - port:
11 number: 8080
12 name: http
13 protocol: HTTP
14 hosts:
15 - "*"
16---
17apiVersion: networking.istio.io/v1alpha3
18kind: VirtualService
19metadata:
20 name: bookinfo
21spec:
22 hosts:
23 - "*"
24 gateways:
25 - bookinfo-gateway
26 http:
27 - match:
28 - uri:
29 exact: /productpage
30 - uri:
31 prefix: /static
32 - uri:
33 exact: /login
34 - uri:
35 exact: /logout
36 - uri:
37 prefix: /api/v1/products
38 route:
39 - destination:
40 host: productpage
41 port:
42 number: 9080
🍀

其实本质上 istio-ingressgateway 也是一个 Envoy 代理,用来作为 Istio 的统一入口网关,它会接收外部流量,然后根据 VirtualService 中定义的路由规则来进行流量的转发。
我们可以查看下 istio-ingressgateway 的 Envoy 配置来验证下:
1# 进入 ingressgateway 组件所在的 Pod 中
2$ kubectl exec -it istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -- /bin/bash
3istio-proxy@istio-ingressgateway-9c8b9b586-s6s48:/$ ll /etc/istio/proxy
4total 20
5drwxrwsrwx 2 root istio-proxy 66 Nov 3 02:16 ./
6drwxr-xr-x 7 root root 103 Nov 3 02:16 ../
7srw-rw-rw- 1 istio-proxy istio-proxy 0 Nov 3 02:16 XDS=
8-rw-r--r-- 1 istio-proxy istio-proxy 14130 Nov 3 02:16 envoy-rev.json
9-rw-r--r-- 1 istio-proxy istio-proxy 2699 Nov 3 02:16 grpc-bootstrap.json
10istio-proxy@istio-ingressgateway-9c8b9b586-s6s48:/$
在 istio-ingressgateway 组件的 Pod 目录中有一个配置文件 envoy-rev.json,这个文件就是 Envoy 的配置文件,但是由于这里采用的是 xDS 动态配置的方式,所以直接看不到前面我们添加的 Gateway 相关信息的。



静态的2个配置:
1.数据采集
2.监控检查


1[root@master1 ~]#kubectl get po -nistio-system -owide
2NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3grafana-86b7d46c86-zphx2 1/1 Running 0 4h38m 10.244.2.15 node1 <none> <none>
4istio-egressgateway-8477dd44c4-jgpcg 1/1 Running 0 18h 10.244.1.18 node2 <none> <none>
5istio-ingressgateway-5c58fcb646-df7rz 1/1 Running 0 18h 10.244.1.19 node2 <none> <none>
6istiod-5d9595449c-8tt97 1/1 Running 0 18h 10.244.1.17 node2 <none> <none>
7jaeger-594658fc5b-789s6 1/1 Running 0 4h38m 10.244.2.16 node1 <none> <none>
8kiali-6ff88d695b-2rwtk 1/1 Running 0 4h38m 10.244.1.25 node2 <none> <none>
9prometheus-67599c8d5c-gdhv9 2/2 Running 0 4h38m 10.244.2.17 node1 <none> <none>
10[root@master1 ~]#curl 10.244.1.19:15090/stats/prometheus
11……
12# TYPE envoy_server_initialization_time_ms histogram
13envoy_server_initialization_time_ms_bucket{le="0.5"} 0
14envoy_server_initialization_time_ms_bucket{le="1"} 0
15envoy_server_initialization_time_ms_bucket{le="5"} 0
16envoy_server_initialization_time_ms_bucket{le="10"} 0
17envoy_server_initialization_time_ms_bucket{le="25"} 0
18envoy_server_initialization_time_ms_bucket{le="50"} 0
19envoy_server_initialization_time_ms_bucket{le="100"} 0
20envoy_server_initialization_time_ms_bucket{le="250"} 1
21envoy_server_initialization_time_ms_bucket{le="500"} 1
22envoy_server_initialization_time_ms_bucket{le="1000"} 1
23envoy_server_initialization_time_ms_bucket{le="2500"} 1
24envoy_server_initialization_time_ms_bucket{le="5000"} 1
25envoy_server_initialization_time_ms_bucket{le="10000"} 1
26envoy_server_initialization_time_ms_bucket{le="30000"} 1
27envoy_server_initialization_time_ms_bucket{le="60000"} 1
28envoy_server_initialization_time_ms_bucket{le="300000"} 1
29envoy_server_initialization_time_ms_bucket{le="600000"} 1
30envoy_server_initialization_time_ms_bucket{le="1800000"} 1
31envoy_server_initialization_time_ms_bucket{le="3600000"} 1
32envoy_server_initialization_time_ms_bucket{le="+Inf"} 1
33envoy_server_initialization_time_ms_sum{} 125
34envoy_server_initialization_time_ms_count{} 1
35[root@master1 ~]#


1[root@master1 ~]#curl 10.244.1.19:15021/healthz/ready
2[root@master1 ~]#curl 10.244.1.19:15021/healthz/ready
3[root@master1 ~]#
4
5[root@master1 ~]#kubectl get deploy istio-ingressgateway -nistio-system -oyaml
6……
7readinessProbe:
8 failureThreshold: 30
9 httpGet:
10 path: /healthz/ready
11 port: 15021
12 scheme: HTTP
13 initialDelaySeconds: 1
14 periodSeconds: 2
15 successThreshold: 1
16 timeoutSeconds: 1
这2个就对的上了:



🍀
但是我们可以利用 Envoy 的 Admin 提供的 config_dump 来查看下配置文件:
1kubectl exec istio-ingressgateway-9c8b9b586-s6s48 -c istio-proxy -n istio-system -- curl 'localhost:15000/config_dump' > ingressgateway_envoy_conf.json

istio envoy 默认配置为 json 格式,导出来的配置文件非常长(==有 10000+行==),我们可以先只看上层内容:

我们可以看到这个配置文件中其实就一个 configs 数组,每个元素都是一项配置,每个配置都指定了一个独特的 @type 字段,来指定该配置是是干嘛的。接下来我们就来看下这个配置文件中的每个配置项都是干嘛的。
BootStrapConfigDump

用于在 Envoy 启动时加载的一些静态配置,包括类似 Sidecar 的环境变量等信息。
我们也可以使用 istioctl proxy-config bootstrap 命令来查看这部分配置:
1$ istioctl proxy-config bootstrap istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yaml
2bootstrap:
3 admin:
4 address:
5 socketAddress:
6 address: 127.0.0.1
7 portValue: 15000
8 profilePath: /var/lib/istio/data/envoy.prof
9 dynamicResources: # 动态配置发现服务信息
10 adsConfig:
11 apiType: GRPC
12 grpcServices:
13 - envoyGrpc:
14 clusterName: xds-grpc
15 setNodeOnFirstMessageOnly: true
16 transportApiVersion: V3
17 cdsConfig:
18 ads: {}
19 initialFetchTimeout: 0s
20 resourceApiVersion: V3
21 ldsConfig:
22 ads: {}
23 initialFetchTimeout: 0s
24 resourceApiVersion: V3
25 node: # 节点信息
26 cluster: istio-ingressgateway.istio-system
27 id: router~10.244.2.52~istio-ingressgateway-9c8b9b586-s6s48.istio-system~istio-system.svc.cluster.local
28 # ......
29 staticResources:
30 clusters:
31 - connectTimeout: 0.250s # prometheus cluster
32 loadAssignment:
33 clusterName: prometheus_stats
34 endpoints:
35 - lbEndpoints:
36 - endpoint:
37 address:
38 socketAddress:
39 address: 127.0.0.1
40 portValue: 15000
41 name: prometheus_stats
42 type: STATIC
43 - connectTimeout: 0.250s # agent cluster
44 loadAssignment:
45 clusterName: agent
46 endpoints:
47 - lbEndpoints:
48 - endpoint:
49 address:
50 socketAddress:
51 address: 127.0.0.1
52 portValue: 15020
53 name: agent
54 type: STATIC
55 - connectTimeout: 1s
56 loadAssignment:
57 clusterName: sds-grpc
58 endpoints:
59 - lbEndpoints:
60 - endpoint:
61 address:
62 pipe:
63 path: ./var/run/secrets/workload-spiffe-uds/socket
64 name: sds-grpc
65 type: STATIC
66 typedExtensionProtocolOptions:
67 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
68 '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
69 explicitHttpConfig:
70 http2ProtocolOptions: {}
71 - circuitBreakers:
72 thresholds:
73 - maxConnections: 100000
74 maxPendingRequests: 100000
75 maxRequests: 100000
76 - maxConnections: 100000
77 maxPendingRequests: 100000
78 maxRequests: 100000
79 priority: HIGH
80 connectTimeout: 1s
81 loadAssignment: # xds-grpc cluster
82 clusterName: xds-grpc
83 endpoints:
84 - lbEndpoints:
85 - endpoint:
86 address:
87 pipe:
88 path: ./etc/istio/proxy/XDS
89 maxRequestsPerConnection: 1
90 name: xds-grpc
91 type: STATIC
92 typedExtensionProtocolOptions:
93 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
94 '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
95 explicitHttpConfig:
96 http2ProtocolOptions: {}
97 upstreamConnectionOptions:
98 tcpKeepalive:
99 keepaliveTime: 300
100 - connectTimeout: 1s
101 dnsLookupFamily: V4_ONLY
102 dnsRefreshRate: 30s
103 loadAssignment: # zipkin cluster
104 clusterName: zipkin
105 endpoints:
106 - lbEndpoints:
107 - endpoint:
108 address:
109 socketAddress:
110 address: zipkin.istio-system
111 portValue: 9411
112 name: zipkin
113 respectDnsTtl: true
114 type: STRICT_DNS
115 listeners:
116 - address:
117 socketAddress:
118 address: 0.0.0.0
119 portValue: 15090 # prometheus listener
120 filterChains:
121 - filters:
122 - name: envoy.filters.network.http_connection_manager
123 typedConfig:
124 '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
125 httpFilters:
126 - name: envoy.filters.http.router
127 typedConfig:
128 '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
129 routeConfig:
130 virtualHosts:
131 - domains:
132 - '*'
133 name: backend
134 routes:
135 - match:
136 prefix: /stats/prometheus
137 route:
138 cluster: prometheus_stats
139 statPrefix: stats
140 - address:
141 socketAddress:
142 address: 0.0.0.0
143 portValue: 15021 # agent listener(健康检查)
144 filterChains:
145 - filters:
146 - name: envoy.filters.network.http_connection_manager
147 typedConfig:
148 '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
149 httpFilters:
150 - name: envoy.filters.http.router
151 typedConfig:
152 '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
153 routeConfig:
154 virtualHosts:
155 - domains:
156 - '*'
157 name: backend
158 routes:
159 - match:
160 prefix: /healthz/ready
161 route:
162 cluster: agent
163 statPrefix: agent
164 statsConfig:
165 # ......
166 tracing: # 链路追踪
167 http:
168 name: envoy.tracers.zipkin
169 typedConfig:
170 '@type': type.googleapis.com/envoy.config.trace.v3.ZipkinConfig
171 collectorCluster: zipkin
172 collectorEndpoint: /api/v2/spans
173 collectorEndpointVersion: HTTP_JSON
174 sharedSpanContext: false
175 traceId128bit: true
上面的配置和之前我们介绍的 Envoy 配置基本一致,在上面配置中定义了一个 Prometheus 监听器,用来暴露 Prometheus 监控指标,还定义了一个 Agent 监听器,用来暴露健康检查接口,另外还定义了一个 zipkin 集群,用来定义链路追踪的配置。另外通过 dynamicResources 定义了动态配置发现服务信息,xds-grpc 就是用来定义 Envoy 与 Pilot 之间的 xDS 通信的。
ListenersConfigDump
这里存储着 Envoy 的 listeners 配置,也就是 Envoy 的监听器。Envoy 在拦截到请求后,会根据请求的地址与端口,将请求交给匹配的 listener 处理。
我们看到这个 ListenersConfigDump 中的 listener 配置分成了 static_listners 和 dynamic_listeners,分别对应 Envoy 的静态配置和动态配置,静态配置,是 Envoy 配置文件中直接指定的,而 dynamic_listeners的 listener 则是 istiod 通过 xDS 协议为 Envoy 下发的。
同样我们也可以使用 istioctl proxy-config listener 命令来查看这部分配置:
1istioctl proxy-config listener istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yaml
对应的配置文件如下所示:
1- accessLog:
2 - filter:
3 responseFlagFilter:
4 flags:
5 - NR
6 name: envoy.access_loggers.file
7 typedConfig:
8 "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
9 logFormat:
10 textFormatSource:
11 inlineString: |
12 [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS% "%UPSTREAM_TRANSPORT_FAILURE_REASON%" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" %UPSTREAM_CLUSTER% %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% %REQUESTED_SERVER_NAME% %ROUTE_NAME%
13 path: /dev/stdout
14 address:
15 socketAddress:
16 address: 0.0.0.0
17 portValue: 8080
18 continueOnListenerFiltersTimeout: true
19 filterChains:
20 - filters:
21 - name: istio_authn
22 typedConfig:
23 "@type": type.googleapis.com/udpa.type.v1.TypedStruct
24 typeUrl: type.googleapis.com/io.istio.network.authn.Config
25 - name: envoy.filters.network.http_connection_manager
26 typedConfig:
27 "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
28 accessLog:
29 - name: envoy.access_loggers.file
30 typedConfig:
31 "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
32 logFormat:
33 textFormatSource:
34 inlineString: |
35 [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS% "%UPSTREAM_TRANSPORT_FAILURE_REASON%" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" %UPSTREAM_CLUSTER% %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% %REQUESTED_SERVER_NAME% %ROUTE_NAME%
36 path: /dev/stdout
37 forwardClientCertDetails: SANITIZE_SET
38 httpFilters:
39 - name: istio.metadata_exchange
40 typedConfig:
41 "@type": type.googleapis.com/udpa.type.v1.TypedStruct
42 typeUrl: type.googleapis.com/io.istio.http.peer_metadata.Config
43 value:
44 upstream_discovery:
45 - istio_headers: {}
46 - workload_discovery: {}
47 upstream_propagation:
48 - istio_headers: {}
49 - name: envoy.filters.http.grpc_stats
50 typedConfig:
51 "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig
52 emitFilterState: true
53 statsForAllMethods: false
54 - name: istio.alpn
55 typedConfig:
56 "@type": type.googleapis.com/istio.envoy.config.filter.http.alpn.v2alpha1.FilterConfig
57 alpnOverride:
58 - alpnOverride:
59 - istio-http/1.0
60 - istio
61 - http/1.0
62 - alpnOverride:
63 - istio-http/1.1
64 - istio
65 - http/1.1
66 upstreamProtocol: HTTP11
67 - alpnOverride:
68 - istio-h2
69 - istio
70 - h2
71 upstreamProtocol: HTTP2
72 - name: envoy.filters.http.fault
73 typedConfig:
74 "@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault
75 - name: envoy.filters.http.cors
76 typedConfig:
77 "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
78 - name: istio.stats
79 typedConfig:
80 "@type": type.googleapis.com/stats.PluginConfig
81 disableHostHeaderFallback: true
82 - name: envoy.filters.http.router
83 typedConfig:
84 "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
85 httpProtocolOptions: {}
86 normalizePath: true
87 pathWithEscapedSlashesAction: KEEP_UNCHANGED
88 rds:
89 configSource:
90 ads: {}
91 initialFetchTimeout: 0s
92 resourceApiVersion: V3
93 routeConfigName: http.8080
94 requestIdExtension:k
95 typedConfig:
96 "@type": type.googleapis.com/envoy.extensions.request_id.uuid.v3.UuidRequestIdConfig
97 useRequestIdForTraceSampling: true
98 serverName: istio-envoy
99 setCurrentClientCertDetails:
100 cert: true
101 dns: true
102 subject: true
103 uri: true
104 statPrefix: outbound_0.0.0.0_8080
105 streamIdleTimeout: 0s
106 tracing:
107 # ......
108 upgradeConfigs:
109 - upgradeType: websocket
110 useRemoteAddress: true
111 name: 0.0.0.0_8080
112 trafficDirection: OUTBOUND
113- address:
114 socketAddress:
115 address: 0.0.0.0
116 portValue: 15090
117 # ......
118- address:
119 socketAddress:
120 address: 0.0.0.0
121 portValue: 15021
122 # ......
虽然上面看到的 listener 配置还是很长,但是我们应该也还是非常熟悉的,本质就是 Envoy 的配置文件中的 listener 配置。我们这里重点看下动态配置对应的配置,静态的就是前面指定 prometheus 和 agent 对应的监听器配置。
我们可以看到上面的动态配置对应的监听器名称为 0.0.0.0_8080,对应的监听地址为 0.0.0.0:8080,也就是说在 Envoy 中监听了 8080 端口:
1address:
2 socketAddress:
3 address: 0.0.0.0
4 portValue: 8080

而前面我们是不是创建了一个 Gateway 资源对象,并指定了 8080 端口,其实这个端口就是我们前面创建的 Gateway 对象中定义的端口,这个监听器的配置就是通过 istiod 通过 xDS 协议下发的。
那么请求是如何到达这个监听器的呢?我们可以查看下 istio-ingressgateway 组建的 Service 数据:
1$ kubectl get svc istio-ingressgateway -n istio-system
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3istio-ingressgateway LoadBalancer 10.103.227.57 <pending> 15021:32459/TCP,80:31896/TCP,443:30808/TCP,31400:31535/TCP,15443:30761/TCP 46h
我们可以看到 istio-ingressgateway 组件的 Service 中定义了 5 个端口,还记得前面我们去访问 Productpage 的时候是如何访问的吗?是不是通过 http://$GATEWAY_URL/productpage 访问的,而我们这里没有 LoadBalancer,所以直接使用 NodePort 形式访问就行,最终我们是通过 http://NodeIP:31896/productpage 来访问应用的,而这个 31896 端口对应 istio-ingressgateway 组件的 Service 中定义的 80 端口,也就是说我们的请求是通过 80 端口到达 istio-ingressgateway 组件的,那么这个 80 端口是如何到达 istio-ingressgateway 组件的呢?
1$ kubectl describe svc istio-ingressgateway -n istio-system
2Name: istio-ingressgateway
3Namespace: istio-system
4# ......
5Port: http2 80/TCP
6TargetPort: 8080/TCP
7NodePort: http2 31896/TCP
8Endpoints: 10.244.2.52:8080
我们查看 Service 的定义就明白了,实际上 istio-ingressgateway 这个 Service 定义的 80 端口对应的是 istio-ingressgateway 组件 Pod 的 8080 端口,也就是说我们的请求是通过 80 端口到达 istio-ingressgateway 组件的 8080 端口的,而这个 8080 端口就是我们前面在 Envoy 配置中看到的监听器的端口了,所以当我们访问 http://$GATEWAY_URL/productpage 的时候请求到达了 istio-ingressgateway 这个组件的 8080 端口了。
当请求到达 istio-ingressgateway 组件时,就会被这个监听器所匹配,然后将请求交给 http_connection_manager 这个 filter 来处理,当然后面就是用各种具体的 filter 来处理请求了,比如 envoy.filters.http.fault 这个 filter 就是用来处理故障注入的,envoy.filters.http.router 则是用来处理路由转发的、envoy.filters.http.cors 则是用来处理跨域请求的等等。
但是我们的请求进到 Envoy 后是又该如何路由呢?我应该将请求转发到哪里去呢?这个是不是就是 Envoy 中的路由配置来决定的了,对于静态配置我们清楚直接在 Envoy 配置文件中就可以看到,比如:
1routeConfig:
2 virtualHosts:
3 - domains:
4 - "*"
5 name: backend
6 routes:
7 - match:
8 prefix: /healthz/ready
9 route:
10 cluster: agent
但是我们这里的路由配置是动态配置的,我们看到对应的配置中有一个 rds 字段,这个字段就是用来指定动态路由配置的,其中的 routeConfigName 字段就是用来指定对应的路由配置名称的:
1rds:
2 configSource:
3 ads: {}
4 initialFetchTimeout: 0s
5 resourceApiVersion: V3
6 routeConfigName: http.8080
RoutesConfigDump

这里面保存着 Envoy 的路由配置,和 listeners 一样,RoutesConfigDump 也分为 static_route_configs 和 dynamic_route_configs,分别对应着静态的路由配置和动态下发的路由配置。
同样我们也可以使用 istioctl proxy-config route 命令来查看这部分配置:
1istioctl proxy-config route istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yaml
对应的配置如下所示:
1- ignorePortInHostMatching: true
2 maxDirectResponseBodySizeBytes: 1048576
3 name: http.8080
4 validateClusters: false
5 virtualHosts:
6 - domains:
7 - "*"
8 includeRequestAttemptCount: true
9 name: "*:8080"
10 routes:
11 - decorator:
12 operation: productpage.default.svc.cluster.local:9080/productpage
13 match:
14 caseSensitive: true
15 path: /productpage
16 metadata:
17 filterMetadata:
18 istio:
19 config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo
20 route:
21 cluster: outbound|9080||productpage.default.svc.cluster.local
22 maxGrpcTimeout: 0s
23 retryPolicy:
24 hostSelectionRetryMaxAttempts: "5"
25 numRetries: 2
26 retriableStatusCodes:
27 - 503
28 retryHostPredicate:
29 - name: envoy.retry_host_predicates.previous_hosts
30 typedConfig:
31 "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
32 retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes
33 timeout: 0s
34 - decorator:
35 operation: productpage.default.svc.cluster.local:9080/static*
36 match:
37 caseSensitive: true
38 prefix: /static
39 metadata:
40 filterMetadata:
41 istio:
42 config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo
43 route:
44 cluster: outbound|9080||productpage.default.svc.cluster.local
45 maxGrpcTimeout: 0s
46 retryPolicy:
47 hostSelectionRetryMaxAttempts: "5"
48 numRetries: 2
49 retriableStatusCodes:
50 - 503
51 retryHostPredicate:
52 - name: envoy.retry_host_predicates.previous_hosts
53 typedConfig:
54 "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
55 retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes
56 timeout: 0s
57 - decorator:
58 operation: productpage.default.svc.cluster.local:9080/login
59 match:
60 caseSensitive: true
61 path: /login
62 metadata:
63 filterMetadata:
64 istio:
65 config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo
66 route:
67 cluster: outbound|9080||productpage.default.svc.cluster.local
68 maxGrpcTimeout: 0s
69 retryPolicy:
70 hostSelectionRetryMaxAttempts: "5"
71 numRetries: 2
72 retriableStatusCodes:
73 - 503
74 retryHostPredicate:
75 - name: envoy.retry_host_predicates.previous_hosts
76 typedConfig:
77 "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
78 retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes
79 timeout: 0s
80 - decorator:
81 operation: productpage.default.svc.cluster.local:9080/logout
82 match:
83 caseSensitive: true
84 path: /logout
85 metadata:
86 filterMetadata:
87 istio:
88 config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo
89 route:
90 cluster: outbound|9080||productpage.default.svc.cluster.local
91 maxGrpcTimeout: 0s
92 retryPolicy:
93 hostSelectionRetryMaxAttempts: "5"
94 numRetries: 2
95 retriableStatusCodes:
96 - 503
97 retryHostPredicate:
98 - name: envoy.retry_host_predicates.previous_hosts
99 typedConfig:
100 "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
101 retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes
102 timeout: 0s
103 - decorator:
104 operation: productpage.default.svc.cluster.local:9080/api/v1/products*
105 match:
106 caseSensitive: true
107 prefix: /api/v1/products
108 metadata:
109 filterMetadata:
110 istio:
111 config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo
112 route:
113 cluster: outbound|9080||productpage.default.svc.cluster.local
114 maxGrpcTimeout: 0s
115 retryPolicy:
116 hostSelectionRetryMaxAttempts: "5"
117 numRetries: 2
118 retriableStatusCodes:
119 - 503
120 retryHostPredicate:
121 - name: envoy.retry_host_predicates.previous_hosts
122 typedConfig:
123 "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
124 retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes
125 timeout: 0s
126- virtualHosts:
127 - domains:
128 - "*"
129 name: backend
130 routes:
131 - match:
132 prefix: /stats/prometheus
133 route:
134 cluster: prometheus_stats
135- virtualHosts:
136 - domains:
137 - "*"
138 name: backend
139 routes:
140 - match:
141 prefix: /healthz/ready
142 route:
143 cluster: agent
后面的两个 virtualHosts 就是我们的静态路由配置,第一个是动态的路由配置,我们可以看到该配置的名称就是 http.8080,是不是和前面的 routeConfigName 是一致的。那么这个配置又是什么地方定义的呢?
其实仔细看这里面的配置和前面我们创建的 VirtualService 这个资源对象是不是很像,我们再看下前面创建的 VirtualService 对象的定义:
1apiVersion: networking.istio.io/v1alpha3
2kind: VirtualService
3metadata:
4 name: bookinfo
5spec:
6 hosts:
7 - "*"
8 gateways:
9 - bookinfo-gateway
10 http:
11 - match:
12 - uri:
13 exact: /productpage
14 - uri:
15 prefix: /static
16 - uri:
17 exact: /login
18 - uri:
19 exact: /logout
20 - uri:
21 prefix: /api/v1/products
22 route:
23 - destination:
24 host: productpage
25 port:
26 number: 9080
我们可以看到在 VirtualService 对象中定义了 5 个路由规则,而这里的 RoutesConfigDump 中也定义了 5 个路由规则,VirtualService 中定义的 5 个路由分别为 /productpage、/static、/login、/logout、/api/v1/products,而 RoutesConfigDump 中定义的 5 个路由分别为 /productpage、/static、/login、/logout、/api/v1/products,是不是一一对应的。最终匹配这些路由规则的请求是被转发到 productpage 这个服务的 9080 端口的。
比如 /productpage 这个路由规则对应的 Envoy 配置如下所示:
1- domains:
2 - "*"
3 includeRequestAttemptCount: true
4 name: "*:8080"
5 routes:
6 - decorator:
7 operation: productpage.default.svc.cluster.local:9080/productpage
8 match:
9 caseSensitive: true
10 path: /productpage
11 metadata:
12 filterMetadata:
13 istio:
14 config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo
15 route:
16 cluster: outbound|9080||productpage.default.svc.cluster.local
17 maxGrpcTimeout: 0s
18 retryPolicy:
19 hostSelectionRetryMaxAttempts: "5"
20 numRetries: 2
21 retriableStatusCodes:
22 - 503
23 retryHostPredicate:
24 - name: envoy.retry_host_predicates.previous_hosts
25 typedConfig:
26 "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate
27 retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes
28 timeout: 0s
这个配置就是我们熟悉的 Envoy 的关于虚拟主机部分的配置,比如当我们请求的路径为 /productpage 时,就会被这个路由规则匹配到,然后就用通过 route 字段来描述我们的路由目标了,针对这个目录,可以看到有一些类似于 retry_policy、timeout等字段来配置这个目标的超时、重试策略等,不过最重要的还是 cluster 这个字段,它指定了这个路由目标对应着哪个上游集群,Envoy 最终将请求发送到这个 Cluster,比如我们这里的集群名称为 outbound|9080||productpage.default.svc.cluster.local,关于其具体配置我们就要去查看 ClustersConfigDump 中的配置了。
ClustersConfigDump

该部分是用来存储 Envoy 的集群配置的,同样也分为 static_clusters 和 dynamic_active_clusters,分别对应着静态配置和动态下发的配置。这里的 Cluster 集群是 Envoy 内部的概念,它是指 Envoy 连接的一组逻辑相同的上游主机,并不是说 K8s 集群,只是大多数情况下我们可以把这个集群理解为 K8s 集群中的一个 Service,一个 Service 通常对应着一组 Pod,由这组 Pod 响应请求并提供同一种服务,而 Envoy 的这个集群实际可以理解成这种Pod 集合。不过 Envoy 的一个集群也不一定就对应着一个 Service,因为集群是一组逻辑相同的上游主机,所以也有可能是别的符合定义的东西,比如说是服务的一个特定版本(如只是 v2 版本的 reviews 服务)。istio 的版本灰度能力就是基于这个做的,因为两个版本的同一服务实际上可以分成两个集群。
同样我们可以使用 istioctl proxy-config cluster 命令来查看这部分配置:
1istioctl proxy-config cluster istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yaml
该配置文件会非常长,它会将 K8s 集群中的 Service 都转换成 Envoy 的 Cluster,这里我们只看下 productpage 这个服务对应的 Cluster 配置,如下所示:
1- circuitBreakers: #
2 thresholds:
3 - maxConnections: 4294967295
4 maxPendingRequests: 4294967295
5 maxRequests: 4294967295
6 maxRetries: 4294967295
7 trackRemaining: true
8 commonLbConfig:
9 localityWeightedLbConfig: {}
10 connectTimeout: 10s
11 edsClusterConfig:
12 edsConfig:
13 ads: {}
14 initialFetchTimeout: 0s
15 resourceApiVersion: V3
16 serviceName: outbound|9080||productpage.default.svc.cluster.local
17 filters:
18 - name: istio.metadata_exchange
19 typedConfig:
20 "@type": type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange
21 protocol: istio-peer-exchange
22 lbPolicy: LEAST_REQUEST
23 metadata:
24 filterMetadata:
25 istio:
26 services:
27 - host: productpage.default.svc.cluster.local
28 name: productpage
29 namespace: default
30 name: outbound|9080||productpage.default.svc.cluster.local
31 transportSocketMatches:
32 - match:
33 tlsMode: istio
34 name: tlsMode-istio
35 transportSocket:
36 name: envoy.transport_sockets.tls
37 typedConfig:
38 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
39 commonTlsContext:
40 alpnProtocols:
41 - istio-peer-exchange
42 - istio
43 combinedValidationContext:
44 defaultValidationContext:
45 matchSubjectAltNames:
46 - exact: spiffe://cluster.local/ns/default/sa/bookinfo-productpage
47 validationContextSdsSecretConfig:
48 name: ROOTCA
49 sdsConfig:
50 apiConfigSource:
51 apiType: GRPC
52 grpcServices:
53 - envoyGrpc:
54 clusterName: sds-grpc
55 setNodeOnFirstMessageOnly: true
56 transportApiVersion: V3
57 initialFetchTimeout: 0s
58 resourceApiVersion: V3
59 tlsCertificateSdsSecretConfigs:
60 - name: default
61 sdsConfig:
62 apiConfigSource:
63 apiType: GRPC
64 grpcServices:
65 - envoyGrpc:
66 clusterName: sds-grpc
67 setNodeOnFirstMessageOnly: true
68 transportApiVersion: V3
69 initialFetchTimeout: 0s
70 resourceApiVersion: V3
71 tlsParams:
72 tlsMaximumProtocolVersion: TLSv1_3
73 tlsMinimumProtocolVersion: TLSv1_2
74 sni: outbound_.9080_._.productpage.default.svc.cluster.local
75 - match: {}
76 name: tlsMode-disabled
77 transportSocket:
78 name: envoy.transport_sockets.raw_buffer
79 typedConfig:
80 "@type": type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer
81 type: EDS
我们可以看到这个 Envoy Cluster 的名称为 outbound|9080||productpage.default.svc.cluster.local,和前面的路由配置中的 cluster 字段是一致的,名称大多数会由 | 分成四个部分,分别是 inbound 或 outbound 代表入向流量或出向流量、端口号、subcluster 名称(就是对应着 destination rule 里的 subset)、Service FQDN,由 istio 的服务发现进行配置,通过这个 name 我们很容易就能看出来这个集群对应的是 K8s 集群的哪个服务。
然后配置的负载均衡策略是 LEAST_REQUEST,另外比较重要的这里的配置的类型为 type: EDS,也就是会通过 EDS 来发现上游的主机服务,这个 EDS 的配置如下所示:
1edsClusterConfig:
2 edsConfig:
3 ads: {}
4 initialFetchTimeout: 0s
5 resourceApiVersion: V3
6 serviceName: outbound|9080||productpage.default.svc.cluster.local
基于 EDS 去动态发现上游主机的配置,其实在前面的 Envoy 章节我们已经介绍过了,和这里是不是几乎是一致的,serviceName 其实就对应着 K8s 集群中的 productpage 这个 Service 对象的 9080 端口,而这个 Service 对象对应着一组 Pod,这组 Pod 就是我们的上游主机了。当然这是通过 xDS 协议下发的,我们可以通过 istioctl proxy-config endpoint 命令来查看这部分配置:
1istioctl proxy-config endpoint istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yaml
该部分数据非常多,下面只截取 productpage 相关的数据,如下所示:
1- addedViaApi: true
2 circuitBreakers:
3 thresholds:
4 - maxConnections: 4294967295
5 maxPendingRequests: 4294967295
6 maxRequests: 4294967295
7 maxRetries: 4294967295
8 - maxConnections: 1024
9 maxPendingRequests: 1024
10 maxRequests: 1024
11 maxRetries: 3
12 priority: HIGH
13 edsServiceName: outbound|9080||productpage.default.svc.cluster.local
14 hostStatuses:
15 - address:
16 socketAddress:
17 address: 10.244.2.62
18 portValue: 9080
19 healthStatus:
20 edsHealthStatus: HEALTHY
21 locality: {}
22 stats:
23 - name: cx_connect_fail
24 - name: cx_total
25 value: "1"
26 - name: rq_error
27 - name: rq_success
28 value: "4"
29 - name: rq_timeout
30 - name: rq_total
31 value: "4"
32 - name: cx_active
33 type: GAUGE
34 - name: rq_active
35 type: GAUGE
36 weight: 1
37 name: outbound|9080||productpage.default.svc.cluster.local
38 observabilityName: outbound|9080||productpage.default.svc.cluster.local
可以看到上面的配置中就包含一个真正的后端服务地址:
1address:
2 socketAddress:
3 address: 10.244.2.62
4 portValue: 9080
这个地址其实就是 productpage 这个 K8s Service 关联的 Pod 的地址。这样一个请求从进入到 Envoy 到最终转发到后端服务的过程就清楚了。
SecretsConfigDump
由于网格中的 Envoy 之间互相通信会使用 mTLS 模式,因此每个 Envoy 通信时都需要提供本工作负载的证书,同时为了签发证书还需要 istio ca 的根证书,这些证书的信息保存在该配置项之下。
可视化
到这里我们就把 Envoy 的整个配置文件都理解了一遍,它们分别是 Bootstrap、Listeners、Routes、Clusters、Secrets 几个配置,其中又涉及到 VirtualHost 等细分概念。总体来看,一个典型的 HTTP 请求在 Envoy 内部经历了以下事情:

整体上一个请求在 Envoy 内部的处理与转发过程中,listener、route、cluster 这几个配置是环环相扣的,它们通过配置的 name 一层又一层地向下引用(listener 内的 filter 引用 route、route 内的 virtual_host 引用 cluster),形成了一条引用链,最终将请求从 listener 递交到具体的 cluster。

🍀
我们可以使用 envoyui.solo.io 这个在线的 Envoy 配置可视化工具来查看 Envoy 的配置,只需要将我们的 Envoy 配置 dump 出来上传上来即可:

经过上面的分析我们也明白了其实 Istio 并没有实现很多复杂的逻辑,服务治理相关的功能比如负载均衡、故障注入、权重路由等都是 Envoy 本身就有的能力,Istio 只是将这些能力抽象成了一个个资源对象,然后通过 Envoy 的 xDS 协议下发到 Envoy 中,这样就能够实现对 Envoy 的流量治理了。所以重点还是需要我们先理解 Envoy 的配置,然后再去理解 Istio 的配置,这样才能更好的理解 Istio,不然你就不清楚 Gateway、VirtualService 等这些资源对象到底是干什么的,它们是如何影响 Envoy 的配置的。
当然我们这里还只是分析的 Istio Ingress Gateway 的配置,而对于 Sidecar 模式的 Envoy 代理又是如何去配置的呢?它又是如何将 Pod 的流量进行拦截的呢?这些我们后面会继续分析。
自定义一个端口访问应用
==🚩 实战:自定义一个端口访问应用-2023.11.6(测试成功)==
实验环境:
1k8s v1.25.4(containerd://1.6.10)
2
3[root@master1 ~]#istioctl version
4client version: 1.19.3
5control plane version: 1.19.3
6data plane version: 1.19.3 (8 proxies)
实验软件:
链接:https://pan.baidu.com/s/1o-GJF88QKWP4WG-FT278Nw?pwd=4pxr
提取码:4pxr
–来自百度网盘超级会员V8的分享
2023.11.6-实战:自定义一个端口访问应用-2023.11.6(测试成功)

实验步骤:
1graph LR
2 A[实战步骤] -->B(1️⃣ 创建Gateway和VirtualService资源)
3 A[实战步骤] -->C(2️⃣ 创建svc)
4 A[实战步骤] -->D(3️⃣ 测试)

🍀
业务默认端口:

1[root@master1 ~]#kubectl get po -nistio-system
2NAME READY STATUS RESTARTS AGE
3grafana-86b7d46c86-zphx2 1/1 Running 0 20h
4istio-egressgateway-8477dd44c4-jgpcg 1/1 Running 0 33h
5istio-ingressgateway-5c58fcb646-df7rz 1/1 Running 0 33h
6istiod-5d9595449c-8tt97 1/1 Running 0 33h
7jaeger-594658fc5b-789s6 1/1 Running 0 20h
8kiali-6ff88d695b-2rwtk 1/1 Running 0 20h
9prometheus-67599c8d5c-gdhv9 2/2 Running 0 20h
10
11
12[root@master1 ~]#kubectl get svc -nistio-system
13NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
14grafana ClusterIP 10.96.218.2 <none> 3000/TCP 20h
15istio-egressgateway ClusterIP 10.96.171.120 <none> 80/TCP,443/TCP 33h
16istio-ingressgateway LoadBalancer 10.104.174.171 <pending> 15021:32479/TCP,80:31814/TCP,443:31263/TCP,31400:32543/TCP,15443:30806/TCP 33h
17istiod ClusterIP 10.110.112.56 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 33h
18jaeger-collector ClusterIP 10.103.124.73 <none> 14268/TCP,14250/TCP,9411/TCP,4317/TCP,4318/TCP 20h
19kiali ClusterIP 10.110.11.151 <none> 20001/TCP,9090/TCP 20h
20loki-headless ClusterIP None <none> 3100/TCP 20h
21prometheus ClusterIP 10.107.255.204 <none> 9090/TCP 20h
22tracing ClusterIP 10.110.109.99 <none> 80/TCP,16685/TCP 20h
23zipkin ClusterIP 10.103.145.97 <none> 9411/TCP 20h
我们通过http://172.29.9.61:31814/productpage 来访问

1svc:80 --> nodeport
2envoy ingress gateway: 8080监听器
3
4[root@master1 istio-1.19.3]#cat samples/bookinfo/networking/bookinfo-gateway.yaml
5apiVersion: networking.istio.io/v1alpha3
6kind: Gateway
7metadata:
8 name: bookinfo-gateway
9spec:
10 # The selector matches the ingress gateway pod labels.
11 # If you installed Istio using Helm following the standard documentation, this would be "istio=ingress"
12 selector:
13 istio: ingressgateway # use istio default controller
14 servers:
15 - port:
16 number: 8080 #监听器
17 name: http
18 protocol: HTTP
19 hosts:
20 - "*"
21---
22apiVersion: networking.istio.io/v1alpha3
23kind: VirtualService
24metadata:
25 name: bookinfo
26spec:
27 hosts:
28 - "*"
29 gateways:
30 - bookinfo-gateway
31 http:
32 - match:
33 - uri:
34 exact: /productpage
35 - uri:
36 prefix: /static
37 - uri:
38 exact: /login
39 - uri:
40 exact: /logout
41 - uri:
42 prefix: /api/v1/products
43 route:
44 - destination:
45 host: productpage #svc
46 port:
47 number: 9080
48[root@master1 istio-1.19.3]#
49
50
51
52#svc
53apiVersion: v1
54 33 kind: Service
55 34 metadata:
56 35 name: details
57 36 labels:
58 37 app: details
59 38 service: details
60 39 spec:
61 40 ports:
62 41 - port: 9080
63 42 name: http
64 43 selector:
65 44 app: details
66
67#
68[root@master1 istio-1.19.3]#kubectl get svc istio-ingressgateway -n istio-system -oyaml
69 - name: http2
70 nodePort: 31814
71 port: 80
72 protocol: TCP
73 targetPort: 8080
🍀
现在自己想创建一个新的svc,8088来作为访问应用的入口,该如何配置呢?
🍀
开始配置
1[root@master1 istio-1.19.3]#cp samples/bookinfo/networking/bookinfo-gateway.yaml test-gateway.yaml
2
3[root@master1 istio-1.19.3]#cat test-gateway.yaml
4apiVersion: networking.istio.io/v1alpha3
5kind: Gateway
6metadata:
7 name: test-gateway
8spec:
9 # The selector matches the ingress gateway pod labels.
10 # If you installed Istio using Helm following the standard documentation, this would be "istio=ingress"
11 selector:
12 istio: ingressgateway # use istio default controller
13 servers:
14 - port:
15 number: 8080
16 name: http
17 protocol: HTTP
18 hosts:
19 - "*"
20---
21apiVersion: networking.istio.io/v1alpha3
22kind: VirtualService
23metadata:
24 name: test
25spec:
26 hosts:
27 - "*"
28 gateways:
29 - test-gateway
30 http:
31 - match:
32 - uri:
33 exact: /productpage
34 - uri:
35 prefix: /static
36 - uri:
37 exact: /login
38 - uri:
39 exact: /logout
40 - uri:
41 prefix: /api/v1/products
42 route:
43 - destination:
44 host: productpage
45 port:
46 number: 9080
47---

部署:
1[root@master1 istio-1.19.3]#kubectl apply -f test-gateway.yaml
2gateway.networking.istio.io/test-gateway created
3virtualservice.networking.istio.io/test created
可以直接edit这个istio-ingressgateway,或者新创建一个svc也行的。

这里新创建一个svc:
1[root@master1 istio-1.19.3]#kubectl apply -f test-gateway.yaml
2
3
4[root@master1 istio-1.19.3]#cat test-gateway.yaml
5apiVersion: v1
6kind: Service
7metadata:
8 labels:
9 app: istio-ingressgateway
10 install.operator.istio.io/owning-resource: installed-state
11 install.operator.istio.io/owning-resource-namespace: istio-system
12 istio: ingressgateway
13 istio.io/rev: default
14 operator.istio.io/component: IngressGateways
15 operator.istio.io/managed: Reconcile
16 operator.istio.io/version: 1.19.3
17 release: istio
18 name: test-gatewy
19 namespace: istio-system
20spec:
21 ports:
22 - name: test-port
23 nodePort: 30080
24 port: 8088
25 protocol: TCP
26 targetPort: 8088
27 selector:
28 app: istio-ingressgateway
29 istio: ingressgateway
30 type: LoadBalancer
31[root@master1 istio-1.19.3]#

验证:
1[root@master1 istio-1.19.3]#kubectl get svc -nistio-system
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3grafana ClusterIP 10.96.218.2 <none> 3000/TCP 20h
4istio-egressgateway ClusterIP 10.96.171.120 <none> 80/TCP,443/TCP 33h
5istio-ingressgateway LoadBalancer 10.104.174.171 <pending> 15021:32479/TCP,80:31814/TCP,443:31263/TCP,31400:32543/TCP,15443:30806/TCP 33h
6istiod ClusterIP 10.110.112.56 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 33h
7jaeger-collector ClusterIP 10.103.124.73 <none> 14268/TCP,14250/TCP,9411/TCP,4317/TCP,4318/TCP 20h
8kiali ClusterIP 10.110.11.151 <none> 20001/TCP,9090/TCP 20h
9loki-headless ClusterIP None <none> 3100/TCP 20h
10prometheus ClusterIP 10.107.255.204 <none> 9090/TCP 20h
11test-gatewy LoadBalancer 10.101.92.232 <pending> 8088:30080/TCP 42s
12tracing ClusterIP 10.110.109.99 <none> 80/TCP,16685/TCP 20h
13zipkin ClusterIP 10.103.145.97 <none> 9411/TCP 20h
14[root@master1 istio-1.19.3]#
同样也是可以访问的:
http://172.29.9.61:30080/productpage

测试结束。😘

