istio 1.6.3
Gateway资源中定义的port和协议定义了在ingressgateway(envoy)中的listener port及协议处理。
但是,Gateway中的port可以填写为 ingressgateway 对应svc中的定义的port或者targetPort,最终在envoy里配置的是targetPort。
例如,Gateway中定义port为443:
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  | 
						apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata:   namespace: istio-bookinfo   name: bookinfo-gateway spec:   selector:     istio: ingressgateway # use istio default controller   servers:   - port:       number: 8080         name: http       protocol: HTTP      hosts:     - "*"   - port:       number: 443 #####用于envoy中listener所关联的route的名称里       name: https #####用于envoy中listener所关联的route的名称里       protocol: HTTPS #####用于envoy中listener所关联的route的名称里     tls:       mode: SIMPLE       serverCertificate: /etc/istio/ingressgateway-certs/tls.crt       privateKey: /etc/istio/ingressgateway-certs/tls.key     hosts:     - "*"  | 
					
而实际envoy中产生的配置是8443:
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  | 
						[root@k8s-master-v1-16 networking]# istioctl proxy-config listener istio-ingressgateway-7b869dcfb5-lfqz9.istio-system --port 8443 -o json [     {         "name": "0.0.0.0_8443",         "address": {             "socketAddress": {                 "address": "0.0.0.0",                 "portValue": 8443 《《《《《8443!!             }         },         "filterChains": [             {                 "filters": [                     {                         "name": "envoy.http_connection_manager",                         "typedConfig": {                             "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager",                             "statPrefix": "outbound_0.0.0.0_8443",                             "rds": {                                 "configSource": {                                     "ads": {}                                 }, ###route name用的是443####                                 "routeConfigName": "https.443.https.bookinfo-gateway.istio-bookinfo"                             },  | 
					
这是因为在ingressgateway的svc中定义了 svc 443 对应targetPort 8443
| 
					 1 2 3 4 5  | 
						  - name: https     nodePort: 30975     port: 443     protocol: TCP     targetPort: 8443  | 
					
如果在gateway中如果定义port为8443,效果也是在envoy中产生8443的listener。
但需要特别注意,在只有一个gateway定义时候,写svc的por或者写对应的targetport都所谓,而如果是多个gateway定义,且定义的都是相同的协议,那么gateway中的端口就必须写一致,否则listener只会关联后创建的gateway所产生的routeConfigName,而后创建的这个route里不会包含先创建的virtualservice逻辑。
例如,在istio-bookinfo namespace里的gateway里配置 HTTP:8080 (ingressgateway的svc 80对应到pod的8080)
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  | 
						[root@k8s-master-v1-16 httpbin]# kubectl get gateways.networking.istio.io -n istio-bookinfo  -o yaml apiVersion: v1 items:   spec:     selector:       istio: ingressgateway     servers:     - hosts:       - '*'       port:         name: http         number: 8080         protocol: HTTP     - hosts:       - istiobookinfo.lab.f5se.io       port:         name: https         number: 443         protocol: HTTPS  | 
					
而httpbin namespace里的gateway配置 HTTP:80
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14  | 
						[root@k8s-master-v1-16 httpbin]# kubectl get gateways.networking.istio.io -n httpbin -o yaml apiVersion: v1 items:   spec:     selector:       istio: ingressgateway     servers:     - hosts:       - httpbin.lab.f5se.io       port:         name: http-httpbin         number: 80         protocol: HTTP  | 
					
这导致envoy listener最终实际关联的是后创建的http.80 这个route(原来的http.8080覆盖了):
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  | 
						[root@k8s-master-v1-16 ~]# istioctl proxy-config listener istio-ingressgateway-7b869dcfb5-gh2vr.istio-system --port 8080 -o json [     {         "name": "0.0.0.0_8080",         "address": {             "socketAddress": {                 "address": "0.0.0.0",                 "portValue": 8080             }         },         "filterChains": [             {                 "filters": [                     {                         "name": "envoy.http_connection_manager",                         "typedConfig": {                             "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager",                             "statPrefix": "outbound_0.0.0.0_8080",                             "rds": {                                 "configSource": {                                     "ads": {}                                 },                                 "routeConfigName": "http.80"  | 
					
所以,在这种最终是共用listener 端口的gateway配置里,端口号以及协议名需要相同(最好就都直接用envoy实际监听的端口号),但port的命名必须不同(port name相同的话,envoy日志会显示冲突的配置)。
| 
					 1 2  | 
						2020-07-10T09:56:26.192152Z	warning	envoy config	[external/envoy/source/common/config/grpc_subscription_impl.cc:101] gRPC config for type.googleapis.com/envoy.api.v2.Listener rejected:  Error adding/updating listener(s) 0.0.0.0_8080: duplicate listener 0.0.0.0_8080 found  | 
					
相同协议相同端口的gateway,无论是否在同一个namespace中,在envoy只能共用一个listener,因此也会共用一个route,这个route里再做7层区分。 如果此时不小心在不同的namespace下配置了相同的virtualservice,将会导致envoy在同一个route中产生两个相同的match条件(而关联的cluster是不同namespace后缀的,从而导致访问异常)
                
文章评论
ok
谢谢博主
来了来了
谢谢分享
感谢分享
一直在疑惑 Istio gateway 资源中的这个 port 到底有什么意义。 因为当你添加多个 gateway 时并绑定多个 不相同的 http服务端口时你会发现这些配置并没有生效。