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服务端口时你会发现这些配置并没有生效。