日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Istio Envoy 配置解讀,看這篇就夠了

來源: 責編: 時間:2023-11-07 09:14:12 331觀看
導讀前面我們創建了一個 Gateway 和 VirtualService 對象,用來對外暴露應用,然后我們就可以通過 ingressgateway 來訪問 Bookinfo 應用了。那么這兩個資源對象是如何實現的呢?Gateway 資源是用來配置允許外部流量進入 Istio

WDX28資訊網——每日最新資訊28at.com

前面我們創建了一個 Gateway 和 VirtualService 對象,用來對外暴露應用,然后我們就可以通過 ingressgateway 來訪問 Bookinfo 應用了。那么這兩個資源對象是如何實現的呢?WDX28資訊網——每日最新資訊28at.com

Gateway 資源是用來配置允許外部流量進入 Istio 服務網格的流量入口,用于接收傳入的 HTTP/TCP 連接。它會配置暴露的端口、協議等,但與 Kubernetes Ingress 資源不同,不會包括任何流量路由配置,真正的路由規則是通過 VirtualService 來配置的。WDX28資訊網——每日最新資訊28at.com

我們再查看一下前面創建的 Gateway 對象的定義:WDX28資訊網——每日最新資訊28at.com

# samples/bookinfo/networking/bookinfo-gateway.yamlapiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:  name: bookinfo-gatewayspec:  selector: # 如果使用的是 Helm 方式安裝,則默認應該是 istio=ingress 標簽    istio: ingressgateway # 匹配 ingress gateway pod 的標簽(kubectl get pods -l istio=ingressgateway -n istio-system)  servers:    - port:        number: 8080        name: http        protocol: HTTP      hosts:        - "*"

這里定義的 Gateway 對象中有一個 selector 標簽選擇器,它會匹配 istio=ingressgateway 標簽的 Pod,其實就是 istio-ingressgateway 這個組件。WDX28資訊網——每日最新資訊28at.com

WDX28資訊網——每日最新資訊28at.com

WDX28資訊網——每日最新資訊28at.com

其實本質上 istio-ingressgateway 也是一個 Envoy 代理,用來作為 Istio 的統一入口網關,它會接收外部流量,然后根據 VirtualService 中定義的路由規則來進行流量的轉發。WDX28資訊網——每日最新資訊28at.com

我們可以查看下 istio-ingressgateway 的 Envoy 配置來驗證下:WDX28資訊網——每日最新資訊28at.com

# 進入 ingressgateway 組件所在的 Pod 中$ kubectl exec -it istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -- /bin/bashistio-proxy@istio-ingressgateway-9c8b9b586-s6s48:/$ ll /etc/istio/proxytotal 20drwxrwsrwx 2 root        istio-proxy    66 Nov  3 02:16 ./drwxr-xr-x 7 root        root          103 Nov  3 02:16 ../srw-rw-rw- 1 istio-proxy istio-proxy     0 Nov  3 02:16 XDS=-rw-r--r-- 1 istio-proxy istio-proxy 14130 Nov  3 02:16 envoy-rev.json-rw-r--r-- 1 istio-proxy istio-proxy  2699 Nov  3 02:16 grpc-bootstrap.jsonistio-proxy@istio-ingressgateway-9c8b9b586-s6s48:/$

在 istio-ingressgateway 組件的 Pod 目錄中有一個配置文件 envoy-rev.json,這個文件就是 Envoy 的配置文件,該文件通過 istio 為 sidecar 注入的參數在啟動的時候修改或生成,由于這里采用的是 xDS 動態配置的方式,所以直接看不到前面我們添加的 Gateway 相關信息的,但是我們可以利用 Envoy 的 Admin 提供的 config_dump 來查看下配置文件:WDX28資訊網——每日最新資訊28at.com

kubectl exec istio-ingressgateway-9c8b9b586-s6s48 -c istio-proxy -n istio-system  -- curl 'localhost:15000/config_dump' > ingressgateway_envoy_conf.json

istio envoy 默認配置為 json 格式,導出來的配置文件非常長(有 10000+行),我們可以先只看上層內容:WDX28資訊網——每日最新資訊28at.com

WDX28資訊網——每日最新資訊28at.com

istio envoy 配置WDX28資訊網——每日最新資訊28at.com

我們可以看到這個配置文件中其實就一個 configs 數組,每個元素都是一項配置,每個配置都指定了一個獨特的 @type 字段,來指定該配置是是干嘛的。接下來我們就來看下這個配置文件中的每個配置項都是干嘛的。WDX28資訊網——每日最新資訊28at.com

BootStrapConfigDump

用于在 Envoy 啟動時加載的一些靜態配置,包括類似 Sidecar 的環境變量等信息。我們也可以使用 istioctl proxy-config bootstrap 命令來查看這部分配置:WDX28資訊網——每日最新資訊28at.com

$ istioctl proxy-config bootstrap istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yamlbootstrap:  admin:    address:      socketAddress:        address: 127.0.0.1        portValue: 15000    profilePath: /var/lib/istio/data/envoy.prof  dynamicResources:  # 動態配置發現服務信息    adsConfig:      apiType: GRPC      grpcServices:      - envoyGrpc:          clusterName: xds-grpc      setNodeOnFirstMessageOnly: true      transportApiVersion: V3    cdsConfig:      ads: {}      initialFetchTimeout: 0s      resourceApiVersion: V3    ldsConfig:      ads: {}      initialFetchTimeout: 0s      resourceApiVersion: V3  node:  # 節點信息    cluster: istio-ingressgateway.istio-system    id: router~10.244.2.52~istio-ingressgateway-9c8b9b586-s6s48.istio-system~istio-system.svc.cluster.local    # ......  staticResources:    clusters:    - connectTimeout: 0.250s  # prometheus cluster      loadAssignment:        clusterName: prometheus_stats        endpoints:        - lbEndpoints:          - endpoint:              address:                socketAddress:                  address: 127.0.0.1                  portValue: 15000      name: prometheus_stats      type: STATIC    - connectTimeout: 0.250s  # agent cluster      loadAssignment:        clusterName: agent        endpoints:        - lbEndpoints:          - endpoint:              address:                socketAddress:                  address: 127.0.0.1                  portValue: 15020      name: agent      type: STATIC    - connectTimeout: 1s      loadAssignment:        clusterName: sds-grpc        endpoints:        - lbEndpoints:          - endpoint:              address:                pipe:                  path: ./var/run/secrets/workload-spiffe-uds/socket      name: sds-grpc      type: STATIC      typedExtensionProtocolOptions:        envoy.extensions.upstreams.http.v3.HttpProtocolOptions:          '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions          explicitHttpConfig:            http2ProtocolOptions: {}    - circuitBreakers:        thresholds:        - maxConnections: 100000          maxPendingRequests: 100000          maxRequests: 100000        - maxConnections: 100000          maxPendingRequests: 100000          maxRequests: 100000          priority: HIGH      connectTimeout: 1s      loadAssignment:  # xds-grpc cluster        clusterName: xds-grpc        endpoints:        - lbEndpoints:          - endpoint:              address:                pipe:                  path: ./etc/istio/proxy/XDS      maxRequestsPerConnection: 1      name: xds-grpc      type: STATIC      typedExtensionProtocolOptions:        envoy.extensions.upstreams.http.v3.HttpProtocolOptions:          '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions          explicitHttpConfig:            http2ProtocolOptions: {}      upstreamConnectionOptions:        tcpKeepalive:          keepaliveTime: 300    - connectTimeout: 1s      dnsLookupFamily: V4_ONLY      dnsRefreshRate: 30s      loadAssignment:  # zipkin cluster        clusterName: zipkin        endpoints:        - lbEndpoints:          - endpoint:              address:                socketAddress:                  address: zipkin.istio-system                  portValue: 9411      name: zipkin      respectDnsTtl: true      type: STRICT_DNS    listeners:    - address:        socketAddress:          address: 0.0.0.0          portValue: 15090  # prometheus listener      filterChains:      - filters:        - name: envoy.filterswork.http_connection_manager          typedConfig:            '@type': type.googleapis.com/envoy.extensions.filterswork.http_connection_manager.v3.HttpConnectionManager            httpFilters:            - name: envoy.filters.http.router              typedConfig:                '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router            routeConfig:              virtualHosts:              - domains:                - '*'                name: backend                routes:                - match:                    prefix: /stats/prometheus                  route:                    cluster: prometheus_stats            statPrefix: stats    - address:        socketAddress:          address: 0.0.0.0          portValue: 15021  # agent listener(健康檢查)      filterChains:      - filters:        - name: envoy.filterswork.http_connection_manager          typedConfig:            '@type': type.googleapis.com/envoy.extensions.filterswork.http_connection_manager.v3.HttpConnectionManager            httpFilters:            - name: envoy.filters.http.router              typedConfig:                '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router            routeConfig:              virtualHosts:              - domains:                - '*'                name: backend                routes:                - match:                    prefix: /healthz/ready                  route:                    cluster: agent            statPrefix: agent  statsConfig:  # ......  tracing: # 鏈路追蹤    http:      name: envoy.tracers.zipkin      typedConfig:        '@type': type.googleapis.com/envoy.config.trace.v3.ZipkinConfig        collectorCluster: zipkin        collectorEndpoint: /api/v2/spans        collectorEndpointVersion: HTTP_JSON        sharedSpanContext: false        traceId128bit: true

上面的配置和之前我們介紹的 Envoy 配置基本一致,在上面配置中定義了一個 Prometheus 監聽器,用來暴露 Prometheus 監控指標,還定義了一個 Agent 監聽器,用來暴露健康檢查接口,另外還定義了一個 zipkin 集群,用來定義鏈路追蹤的配置。另外通過 dynamicResources 定義了動態配置發現服務信息,xds-grpc 就是用來定義 Envoy 與 Pilot 之間的 xDS 通信的。WDX28資訊網——每日最新資訊28at.com

ListenersConfigDump

這里存儲著 Envoy 的 listeners 配置,也就是 Envoy 的監聽器。Envoy 在攔截到請求后,會根據請求的地址與端口,將請求交給匹配的 listener 處理。WDX28資訊網——每日最新資訊28at.com

我們看到這個 ListenersConfigDump 中的 listener 配置分成了 static_listners 和 dynamic_listeners,分別對應 Envoy 的靜態配置和動態配置,靜態配置,是 Envoy 配置文件中直接指定的,而 dynamic_listeners的 listener 則是 istiod 通過 xDS 協議為 Envoy 下發的。WDX28資訊網——每日最新資訊28at.com

同樣我們也可以使用 istioctl proxy-config listener 命令來查看這部分配置:WDX28資訊網——每日最新資訊28at.com

istioctl proxy-config listener istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yaml

對應的配置文件如下所示:WDX28資訊網——每日最新資訊28at.com

- accessLog:    - filter:        responseFlagFilter:          flags:            - NR      name: envoy.access_loggers.file      typedConfig:        "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog        logFormat:          textFormatSource:            inlineString: |              [%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%        path: /dev/stdout  address:    socketAddress:      address: 0.0.0.0      portValue: 8080  continueOnListenerFiltersTimeout: true  filterChains:    - filters:        - name: istio_authn          typedConfig:            "@type": type.googleapis.com/udpa.type.v1.TypedStruct            typeUrl: type.googleapis.com/io.istiowork.authn.Config        - name: envoy.filterswork.http_connection_manager          typedConfig:            "@type": type.googleapis.com/envoy.extensions.filterswork.http_connection_manager.v3.HttpConnectionManager            accessLog:              - name: envoy.access_loggers.file                typedConfig:                  "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog                  logFormat:                    textFormatSource:                      inlineString: |                        [%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%                  path: /dev/stdout            forwardClientCertDetails: SANITIZE_SET            httpFilters:              - name: istio.metadata_exchange                typedConfig:                  "@type": type.googleapis.com/udpa.type.v1.TypedStruct                  typeUrl: type.googleapis.com/io.istio.http.peer_metadata.Config                  value:                    upstream_discovery:                      - istio_headers: {}                      - workload_discovery: {}                    upstream_propagation:                      - istio_headers: {}              - name: envoy.filters.http.grpc_stats                typedConfig:                  "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig                  emitFilterState: true                  statsForAllMethods: false              - name: istio.alpn                typedConfig:                  "@type": type.googleapis.com/istio.envoy.config.filter.http.alpn.v2alpha1.FilterConfig                  alpnOverride:                    - alpnOverride:                        - istio-http/1.0                        - istio                        - http/1.0                    - alpnOverride:                        - istio-http/1.1                        - istio                        - http/1.1                      upstreamProtocol: HTTP11                    - alpnOverride:                        - istio-h2                        - istio                        - h2                      upstreamProtocol: HTTP2              - name: envoy.filters.http.fault                typedConfig:                  "@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault              - name: envoy.filters.http.cors                typedConfig:                  "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors              - name: istio.stats                typedConfig:                  "@type": type.googleapis.com/stats.PluginConfig                  disableHostHeaderFallback: true              - name: envoy.filters.http.router                typedConfig:                  "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router            httpProtocolOptions: {}            normalizePath: true            pathWithEscapedSlashesAction: KEEP_UNCHANGED            rds:              configSource:                ads: {}                initialFetchTimeout: 0s                resourceApiVersion: V3              routeConfigName: http.8080            requestIdExtension:k              typedConfig:                "@type": type.googleapis.com/envoy.extensions.request_id.uuid.v3.UuidRequestIdConfig                useRequestIdForTraceSampling: true            serverName: istio-envoy            setCurrentClientCertDetails:              cert: true              dns: true              subject: true              uri: true            statPrefix: outbound_0.0.0.0_8080            streamIdleTimeout: 0s            tracing:              # ......            upgradeConfigs:              - upgradeType: websocket            useRemoteAddress: true  name: 0.0.0.0_8080  trafficDirection: OUTBOUND- address:    socketAddress:      address: 0.0.0.0      portValue: 15090  # ......- address:    socketAddress:      address: 0.0.0.0      portValue: 15021  # ......

雖然上面看到的 listener 配置還是很長,但是我們應該也還是非常熟悉的,本質就是 Envoy 的配置文件中的 listener 配置。我們這里重點看下動態配置對應的配置,靜態的就是前面指定 prometheus 和 agent 對應的監聽器配置。WDX28資訊網——每日最新資訊28at.com

我們可以看到上面的動態配置對應的監聽器名稱為 0.0.0.0_8080,對應的監聽地址為 0.0.0.0:8080,也就是說在 Envoy 中監聽了 8080 端口:WDX28資訊網——每日最新資訊28at.com

address:  socketAddress:    address: 0.0.0.0    portValue: 8080

而前面我們是不是創建了一個 Gateway 資源對象,并指定了 8080 端口,其實這個端口就是我們前面創建的 Gateway 對象中定義的端口,這個監聽器的配置就是通過 istiod 通過 xDS 協議下發的。WDX28資訊網——每日最新資訊28at.com

那么請求是如何到達這個監聽器的呢?我們可以查看下 istio-ingressgateway 組建的 Service 數據:WDX28資訊網——每日最新資訊28at.com

$ kubectl get svc istio-ingressgateway -n istio-systemNAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                      AGEistio-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 組件的呢?WDX28資訊網——每日最新資訊28at.com

$ kubectl describe svc istio-ingressgateway -n istio-systemName:                     istio-ingressgatewayNamespace:                istio-system# ......Port:                     http2  80/TCPTargetPort:               8080/TCPNodePort:                 http2  31896/TCPEndpoints:                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 端口了。WDX28資訊網——每日最新資訊28at.com

當請求到達 istio-ingressgateway 組件時,就會被這個監聽器所匹配,然后將請求交給 http_connection_manager 這個 filter 來處理,當然后面就是用各種具體的 filter 來處理請求了,比如 envoy.filters.http.fault 這個 filter 就是用來處理故障注入的,envoy.filters.http.router 則是用來處理路由轉發的、envoy.filters.http.cors 則是用來處理跨域請求的等等。WDX28資訊網——每日最新資訊28at.com

但是我們的請求進到 Envoy 后是又該如何路由呢?我應該將請求轉發到哪里去呢?這個是不是就是 Envoy 中的路由配置來決定的了,對于靜態配置我們清楚直接在 Envoy 配置文件中就可以看到,比如:WDX28資訊網——每日最新資訊28at.com

routeConfig:  virtualHosts:    - domains:        - "*"      name: backend      routes:        - match:            prefix: /healthz/ready          route:            cluster: agent

但是我們這里的路由配置是動態配置的,我們看到對應的配置中有一個 rds 字段,這個字段就是用來指定動態路由配置的,其中的 routeConfigName 字段就是用來指定對應的路由配置名稱的:WDX28資訊網——每日最新資訊28at.com

rds:  configSource:    ads: {}    initialFetchTimeout: 0s    resourceApiVersion: V3  routeConfigName: http.8080

RoutesConfigDump

這里面保存著 Envoy 的路由配置,和 listeners 一樣,RoutesConfigDump 也分為 static_route_configs 和 dynamic_route_configs,分別對應著靜態的路由配置和動態下發的路由配置。WDX28資訊網——每日最新資訊28at.com

同樣我們也可以使用 istioctl proxy-config route 命令來查看這部分配置:WDX28資訊網——每日最新資訊28at.com

istioctl proxy-config route istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yaml

對應的配置如下所示:WDX28資訊網——每日最新資訊28at.com

- ignorePortInHostMatching: true  maxDirectResponseBodySizeBytes: 1048576  name: http.8080  validateClusters: false  virtualHosts:    - domains:        - "*"      includeRequestAttemptCount: true      name: "*:8080"      routes:        - decorator:            operation: productpage.default.svc.cluster.local:9080/productpage          match:            caseSensitive: true            path: /productpage          metadata:            filterMetadata:              istio:                config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo          route:            cluster: outbound|9080||productpage.default.svc.cluster.local            maxGrpcTimeout: 0s            retryPolicy:              hostSelectionRetryMaxAttempts: "5"              numRetries: 2              retriableStatusCodes:                - 503              retryHostPredicate:                - name: envoy.retry_host_predicates.previous_hosts                  typedConfig:                    "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate              retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes            timeout: 0s        - decorator:            operation: productpage.default.svc.cluster.local:9080/static*          match:            caseSensitive: true            prefix: /static          metadata:            filterMetadata:              istio:                config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo          route:            cluster: outbound|9080||productpage.default.svc.cluster.local            maxGrpcTimeout: 0s            retryPolicy:              hostSelectionRetryMaxAttempts: "5"              numRetries: 2              retriableStatusCodes:                - 503              retryHostPredicate:                - name: envoy.retry_host_predicates.previous_hosts                  typedConfig:                    "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate              retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes            timeout: 0s        - decorator:            operation: productpage.default.svc.cluster.local:9080/login          match:            caseSensitive: true            path: /login          metadata:            filterMetadata:              istio:                config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo          route:            cluster: outbound|9080||productpage.default.svc.cluster.local            maxGrpcTimeout: 0s            retryPolicy:              hostSelectionRetryMaxAttempts: "5"              numRetries: 2              retriableStatusCodes:                - 503              retryHostPredicate:                - name: envoy.retry_host_predicates.previous_hosts                  typedConfig:                    "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate              retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes            timeout: 0s        - decorator:            operation: productpage.default.svc.cluster.local:9080/logout          match:            caseSensitive: true            path: /logout          metadata:            filterMetadata:              istio:                config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo          route:            cluster: outbound|9080||productpage.default.svc.cluster.local            maxGrpcTimeout: 0s            retryPolicy:              hostSelectionRetryMaxAttempts: "5"              numRetries: 2              retriableStatusCodes:                - 503              retryHostPredicate:                - name: envoy.retry_host_predicates.previous_hosts                  typedConfig:                    "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate              retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes            timeout: 0s        - decorator:            operation: productpage.default.svc.cluster.local:9080/api/v1/products*          match:            caseSensitive: true            prefix: /api/v1/products          metadata:            filterMetadata:              istio:                config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo          route:            cluster: outbound|9080||productpage.default.svc.cluster.local            maxGrpcTimeout: 0s            retryPolicy:              hostSelectionRetryMaxAttempts: "5"              numRetries: 2              retriableStatusCodes:                - 503              retryHostPredicate:                - name: envoy.retry_host_predicates.previous_hosts                  typedConfig:                    "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate              retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes            timeout: 0s- virtualHosts:    - domains:        - "*"      name: backend      routes:        - match:            prefix: /stats/prometheus          route:            cluster: prometheus_stats- virtualHosts:    - domains:        - "*"      name: backend      routes:        - match:            prefix: /healthz/ready          route:            cluster: agent

后面的兩個 virtualHosts 就是我們的靜態路由配置,第一個是動態的路由配置,我們可以看到該配置的名稱就是 http.8080,是不是和前面的 routeConfigName 是一致的。那么這個配置又是什么地方定義的呢?WDX28資訊網——每日最新資訊28at.com

其實仔細看這里面的配置和前面我們創建的 VirtualService 這個資源對象是不是很像,我們再看下前面創建的 VirtualService 對象的定義:WDX28資訊網——每日最新資訊28at.com

apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:  name: bookinfospec:  hosts:    - "*"  gateways:    - bookinfo-gateway  http:    - match:        - uri:            exact: /productpage        - uri:            prefix: /static        - uri:            exact: /login        - uri:            exact: /logout        - uri:            prefix: /api/v1/products      route:        - destination:            host: productpage            port:              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 端口的。WDX28資訊網——每日最新資訊28at.com

比如 /productpage 這個路由規則對應的 Envoy 配置如下所示:WDX28資訊網——每日最新資訊28at.com

- domains:    - "*"  includeRequestAttemptCount: true  name: "*:8080"  routes:    - decorator:        operation: productpage.default.svc.cluster.local:9080/productpage      match:        caseSensitive: true        path: /productpage      metadata:        filterMetadata:          istio:            config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/bookinfo      route:        cluster: outbound|9080||productpage.default.svc.cluster.local        maxGrpcTimeout: 0s        retryPolicy:          hostSelectionRetryMaxAttempts: "5"          numRetries: 2          retriableStatusCodes:            - 503          retryHostPredicate:            - name: envoy.retry_host_predicates.previous_hosts              typedConfig:                "@type": type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate          retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes        timeout: 0s

這個配置就是我們熟悉的 Envoy 的關于虛擬主機部分的配置,比如當我們請求的路徑為 /productpage 時,就會被這個路由規則匹配到,然后就用通過 route 字段來描述我們的路由目標了,針對這個目錄,可以看到有一些類似于 retry_policy、timeout等字段來配置這個目標的超時、重試策略等,不過最重要的還是 cluster 這個字段,它指定了這個路由目標對應著哪個上游集群,Envoy 最終將請求發送到這個 Cluster,比如我們這里的集群名稱為 outbound|9080||productpage.default.svc.cluster.local,關于其具體配置我們就要去查看 ClustersConfigDump 中的配置了。WDX28資訊網——每日最新資訊28at.com

ClustersConfigDump

該部分是用來存儲 Envoy 的集群配置的,同樣也分為 static_clusters 和 dynamic_active_clusters,分別對應著靜態配置和動態下發的配置。這里的 Cluster 集群是 Envoy 內部的概念,它是指 Envoy 連接的一組邏輯相同的上游主機,并不是說 K8s 集群,只是大多數情況下我們可以把這個集群理解為 K8s 集群中的一個 Service,一個 Service 通常對應著一組 Pod,由這組 Pod 響應請求并提供同一種服務,而 Envoy 的這個集群實際可以理解成這種Pod 集合。不過 Envoy 的一個集群也不一定就對應著一個 Service,因為集群是一組邏輯相同的上游主機,所以也有可能是別的符合定義的東西,比如說是服務的一個特定版本(如只是 v2 版本的 reviews 服務)。istio 的版本灰度能力就是基于這個做的,因為兩個版本的同一服務實際上可以分成兩個集群。WDX28資訊網——每日最新資訊28at.com

同樣我們可以使用 istioctl proxy-config cluster 命令來查看這部分配置:WDX28資訊網——每日最新資訊28at.com

istioctl proxy-config cluster istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yaml

該配置文件會非常長,它會將 K8s 集群中的 Service 都轉換成 Envoy 的 Cluster,這里我們只看下 productpage 這個服務對應的 Cluster 配置,如下所示:WDX28資訊網——每日最新資訊28at.com

- circuitBreakers: #    thresholds:      - maxConnections: 4294967295        maxPendingRequests: 4294967295        maxRequests: 4294967295        maxRetries: 4294967295        trackRemaining: true  commonLbConfig:    localityWeightedLbConfig: {}  connectTimeout: 10s  edsClusterConfig:    edsConfig:      ads: {}      initialFetchTimeout: 0s      resourceApiVersion: V3    serviceName: outbound|9080||productpage.default.svc.cluster.local  filters:    - name: istio.metadata_exchange      typedConfig:        "@type": type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange        protocol: istio-peer-exchange  lbPolicy: LEAST_REQUEST  metadata:    filterMetadata:      istio:        services:          - host: productpage.default.svc.cluster.local            name: productpage            namespace: default  name: outbound|9080||productpage.default.svc.cluster.local  transportSocketMatches:    - match:        tlsMode: istio      name: tlsMode-istio      transportSocket:        name: envoy.transport_sockets.tls        typedConfig:          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext          commonTlsContext:            alpnProtocols:              - istio-peer-exchange              - istio            combinedValidationContext:              defaultValidationContext:                matchSubjectAltNames:                  - exact: spiffe://cluster.local/ns/default/sa/bookinfo-productpage              validationContextSdsSecretConfig:                name: ROOTCA                sdsConfig:                  apiConfigSource:                    apiType: GRPC                    grpcServices:                      - envoyGrpc:                          clusterName: sds-grpc                    setNodeOnFirstMessageOnly: true                    transportApiVersion: V3                  initialFetchTimeout: 0s                  resourceApiVersion: V3            tlsCertificateSdsSecretConfigs:              - name: default                sdsConfig:                  apiConfigSource:                    apiType: GRPC                    grpcServices:                      - envoyGrpc:                          clusterName: sds-grpc                    setNodeOnFirstMessageOnly: true                    transportApiVersion: V3                  initialFetchTimeout: 0s                  resourceApiVersion: V3            tlsParams:              tlsMaximumProtocolVersion: TLSv1_3              tlsMinimumProtocolVersion: TLSv1_2          sni: outbound_.9080_._.productpage.default.svc.cluster.local    - match: {}      name: tlsMode-disabled      transportSocket:        name: envoy.transport_sockets.raw_buffer        typedConfig:          "@type": type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer  type: EDS

我們可以看到這個 Envoy Cluster 的名稱為 outbound|9080||productpage.default.svc.cluster.local,和前面的路由配置中的 cluster 字段是一致的,名稱大多數會由 | 分成四個部分,分別是 inbound 或 outbound 代表入向流量或出向流量、端口號、subcluster 名稱(就是對應著 destination rule 里的 subset)、Service FQDN,由 istio 的服務發現進行配置,通過這個 name 我們很容易就能看出來這個集群對應的是 K8s 集群的哪個服務。WDX28資訊網——每日最新資訊28at.com

然后配置的負載均衡策略是 LEAST_REQUEST,另外比較重要的這里的配置的類型為 type: EDS,也就是會通過 EDS 來發現上游的主機服務,這個 EDS 的配置如下所示:WDX28資訊網——每日最新資訊28at.com

edsClusterConfig:  edsConfig:    ads: {}    initialFetchTimeout: 0s    resourceApiVersion: V3  serviceName: outbound|9080||productpage.default.svc.cluster.local

基于 EDS 去動態發現上游主機的配置,其實在前面的 Envoy 章節我們已經介紹過了,和這里是不是幾乎是一致的,serviceName 其實就對應著 K8s 集群中的 productpage 這個 Service 對象的 9080 端口,而這個 Service 對象對應著一組 Pod,這組 Pod 就是我們的上游主機了。當然這是通過 xDS 協議下發的,我們可以通過 istioctl proxy-config endpoint 命令來查看這部分配置:WDX28資訊網——每日最新資訊28at.com

istioctl proxy-config endpoint istio-ingressgateway-9c8b9b586-s6s48 -n istio-system -o yaml

該部分數據非常多,下面只截取 productpage 相關的數據,如下所示:WDX28資訊網——每日最新資訊28at.com

- addedViaApi: true  circuitBreakers:    thresholds:    - maxConnections: 4294967295      maxPendingRequests: 4294967295      maxRequests: 4294967295      maxRetries: 4294967295    - maxConnections: 1024      maxPendingRequests: 1024      maxRequests: 1024      maxRetries: 3      priority: HIGH  edsServiceName: outbound|9080||productpage.default.svc.cluster.local  hostStatuses:  - address:      socketAddress:        address: 10.244.2.62        portValue: 9080    healthStatus:      edsHealthStatus: HEALTHY    locality: {}    stats:    - name: cx_connect_fail    - name: cx_total      value: "1"    - name: rq_error    - name: rq_success      value: "4"    - name: rq_timeout    - name: rq_total      value: "4"    - name: cx_active      type: GAUGE    - name: rq_active      type: GAUGE    weight: 1  name: outbound|9080||productpage.default.svc.cluster.local  observabilityName: outbound|9080||productpage.default.svc.cluster.local

可以看到上面的配置中就包含一個真正的后端服務地址:WDX28資訊網——每日最新資訊28at.com

address:  socketAddress:    address: 10.244.2.62    portValue: 9080

這個地址其實就是 productpage 這個 K8s Service 關聯的 Pod 的地址。這樣一個請求從進入到 Envoy 到最終轉發到后端服務的過程就清楚了。WDX28資訊網——每日最新資訊28at.com

SecretsConfigDump

由于網格中的 Envoy 之間互相通信會使用 mTLS 模式,因此每個 Envoy 通信時都需要提供本工作負載的證書,同時為了簽發證書還需要 istio ca 的根證書,這些證書的信息保存在該配置項之下。WDX28資訊網——每日最新資訊28at.com

總結

到這里我們就把 Envoy 的整個配置文件都理解了一遍,它們分別是 Bootstrap、Listeners、Routes、Clusters、Secrets 幾個配置,其中又涉及到 VirtualHost 等細分概念。WDX28資訊網——每日最新資訊28at.com

WDX28資訊網——每日最新資訊28at.com

整體上一個請求在 Envoy 內部的處理與轉發過程中,listener、route、cluster 這幾個配置是緊密相連的,它們通過配置的 name 一層又一層地向下引用(listener 內的 filter 引用 route、route 內的 virtual_host 引用 cluster),形成了一條引用鏈,最終將請求從 listener 遞交到具體的 cluster。WDX28資訊網——每日最新資訊28at.com

我們可以使用 envoyui.solo.io 這個在線的 Envoy 配置可視化工具來查看 Envoy 的配置,只需要將我們的 Envoy 配置 dump 出來上傳上來即可:WDX28資訊網——每日最新資訊28at.com

WDX28資訊網——每日最新資訊28at.com

Envoy config dumpWDX28資訊網——每日最新資訊28at.com

經過上面的分析我們也明白了其實 Istio 并沒有實現很多復雜的邏輯,服務治理相關的功能比如負載均衡、故障注入、權重路由等都是 Envoy 本身就有的能力,Istio 只是將這些能力抽象成了一個個資源對象,然后通過 Envoy 的 xDS 協議下發到 Envoy 中,這樣就能夠實現對 Envoy 的流量治理了。所以重點還是需要我們先理解 Envoy 的配置,然后再去理解 Istio 的配置,這樣才能更好的理解 Istio,不然你就不清楚 Gateway、VirtualService 等這些資源對象到底是干什么的,它們是如何影響 Envoy 的配置的。WDX28資訊網——每日最新資訊28at.com

當然我們這里還只是分析的 Istio Ingress Gateway 的配置,而對于 Sidecar 模式的 Envoy 代理又是如何去配置的呢?它又是如何將 Pod 的流量進行攔截的呢?這些我們后面會繼續分析。WDX28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-17399-0.htmlIstio Envoy 配置解讀,看這篇就夠了

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 數十萬定時任務,如何高效觸發定時和超時

下一篇: 我們一起聊聊淘寶為何需要確認收貨?京東為何不需要?

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 林芝县| 彰化市| 富顺县| 綦江县| 安西县| 陈巴尔虎旗| 洪洞县| 微山县| 萝北县| 准格尔旗| 理塘县| 武隆县| 白朗县| 雷山县| 成安县| 东乌| 玉林市| 荃湾区| 页游| 芮城县| 万全县| 广东省| 西城区| 吉水县| 名山县| 大埔县| 冷水江市| 绥宁县| 怀集县| 合水县| 和硕县| 双桥区| 黎川县| 墨脱县| 平和县| 象州县| 固原市| 资溪县| 河源市| 正镶白旗| 乌审旗|