Istio如何使用相同的端口訪問網格外服務

1.一、背景html

寫這篇文章的目的是爲了說明如下問題:如何使用TCP協議相同的端口訪問網格外多個服務? 這是最近直播的時候有一個同窗提出的,當時我沒有徹底明白,「訪問多集羣」 的意思。後來仔細思考了一下,問題應該就是Istio服務網格內如何經過相同的協議,端口訪問不一樣的服務。mysql

1.二、使用場景git

確定會有人回答,既然相同的端口不能使用,何不換一個端口呢,這樣作也是一種解決方法。我在想有一些場景必定無法或者不方便繞過去。github

1) 假如同一個網格內部署了生產,測試,開發三套環境,都須要經過3306端口訪問對應環境的mysql數據庫。redis

2) 假如同一個網格內部署了生產,測試,開發三套環境,都須要經過6379端口訪問對應環境的redis。sql

在微服務盛行的今天,每每須要團隊之間協做,沒辦法保證全部的微服務都運行在同一服務網格內。尤爲是中間件服務,做爲公司公共服務,必定是業務共享的。既然咱們不可避免的須要使用相同的端口,訪問外部服務,接下來告訴你們兩種方案解決以上問題。數據庫

1.三、解決方案json

經過相同的端口443訪問 https://github.com 和 https://www.huaweicloud.com,從網格內訪問外部服務,須要分別建立對應的ServiceEntentry:api

1) www.huaweicloud.com緩存

cat <<EOF | kubectl apply -f -

apiVersion: networking.istio.io/v1alpha3

kind: ServiceEntry

metadata:

  name: hwcloud

spec:

  hosts:

  - www.huaweicloud.com

  ports:

  - number: 443

    name: tcp

    protocol: TCP

  resolution: DNS

  location: MESH_EXTERNAL

EOF

2) github.com

cat <<EOF | kubectl apply -f -

apiVersion: networking.istio.io/v1alpha3

kind: ServiceEntry

metadata:

  name: github

spec:

  hosts:

  - github.com

  ports:

  - number: 443

    name: tcp

    protocol: TCP

  resolution: DNS

  location: MESH_EXTERNAL

EOF

兩條規則建好以後,等待pilot將新的配置下發到全部的proxy,咱們經過sleep pod驗證連通性

 

$ kubectl exec sleep-754684654f-trpt2 -- curl -sL -o /dev/null https://www.huaweicloud.com –v

< HTTP/1.1 200 OK

< Server: NWSs

< Date: Fri, 21 Dec 2018 02:23:11 GMT

< Content-Type: text/html;charset=utf-8

< Content-Length: 703122

< Connection: keep-alive

< Cache-Control: public, max-age=600

< Expires: Fri, 21 Dec 2018 02:33:10 GMT

< Last-Modified: Thu, 20 Dec 2018 10:30:00 GMT

< X-NWS-LOG-UUID: 0d13017f-8767-4399-a509-6c11b2a9f3d0

< Access-Control-Allow-Origin: *

< dl-from: qcloud

< X-Cache-Lookup: Hit From Disktank3

< X-Via: LIANTONG-HENAN_171(200:hit)

{ [15930 bytes data]

* Connection #0 to host www.huaweicloud.com left intact

kubectl exec sleep-754684654f-trpt2 -- curl -sL -o /dev/null https://github.com –v -k

< HTTP/1.1 404 Not Found

< Server: NWSs

< Date: Fri, 21 Dec 2018 02:29:26 GMT

< Content-Type: text/html

< Content-Length: 52

< Connection: keep-alive

< X-NWS-LOG-UUID: b283fee3-89e0-48bc-8d6e-0c3a68ecc4bf

< X-Via: LIANTONG-HENAN_25(404:hit)

{ [52 bytes data]

* Connection #0 to host github.com left intact

因而可知能夠在網格內部訪問https://www.huaweicloud.com,可是不能夠訪問https://github.com. 這裏有一個緣由是istio會將ServiceEntry規則按照建立時間排序,建立時間較早的優先級高,因此先建立的 hwcloud ServiceEntry生效。

能夠查看sleep pod上的配置來確認:listener配置只有到華爲雲的cluster"outbound|443||www.huaweicloud.com"

 

 

$ istioctl pc listener sleep-754684654f-trpt2  --address=0.0.0.0 --port=443 -ojson

[

    {

        "name": "0.0.0.0_443",

        "address": {

            "socketAddress": {

                "address": "0.0.0.0",

                "portValue": 443

            }

        },

        "filterChains": [

            {

                "filters": [

                    {

                        "name": "mixer",

                         …

                    },

                    {

                        "name": "envoy.tcp_proxy",

                        "config": {

                            "access_log": [

                                {

                                  …

                                }

                            ],

                            "cluster": "outbound|443||www.huaweicloud.com",

                            "stat_prefix": "outbound|443||www.huaweicloud.com"

                        }

                    }

                ]

            }

        ],

        …

    }

]

爲了同時訪問二者,這裏我提供兩種方法:

1.3.1建立ServiceEntry時指定Address

查詢www.huaweicloud.com域名綁定的ip地址,選擇一個或者多個更新hwcloud ServiceEntry

0124_1.jpg

一樣的方法更新 github 

0124_2.jpg

驗證https://www.huaweicloud.com和https://github.com都可以從網格內訪問,由於指定了spec.addresses 後,pilot生成listener使就會使用指定的ip地址代替‘0.0.0.0’的全匹配方式。

0124_3.jpg

雖然着這種方式必定程度上能夠解決同一端口訪問外部服務的需求。可是因爲須要提早設置ip地址,因此在ip常常變更的場景下缺乏靈活性。下面提供一種更靈活的方法。

1.3.2 指定ServiceEntry的做用域

Istio社區最近實現了網絡的配置做用域特性:https://github.com/istio/istio/pull/10287, 容許用戶設置相應規則的做用域範圍。

目前 ServiceEntry,VirtualService,Gateway, DestinationRule等均可以經過spec.configScope設置做用範圍。ConfigScope 能夠設置爲"PUBLIC","PRIVATE"類型。

"PUBLIC" 表示規則對網格內全部的工做負載可見,這也是默認值。

"PRIVATE" 表示規則僅對同一namespace下面的工做負載可見。

所以能夠利用ConfigScope將github以及hwcloud都設置成PRIVATE,分別建立在兩個不一樣的namespace下面。這樣也能夠作到ns1內的工做負載訪問https://github.com, ns2內的工做負載訪問https://www.huaweicloud.com .

 

cat <<EOF | kubectl apply -f -

apiVersion: networking.istio.io/v1alpha3

kind: ServiceEntry

metadata:

  name: github

  namespace: ns1

spec:

  hosts:

  - github.com

  ports:

  - number: 443

    name: tcp

    protocol: TCP

  resolution: DNS

  location: MESH_EXTERNAL

  configScope: PRIVATE

EOF

cat <<EOF | kubectl apply -f -

apiVersion: networking.istio.io/v1alpha3

kind: ServiceEntry

metadata:

  name: hwcloud

  namespace: ns2

spec:

  hosts:

  - www.huaweicloud.com

  ports:

  - number: 443

    name: tcp

    protocol: TCP

  resolution: DNS

  location: MESH_EXTERNAL

  configScope: PRIVATE

EOF

ConfigScope這種方式很是適合前面提到的場景:在同一個微服務網格內同時部署生產,測試環境, 而且生產,測試環境都須要調用對應環境的中間件服務(緩存,數據庫,MQ等)。

1.四、小結

Istio服務網格內,端口衝突致使的服務連通性問題很是常見,可是變幻無窮都逃不過Listener - Route – Cluster – Endpoint, Envoy的全部功能歸根到底都是經過這四種配置控制。社區提供的命令行工具:istioctl能夠很方便的可以解析出Envoy的配置,便於快速定位問題。Ref:https://istio.io/help/ops/traffic-management/proxy-cmd/

原文出處:https://www.cnblogs.com/CCE-SWR/p/10313351.html

相關文章
相關標籤/搜索