<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          凌晨 12 點突發(fā) Istio 生產事故!一頓操作猛如虎解決了

          共 64704字,需瀏覽 130分鐘

           ·

          2021-09-19 08:57

          作者:龍小蝦,K8s 愛好者,目前在某運營商科技公司,主要負責維護 KubeSphere 容器平臺之上的容器化業(yè)務

          事故起因

          業(yè)務上新集群,本來以為"灑灑水",11 點切,12 點就能在家睡覺了。流量切過來后,在驗證過程中,發(fā)現網頁能夠正常打開,在登錄時返回了 502,當場懵逼。在相關的容器日志發(fā)現一個高頻的報錯條目“7000 端口無法連接”,向業(yè)務組了解到這是 redis 集群中的一個端口,前后端是通過 redis 交互的,該集群同時還有 7001-7003 其它三個端口。

          用 nc 命令對 redis 集群進行連接測試:向服務端發(fā)送 keys * 命令時,7000 端口返回的是 HTTP/1.1 400 Bad Request,其他三個端口是 redis 返回的 -NOAUTH Authentication required

          $ nc 10.0.0.6 7000
          keys *
          HTTP/1.1 400 Bad Request
          content-length: 0
          connection: close

          $ nc 10.0.0.6 7003
          keys *
          -NOAUTH Authentication required

          判斷 7000 端口連接到了其他應用上,至少不是 redis。在宿主機上抓包發(fā)現沒有抓到訪問 7000 端口的流量,然后查看容器的 nf_conntrackb 表,發(fā)現 7000 端口的數據只有到本地的會話信息;7003 的有兩條會話信息,一條到本機的,一條到目標服務器的。

          $ grep 7000 /proc/net/nf_conntrack
          ipv4     2 tcp      6 110 TIME_WAIT src=10.64.192.14 dst=10.0.0.6 sport=50498 dport=7000 src=127.0.0.1 dst=10.64.192.14 sport=15001 dport=50498 [ASSURED] mark=0 zone=0 use=2

          $ grep 7003 /proc/net/nf_conntrack
          ipv4     2 tcp      6 104 TIME_WAIT src=10.64.192.14 dst=10.0.0.6 sport=38952 dport=7003 src=127.0.0.1 dst=10.64.192.14 sport=15001 dport=38952 [ASSURED] mark=0 zone=0 use=2
          ipv4     2 tcp      6 104 TIME_WAIT src=10.64.192.14 dst=10.0.0.6 sport=38954 dport=7003 src=10.0.0.6 dst=10.64.192.14 sport=7003 dport=38954 [ASSURED] mark=0 zone=0 use=2

          由此判斷出 istio 沒有代理轉發(fā)出 7000 的流量,這突然就觸及到了我的知識盲區(qū),一大堆人看著,辦公室 26 度的空調,一直在冒汗。沒辦法了,在與業(yè)務商量后,只能先關閉 istio 注入,優(yōu)先恢復了業(yè)務?;厝ズ髳貉a istio 的相關資料。終于將問題解決。記錄下相關信息,以供日后參考。

          背景知識補充

          istio Sidecar 的模式

          istio 的 Sidecar 有兩種模式:

          • ALLOW_ANY:istio 代理允許調用未知的服務,黑名單模式。
          • REGISTRY_ONLY:istio 代理會阻止任何沒有在網格中定義的 HTTP 服務或 service entry 的主機,白名單模式。

          istio-proxy(Envoy)的配置結構

          istio-proxy(Envoy)的代理信息大體由以下幾個部分組成:

          • Cluster:在 Envoy 中,Cluster 是一個服務集群,Cluster 中包含一個到多個 endpoint,每個 endpoint 都可以提供服務,Envoy 根據負載均衡算法將請求發(fā)送到這些 endpoint 中。cluster 分為 inbound 和 outbound 兩種,前者對應 Envoy 所在節(jié)點上的服務;后者占了絕大多數,對應 Envoy 所在節(jié)點的外部服務??梢允褂萌缦路绞椒謩e查看 inbound 和 outbound 的 cluster。
          • Listeners:Envoy 采用 listener 來接收并處理 downstream 發(fā)過來的請求,可以直接與 Cluster 關聯,也可以通過 rds 配置路由規(guī)則(Routes),然后在路由規(guī)則中再根據不同的請求目的地對請求進行精細化的處理。
          • Routes:配置 Envoy 的路由規(guī)則。istio 下發(fā)的缺省路由規(guī)則中對每個端口(服務)設置了一個路由規(guī)則,根據 host 來對請求進行路由分發(fā),routes 的目的為其他服務的 cluster。
          • Endpoint:cludter 對應的后端服務,可以通過 istio pc endpoint 查看 inbound 和 outbound 對應的 endpoint 信息。

          服務發(fā)現類型

          cluster 的服務發(fā)現類型主要有:

          • ORIGINAL_DST:類型的 Cluster,Envoy 在轉發(fā)請求時會直接采用 downstream 請求中的原始目的地 IP 地址
          • EDS:EDS 獲取到該 Cluster 中所有可用的 Endpoint,并根據負載均衡算法(缺省為 Round Robin)將 Downstream 發(fā)來的請求發(fā)送到不同的 Endpoint。istio 會自動為集群中的 service 創(chuàng)建代理信息,listener 的信息從 service 獲取,對應的 cluster 被標記為 EDS 類型
          • STATIC:缺省值,在集群中列出所有可代理的主機 Endpoints。當沒有內容為空時,不進行轉發(fā)。
          • LOGICAL_DNS:Envoy 使用 DNS 添加主機,但如果 DNS 不再返回時,也不會丟棄。
          • STRICT_DNS:Envoy 將監(jiān)控 DNS,而每個匹配的 A 記錄都將被認為是有效的。

          兩個特殊集群

          BlackHoleCluster:黑洞集群,匹配此集群的流量將被不會被轉發(fā)。

          {
              "name""BlackHoleCluster",
              "type""STATIC",
              "connectTimeout""10s"
          }

          類型為 static,但是沒有指定可代理的 Endpoint,所以流量不會被轉發(fā)。

          PassthroughCluster:透傳集群,匹配此集群的流量數據包的目的 IP 不會改變。

          {
              "name""PassthroughCluster",
              "type""ORIGINAL_DST",
              "connectTimeout""10s",
              "lbPolicy""CLUSTER_PROVIDED",
              "circuitBreakers": {
                 "thresholds": [
                    {
                        "maxConnections"4294967295,
                         "maxPendingRequests"4294967295,
                         "maxRequests"4294967295,
                         "maxRetries"4294967295
                      }
                  ]
           }

          類型為 original_dst,流量將原樣轉發(fā)。

          一個特殊的 Listener

          istio 中有一個特殊的 Listener 叫 virtualOutbound,定義如下:

          • virtualOutbound:每個 Sidecar 都有一個綁定到 0.0.0.0:15001 的 listener,該 listener 下關聯了許多 virtual listener。iptables 會先將所有出站流量導入該 listener,該 listener 有一個字段 useOriginalDst 設置為 true,表示會使用最佳匹配原始目的地的方式將請求分發(fā)到 virtual listener,如果沒有找到任何 virtual listener,將會直接發(fā)送到數據包原目的地的 PassthroughCluster。

          useOriginalDst 字段的具體意義是,如果使用 iptables 重定向連接,則代理接收流量的目標地址可能與原始目標地址不同。當此標志設置為 true 時,偵聽器會將重定向流量轉交給與原始目標地址關聯的偵聽器。如果沒有與原始目標地址關聯的偵聽器,則流量由接收它的偵聽器處理。默認為 false。

          virtualOutbound 的流量處理流程如圖所示:

          這是 virtualOutbound 的部分配置:

          {
             "name""envoy.tcp_proxy",
             "typedConfig": {
                "@type""type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy",
                "statPrefix""PassthroughCluster",
                "cluster""PassthroughCluster"
               }
          }
          ……………
          "useOriginalDst"true

          istio 的 outbond 流量處理

          開啟流量治理后,pod 訪問外部資源的流量轉發(fā)路徑如圖所示:

          istio 注入后 istio-proxy 有一個監(jiān)聽在 15001 的端口,所有非 istio-proxy 用戶進程產生的 outbond 流量,通過 iptables 規(guī)則被重定向到 15001。

          # Sidecar 注入的 pod 監(jiān)聽的端口
          $ ss -tulnp
          State       Recv-Q Send-Q                                 Local Address:Port                                                Peer Address:Port
          LISTEN      0      128                                                *:80                                                             *:*
          LISTEN      0      128                                                *:15090                                                          *:*
          LISTEN      0      128                                        127.0.0.1:15000                                                          *:*
          LISTEN      0      128                                                *:15001                                                          *:*
          LISTEN      0      128                                                *:15006                                                          *:*
          LISTEN      0      128                                             [::]:15020                                                       [::]:*

          # Pod 內部的 iptables 表項
          $ iptables-save
          # Generated by iptables-save v1.4.21 on Fri Sep 17 13:47:09 2021
          *nat
          :PREROUTING ACCEPT [129886:7793160]
          :INPUT ACCEPT [181806:10908360]
          :OUTPUT ACCEPT [53409:3257359]
          :POSTROUTING ACCEPT [53472:3261139]
          :istio_INBOUND - [0:0]
          :istio_IN_REDIRECT - [0:0]
          :istio_OUTPUT - [0:0]
          :istio_REDIRECT - [0:0]
          -A PREROUTING -p tcp -j istio_INBOUND
          -A OUTPUT -p tcp -j istio_OUTPUT
          -A istio_INBOUND -p tcp -m tcp --dport 22 -j RETURN
          -A istio_INBOUND -p tcp -m tcp --dport 15020 -j RETURN
          -A istio_INBOUND -p tcp -j istio_IN_REDIRECT
          -A istio_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15006
          -A istio_OUTPUT -s 127.0.0.6/32 -o lo -j RETURN
          -A istio_OUTPUT ! -d 127.0.0.1/32 -o lo -j istio_IN_REDIRECT
          -A istio_OUTPUT -m owner --uid-owner 1337 -j RETURN
          -A istio_OUTPUT -m owner --gid-owner 1337 -j RETURN
          -A istio_OUTPUT -d 127.0.0.1/32 -j RETURN
          -A istio_OUTPUT -j istio_REDIRECT
          -A istio_REDIRECT -p tcp -j REDIRECT --to-ports 15001
          COMMIT
          # Completed on Fri Sep 17 13:47:09 2021

          istio-proxy 收到流量后,大致的處理步驟如下:

          • Proxy 在 ALLOW_ANY 模式下沒有匹配上 listener 將被直接轉發(fā)
          • listener 關聯了 type 為 ORIGINAL_DST 的 cluster 將使用原始請求種的 IP 地址
          • 匹配上了 BlackHoleCluster,將不會被轉發(fā)

          被代理流量的匹配步驟大致如下:

          疑問:isito 為 svc 創(chuàng)建的 listener 地址是全零的,集群內部的端口是會存在復用的,那 istio 到底是怎么區(qū)分流量的呢?

          關鍵就在于 route,route 由 virtual_host 條目組成,這些 virtual_host 條目就是根據 svc 的信息生成的,訪問集群內部的 svc 時,在 route 里可以根據域名或者 svc 對應的 virtual_ip 進行精確匹配,所以完全不需要擔心啦。

          $ kubectl get svc -A | grep 8001
          NodePort    10.233.34.158   <none>        8001:30333/TCP                                                                                                                               8d
          NodePort    10.233.9.105    <none>        8001:31717/TCP                                                                                                                               8d
          NodePort    10.233.60.59    <none>        8001:31135/TCP                                                                                                                               2d16h
          NodePort    10.233.18.212   <none>        8001:32407/TCP                                                                                                                               8d
          NodePort    10.233.15.5     <none>        8001:30079/TCP                                                                                                                               8d
          NodePort    10.233.59.21    <none>        8001:31103/TCP                                                                                                                               8d
          NodePort    10.233.17.123   <none>        8001:31786/TCP                                                                                                                               8d
          NodePort    10.233.9.196    <none>        8001:32662/TCP                                                                                                                               8d
          NodePort    10.233.62.85    <none>        8001:32104/TCP                                                                                                                               8d
          ClusterIP     10.233.49.245   <none>        8000/TCP,8001/TCP,8443/TCP,8444/TCP

          這是 route 下的 virtual_host 條目:

              {
                  "name""8001",
                  "virtualHosts": [
                      {
                          "name""merchant-center.open.svc.cluster.local:8001",
                          "domains": [
                              "merchant-center.open.svc.cluster.local",
                              "merchant-center.open.svc.cluster.local:8001",
                              "merchant-center.open",
                              "merchant-center.open:8001",
                              "merchant-center.open.svc.cluster",
                              "merchant-center.open.svc.cluster:8001",
                              "merchant-center.open.svc",
                              "merchant-center.open.svc:8001",
                              "10.233.60.59",
                              "10.233.60.59:8001"
                          ],
                          "routes": [
                              {
                                  "name""default",
                                  "match": {
                                      "prefix""/"
                                  },
                                  "route": {
                                      "cluster""outbound|8001||merchant-center.open.svc.cluster.local",
                                      "timeout""0s",
                                      "retryPolicy": {
                                          "retryOn""connect-failure,refused-stream,unavailable,cancelled,resource-exhausted,retriable-status-codes",
                                          "numRetries"2,
                                          "retryHostPredicate": [
                                              {
                                                  "name""envoy.retry_host_predicates.previous_hosts"
                                              }
                                          ],
                                          "hostSelectionRetryMaxAttempts""5",
                                          "retriableStatusCodes": [
                                              503
                                          ]
                                      },
                                      "maxGrpcTimeout""0s"
                                  },
          …………………
          {
                          "name""cashier-busi-svc.pay.svc.cluster.local:8001",
                          "domains": [
                              "cashier-busi-svc.pay.svc.cluster.local",
                              "cashier-busi-svc.pay.svc.cluster.local:8001",
                              "cashier-busi-svc.pay",
                              "cashier-busi-svc.pay:8001",
                              "cashier-busi-svc.pay.svc.cluster",
                              "cashier-busi-svc.pay.svc.cluster:8001",
                              "cashier-busi-svc.pay.svc",
                              "cashier-busi-svc.pay.svc:8001",
                              "10.233.17.123",
                              "10.233.17.123:8001"
                          ],
          …………………
                      {
                          "name""center-job.manager.svc.cluster.local:8001",
                          "domains": [
                              "center-job.manager.svc.cluster.local",
                              "center-job.manager.svc.cluster.local:8001",
                              "center-job.manager",
                              "center-job.manager:8001",
                              "center-job.manager.svc.cluster",
                              "center-job.manager.svc.cluster:8001",
                              "center-job.manager.svc",
                              "center-job.manager.svc:8001",
                              "10.233.34.158",
                              "10.233.34.158:8001"
                          ],
          ……………

          問題分析

          基于以上信息,對集群內的 svc 進行端口過濾,終于發(fā)現了集群中存在使用了 7000 端口的 service:

          使用7000端口的svc

          istio 會為 10.233.0.115:7000 自動生成一個 0.0.0.0:7000 的 listener:

          ADDRESS      PORT     TYPE
          0.0.0.0         7000      TCP

          查看詳細配置信息,在該 listener 中對于 tcp 流量是不轉發(fā)(BlackHoleCluster),所以目標地址為 10.0.x.x:7000 的流量被 listener_0.0.0.0:7000 匹配到時,因為是 tcp 的流量(nc 命令默認 tcp 協(xié)議),所以代理沒有對該流量進行轉發(fā)。這與開頭提到的 pod 沒有流量發(fā)出來現象一致。

          {
               "name""0.0.0.0_7000",
               "address": {
                  "socketAddress": {
                  "address""0.0.0.0",
                  "portValue"7000
                  }
               },
               "filterChains": [
                 {
                    "filterChainMatch": {
                    "prefixRanges": [
                       {
                          "addressPrefix""10.64.x.x",
                          "prefixLen"32
                        }
                     ]
                  },
               "filters": [
                 {
                    "name""envoy.tcp_proxy",
                    "typedConfig": {
                      "@type""type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy",
                      "statPrefix""BlackHoleCluster",
                      "cluster""BlackHoleCluster"
                      }
                    }
                  ]
          }

          至于 7001-7003 為什么能通,是因為 istio-proxy 默認使用的是 ALLOW_ANY 模式,對于沒有匹配上 listener 的流量是直接放行。可以通過 istio_configmap 配置信息來驗證一下:

          $ kubectl get cm istio -n istio-system -o yaml | grep -i -w -a3 "mode"
              # REGISTRY_ONLY - restrict outbound traffic to services defined in the service registry as well
              #   as those defined through ServiceEntries
              outboundTrafficPolicy:
                mode: ALLOW_ANY
              localityLbSetting:
                enabled: true
              # The namespace to treat as the administrative root namespace for istio
          --
                drainDuration: 45s
                parentShutdownDuration: 1m0s
                #
                # The mode used to redirect inbound connections to Envoy. This setting
                # has no effect on outbound traffic: iptables REDIRECT is always used for
                # outbound connections.
                # If "REDIRECT", use iptables REDIRECT to NAT and redirect to Envoy.
                # The "REDIRECT" mode loses source addresses during redirection.
                # If "TPROXY", use iptables TPROXY to redirect to Envoy.
                # The "TPROXY" mode preserves both the source and destination IP
                # addresses and ports, so that they can be used for advanced filtering
                # and manipulation.
                # The "TPROXY" mode also configures the Sidecar to run with the
                # CAP_NET_ADMIN capability, which is required to use TPROXY.
                #interceptionMode: REDIRECT
                #

          解決方案

          最后我們來解決開頭提到的問題,總共有三種解決方案。

          方法 1:Service Entry

          服務條目(Service Entry)是 istio 重要的資源對象之一,作用是將外部的資源注冊到 istio 內部的網格服務中來,以提供網格內對外部資源的更加精細化的控制。我們可以簡單理解為白名單,istios 根據 Service Entry 的內容生成 listeners。

          我們在命名空間 dev-self-pc-ct 中添加如下配置:

          $ kubectl apply -f - <<EOF
          apiVersion: networking.istio.io/v1alpha3
          kind: ServiceEntry
          metadata:
            name: rediscluster
            namespace: dev-self
          spec:
            hosts:
            - redis
            addresses:
            - 10.0.x.x/32
            ports:
            - number: 7000
              name: redis-7000
              protocol: tcp
            - number: 7001
              name: redis-7001
              protocol: tcp
            - number: 7002
              name: redis-7002
              protocol: tcp
            - number: 7003
              name: redis-7003
              protocol: tcp
            resolution: NONE
            location: MESH_EXTERNAL
          EOF

          查看 listener:

          $ ./istioctl proxy-config listeners test-8c4c9dcb9-kpm8n.dev-self --address 10.0.x.x -o json

          [
              {
                  "name""10.0.x.x_7000",
                  "address": {
                      "socketAddress": {
                          "address""10.0.x.x",
                          "portValue": 7000
                      }
                  },
                  "filterChains": [
                      {
                          "filters": [
                              {
                                  "name""mixer",
                                  "typedConfig": {
                                      "@type""type.googleapis.com/istio.mixer.v1.config.client.TcpClientConfig",
                                      "transport": {
                                          "networkFailPolicy": {
                                              "policy""FAIL_CLOSE",
                                              "baseRetryWait""0.080s",
                                              "maxRetryWait""1s"
                                          },
                                          "checkCluster""outbound|9091||istio-policy.istio-system.svc.cluster.local",
                                          "reportCluster""outbound|9091||istio-telemetry.istio-system.svc. cluster.local",
                                          "reportBatchMaxEntries": 100,
                                          "reportBatchMaxTime""1s"
                                      },
                                      "mixerAttributes": {
                                          "attributes": {
                                              "context.proxy_version": {
                                                  "stringValue""1.4.8"
                                              },
                                              "context.reporter.kind": {
                                                  "stringValue""outbound"
                                              },
                                              "context.reporter.uid": {
                                                  "stringValue""kubernetes://test-8c4c9dcb9-kpm8n.dev-self"
                                              },
                                              "destination.service.host": {
                                                  "stringValue""redis"
                                              },
                                              "destination.service.name": {
                                                  "stringValue""redis"
                                              },
                                              "destination.service.namespace": {
                                                  "stringValue""dev-self "
                                              },
                                              "source.namespace": {
                                                  "stringValue""dev-self "
                                              },
                                              "source.uid": {
                                                  "stringValue""kubernetes://test-8c4c9dcb9-kpm8n.dev-self"
                                              }
                                          }
                                      },
                                      "disableCheckCalls"true
                                  }
                              },
                              {
                                  "name""envoy.tcp_proxy",
                                  "typedConfig": {
                                      "@type""type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy",
                                      "statPrefix""outbound|7000||redis",
                                      "cluster""outbound|7000||redis"
                                  }
                              }
                          ]
                      }
                  ],
                  "deprecatedV1": {
                      "bindToPort"false
                  },
                  "listenerFiltersTimeout""0.100s",
                  "continueOnListenerFiltersTimeout"true,
                  "trafficDirection""OUTBOUND"
              },
              ......
          ]

          我們可以看到 listener "10.0.1.6_7000" 中 tcp 流量關聯了 outbound|7000||redis 集群,該集群的類型是 ORIGINAL_DST,即保持源報文的目的地址,并且沒有關聯任何 service。

          所以此時訪問 10.0.x.x:7000 的目標地址不會改變。

          {
              "name""outbound|7000||redis",
              "type""ORIGINAL_DST",
              "connectTimeout""10s",
              "lbPolicy""CLUSTER_PROVIDED",
              "circuitBreakers": {
              "thresholds": [
                 {
                    "maxConnections"4294967295,
                    "maxPendingRequests"4294967295,
                    "maxRequests"4294967295,
                    "maxRetries"4294967295
                 }
               ]
            }
          }

          再次訪問測試:

          $ nc 10.0.0.6 7000
          keys *
          -NOAUTH Authentication required.

          $ nc 10.0.0.7 7000
          keys *
          -NOAUTH Authentication required.

          $ nc 10.0.0.8 7000
          keys *
          -NOAUTH Authentication required.

          已經可以正常轉發(fā)。

          方法 2:更改 global.proxy.includeIPRanges 或 global.proxy.excludeIPRanges 配置選項

          • global.proxy.includeIPRanges:需要進行代理 ip 地址范圍
          • global.proxy.excludeIPRanges:不需要進行代理的 ip 地址范圍。

          最終效果為在 pod 的 iptables 規(guī)則上匹配或排除對應的地址,訪問這些地址流量不會被重定向到 istio-proxy,而是直接發(fā)送。

          我們可以使用 kubectl apply 命令更新 istio-Sidecar-injector 配置,也可以修改 spec. template.metadata. annotations 中的 traffic.Sidecar.istio.io/includeOutboundIPRanges 來達到相同的效果。

            template:
              metadata:
                annotations:
                  kubectl.kubernetes.io/restartedAt: '2021-06-09T21:59:10+08:00'
                  kubesphere.io/restartedAt: '2021-09-13T17:07:03.082Z'
                  logging.kubesphere.io/logSidecar-config: '{}'
                  Sidecar.istio.io/componentLogLevel: 'ext_authz:trace,filter:debug'
                  Sidecar.istio.io/inject: 'true'
                  traffic.Sidecar.istio.io/excludeOutboundIPRanges: 10.0.1.0/24

          Pod 里的 iptables 規(guī)則會將目標地址為 10.0.x.x/24 的流量正常轉發(fā):

          # Generated by iptables-save v1.4.21 on Fri Sep 17 14:26:10 2021
          *nat
          :PREROUTING ACCEPT [131058:7863480]
          :INPUT ACCEPT [183446:11006760]
          :OUTPUT ACCEPT [53889:3286544]
          :POSTROUTING ACCEPT [53953:3290384]
          :istio_INBOUND - [0:0]
          :istio_IN_REDIRECT - [0:0]
          :istio_OUTPUT - [0:0]
          :istio_REDIRECT - [0:0]
          -A PREROUTING -p tcp -j istio_INBOUND
          -A OUTPUT -p tcp -j istio_OUTPUT
          -A istio_INBOUND -p tcp -m tcp --dport 22 -j RETURN
          -A istio_INBOUND -p tcp -m tcp --dport 15020 -j RETURN
          -A istio_INBOUND -p tcp -j istio_IN_REDIRECT
          -A istio_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15006
          -A istio_OUTPUT -s 127.0.0.6/32 -o lo -j RETURN
          -A istio_OUTPUT ! -d 127.0.0.1/32 -o lo -j istio_IN_REDIRECT
          -A istio_OUTPUT -m owner --uid-owner 1337 -j RETURN
          -A istio_OUTPUT -m owner --gid-owner 1337 -j RETURN
          -A istio_OUTPUT -d 127.0.0.1/32 -j RETURN
          -A istio_OUTPUT -d  10.0.0.0/24  -j RETURN
          -A istio_OUTPUT -j istio_REDIRECT
          -A istio_REDIRECT -p tcp -j REDIRECT --to-ports 15001
          COMMIT
          # Completed on Fri Sep 17 14:26:10 2021

          方法 3:用 Service 打敗 Service

          這個方法基于 istio 會為集群中的 svc 自動生成 listener 的工作方式,手動在集群中為外部服務創(chuàng)建 service 和 endpoints:

          apiVersion: v1
          kind: Endpoints
          metadata:
            name: rediscluster
            labels:
              name: rediscluster
              app: redis-jf
              user: jf
            namespace: dev-self
          subsets:
            - addresses:
                - ip: 10.0.x.x
                - ip: 10.0.x.x
                - ip: 10.0.x.x
              ports:
                - name: tcp-7000
                  port: 7000
                - name: tcp-7001
                  port: 7001
                - name: tcp-7002
                  port: 7002
                - name: tcp-7003
                  port: 7003
          ---
          apiVersion: v1
          kind: Service
          metadata:
            name: rediscluster
            namespace: dev-self
          spec:
            ports:
            - name: tcp-7000
              protocol: TCP
              port: 7000
              targetPort: 7000
            - name: tcp-7001
              protocol: TCP
              port: 7001
              targetPort: 7001
            - name: tcp-7002
              protocol: TCP
              port: 7002
              targetPort: 7002
            - name: tcp-7003
              protocol: TCP
              port: 7003
              targetPort: 7003
            selector:
              name: rediscluster
              app: redis-jf
              user: jf

          應用以上配置后 istio 會自動生成一個 service_ip+port 的 listener。Service 信息如下:

          Selector:          app=redis-jf,name=rediscluster,user=jf
          Type:              ClusterIP
          IP:                10.233.40.115
          Port:              tcp-7000  7000/TCP
          TargetPort:        7000/TCP
          Endpoints:         <none>
          Port:              tcp-7001  7001/TCP
          TargetPort:        7001/TCP
          Endpoints:         <none>
          Port:              tcp-7002  7002/TCP
          TargetPort:        7002/TCP
          Endpoints:         <none>
          Port:              tcp-7003  7003/TCP
          TargetPort:        7003/TCP
          Endpoints:         <none>
          Session Affinity:  None
          Events:            <none>

          Listener 部分信息如下:

          {
             "name""10.233.59.159_7000",
             "address": {
                "socketAddress": {
                   "address""10.233.59.159",
                   "portValue"7000
                   }
               },
                "filterChains": [
                    {
                       "filters": [
                           {
                             "name""mixer",
                             "typedConfig": {
                               "@type""type.googleapis.com/istio.mixer.v1.config.client.TcpClientConfig",
                               "transport": {
                                 "networkFailPolicy": {
                                    "policy""FAIL_CLOSE",
                                    "baseRetryWait""0.080s",
                                    "maxRetryWait""1s"
                                  },
                               "checkCluster""outbound|9091||istio-policy.istio-system.svc.cluster.local",
                               "reportCluster""outbound|9091||istio-telemetry.istio-system.svc.cluster.local",
                               "reportBatchMaxEntries"100,
                               "reportBatchMaxTime""1s"
                             },
                             "mixerAttributes": {
                                "attributes": {
                                   "context.proxy_version": {
                                   "stringValue""1.4.8"
                               },
          ......

          該 listener 指向了一個 cluster:

          {
            "name""envoy.tcp_proxy",
            "typedConfig": {
                "@type""type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy",
                "statPrefix""outbound|7000||redis",
                "cluster""outbound|7000||redis"
              }
          }

          對應的 service 信息如下:

          可以看到 endpoint 就是剛才我們指定的外部服務器地址:

          進行訪問測試:

          已經可以正常訪問了。

          總結

          最后我們來比較一下這三種方法。

          • 方法 1:通過添加 ServiceEntry,以允許訪問外部服務??梢宰屇闶褂?istio 服務網格所有的功能去調用集群內或集群外的服務,這是官方推薦的方法。
          • 方法 2:直接繞過了 istio Sidecar 代理,使你的服務可以直接訪問任意的外部服務。 但是,以這種方式配置代理需要了解集群提供商相關知識和配置。將失去對外部服務訪問的監(jiān)控,并且無法將 istio 功能應用于外部服務的流量。
          • 方法 3:這個方法相對于其他兩種,配置有點復雜,同時還要通過 service 的方式來訪問外部服務,這意味著對于已經存在的應用需要進行改造。具體能否實施看實際情況。

          方法 1 的做法類似于“白名單”,不但能達到訪問外部服務的目的,并且可以像集群內部服務一樣對待(可使用 istio 的流量控制功能)。另外,即使服務受到入侵,由于“白名單”的設置入侵者也無法(或較難)將流量回傳到入侵機器,進一步保證了服務的安全性;

          方法 2 直接繞過了 istio Sidecar 代理,使你的服務可以直接訪問任意的外部服務。 但是,以這種方式配置代理需要了解集群提供商相關知識和配置。 你將失去對外部服務訪問的監(jiān)控,并且無法將 istio 功能應用于外部服務的流量;

          方法 3 雖然也可以使用 istio 的流量控制功能來管理外部流量,但是在實際操作中會存在配置復雜、改造應用等問題

          因此,強烈推薦大家使用方法一。最后,特別提醒一下大家。includeOutboundIPRanges 設置為空是有問題的,這相當于將所有的服務都配置代理繞行,那 Sidecar 就沒起作用了,沒了 Sidecar 的 istio 就沒有靈魂了。。

          關于 KubeSphere

          KubeSphere (https://kubesphere.io)是在 Kubernetes 之上構建的開源容器混合云,提供全棧的 IT 自動化運維的能力,簡化企業(yè)的 DevOps 工作流。

          KubeSphere 已被 Aqara 智能家居、杭州數跑科技、本來生活、新浪、華夏銀行、四川航空、國藥集團、微眾銀行、紫金保險、中通、中國人保壽險、中國太平保險、中移金科、Radore、ZaloPay 等海內外數千家企業(yè)采用。KubeSphere 提供了開發(fā)者友好的向導式操作界面和豐富的企業(yè)級功能,包括多云與多集群管理、Kubernetes 資源管理、DevOps (CI/CD)、應用生命周期管理、微服務治理 (Service Mesh)、多租戶管理、監(jiān)控日志、告警通知、審計事件、存儲與網絡管理、GPU support 等功能,幫助企業(yè)快速構建一個強大和功能豐富的容器云平臺。

           ? GitHub:https://github.com/kubesphere
           ?? 官網(中國站):https://kubesphere.com.cn
           ?????? 微信群:請搜索添加群助手微信號 kubesphere

          瀏覽 74
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩无码一级片 | 淫淫五月天婷婷 | 苍井空亚洲精品AA片在线播放 | 一级a性色毛片 | 色播婷婷五月 |