天天看點

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

在多控制平面拓撲的配置中,每個 Kubernetes 叢集都會安裝相同的 Istio 控制平面,并且每個控制平面隻會管理自己叢集内的服務端點。通過使用 Istio 網關、公共根證書頒發機構(CA)以及服務條目 ServiceEntry,可以将多個叢集配置組成一個邏輯上的單一服務網格。這種方法沒有特殊的網絡要求,是以通常被認為是在 Kubernetes 叢集之間沒有通用網絡連接配接時的一種最簡單方法。

在這種拓撲配置下,Kubernetes 跨叢集通信需要服務之間的雙向 TLS 連接配接,要在叢集之間啟用雙向 TLS 通信,每個叢集的 Citadel 将配置由共享的根 CA 生成的中間 CA 證書,如圖所示。

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

(多控制平面)

部署控制平面

從共享的根 CA 為每個叢集的 Citadel 生成中間 CA 證書,共享的根 CA 啟用跨不同叢集的雙向 TLS 通信。為了便于說明,我們将 samples/certs 目錄下 Istio 安裝中提供的示例根 CA 證書用于兩個叢集。在實際部署中,你可能會為每個叢集使用不同的 CA 證書,所有 CA 證書都由公共根 CA 簽名。

在每個 Kubernetes 叢集中實施以下步驟,以在所有叢集中部署相同的 Istio 控制平面配置。

1. 使用以下的指令為生成的 CA 證書建立 Kubernetes 密鑰,如下所示:

kubectl

create namespace istio-system

create secret generic cacerts -n istio-system \

--from-file=samples/certs/ca-cert.pem \           

--from-file=samples/certs/ca-key.pem \

--from-file=samples/certs/root-cert.pem \

--from-file=samples/certs/cert-chain.pem

1. 安裝 Istio 的 CRD 并等待幾秒鐘,以便将它們送出給 Kubernetes API 伺服器,如下所示:

for

i in install/kubernetes/helm/istio-init/files/crd*yaml; do kubectl apply -f $i;

done

  1. 部署 Istio 控制平面:如果 helm 依賴項缺失或者不是最新的,可以通過 helm dep update 來更新這些依賴項。注意因為沒有使用 istio-cni,可以暫時将其從依賴項 requirements.yaml 中去掉再執行更新操作。具體執行指令如下:

helm

template install/kubernetes/helm/istio --name istio --namespace istio-system \

-f

install/kubernetes/helm/istio/values-istio-multicluster-gateways.yaml >

./istio.yaml

apply -f ./istio.yaml

確定上述步驟在每個 Kubernetes 叢集中都執行成功。當然,通過 helm 生成 istio.yaml 的指令執行一次即可。

設定 DNS

為遠端叢集中的服務提供 DNS 解析,則現有應用程式不需要做修改就可以運作,因為應用程式通常期望通過其 DNS 名稱來解析服務并通路所得到的 IP 位址。Istio 本身不使用 DNS 在服務之間路由請求,同一個 Kubernetes 叢集下的服務會共享一個相同的 DNS 字尾(例如 svc.cluster.local)。Kubernetes DNS 為這些服務提供 DNS 解析能力。為了給遠端叢集中的服務提供相似的設定,将遠端叢集中的服務以 ..global 的格式命名。

Istio 安裝包中附帶了一個 CoreDNS 伺服器,該伺服器将為這些服務提供DNS解析能力。為了利用這個 DNS 解析能力,需要配置 Kubernetes 的 DNS 服務指向該 CoreDNS 服務。該 CoreDNS 服務将作為 .global DNS 域的 DNS 伺服器。

對于使用 kube-dns 的叢集,請建立以下配置項或更新現有的配置項:

apply -f - <apiVersion:

v1

kind:

ConfigMap

metadata:

name: kube-dns

namespace: kube-system

data:

stubDomains: |

{"global": ["$(kubectl get           

svc -n istio-system istiocoredns -o jsonpath={.spec.clusterIP})"]}

EOF

對于使用 CoreDNS 的叢集,請建立以下配置項或更新現有的配置項:

name: coredns

Corefile: |

.:53 {
    errors
    health
    kubernetes cluster.local in-addr.arpa           

ip6.arpa {

pods insecure
       upstream
       fallthrough in-addr.arpa ip6.arpa
    }
    prometheus :9153
    proxy . /etc/resolv.conf
    cache 30
    reload
    loadbalance
}
global:53 {
    errors
    cache 30
    proxy . $(kubectl get svc -n           

istio-system istiocoredns -o jsonpath={.

spec.clusterIP})
}           

部署示例應用

為了示範跨叢集通路,在一個 Kubernetes 叢集中部署 sleep 應用服務,在第二個叢集中部署 httpbin 應用服務,然後驗證 sleep 應用是否可以調用遠端叢集的 httpbin 服務。

1. 部署 sleep 服務到第一個叢集 cluster1 中,執行如下指令:

create namespace app1

label namespace app1 istio-injection=enabled

apply -n app1 -f samples/sleep/sleep.yaml

export

SLEEP_POD=$(kubectl get -n app1 pod -l app=sleep -o

jsonpath={.items..metadata.name})

1. 部署 httpbin 服務到第二個叢集 cluster2 中,執行如下指令:

create namespace app2

label namespace app2 istio-injection=enabled

apply -n app2 -f samples/httpbin/httpbin.yaml

1. 擷取叢集 cluster2 的入口網關位址,如下所示:

CLUSTER2_GW_ADDR=$(kubectl get svc --selector=app=istio-ingressgateway \

-n istio-system -o

jsonpath="{.items[0].status.loadBalancer.ingress[0].ip}")

1. 為了讓在叢集 cluster1 中的服務 sleep 能夠通路叢集 cluster2 中的服務 httpbin,我們需要在叢集 cluster1 中為服務 httpbin 建立一個服務條目 ServiceEntry 資源。服務條目 ServiceEntry 的主機名應該是..globalname,其中 name 和 namespace 分别對應于叢集 cluster2 中的遠端服務的名稱和命名空間。

對于 *.global 域下服務的 DNS 解析,需要為這些服務配置設定一個 IP 位址,并且保證 .globalDNS 域中的每個服務在叢集中必須具有唯一的 IP 位址。這些 IP 位址在 pod 之外是不可路由的。在這個例子中,我們将使用網段 127.255.0.0/16 來避免與其他的IP沖突。這些 IP 的應用流量将由 Sidecar 代理捕獲并路由到适當的其他遠端服務。

在叢集 cluster1 中建立該 httpbin 服務對應的 ServiceEntry,執行如下指令:

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由
如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

上面的配置将會使叢集 cluster1 中通路 httpbin.app2.global 的所有流量,包括通路它的任何端口的流量,都會被路由到啟用了雙向 TLS 連接配接的端點 :15443 上。

端口 15443 的網關是一個特殊的 SNI 感覺的 Envoy 代理,它是在前面開始部分中作為多叢集 Istio 安裝步驟的一部分預先配置和安裝的。進入端口 15443 的流量将在目标叢集的适當内部服務的 pod 中進行負載均衡。

在叢集 cluster1 下執行如下指令檢視容器 istiocoredns,可以看到上述 ServiceEntry 的域名映射關系已經被加載:

ISTIO_COREDNS=$(kubectl get -n istio-system po -l app=istiocoredns -o

logs --tail 2 -n istio-system ${ISTIO_COREDNS} -c istio-coredns-plugin

執行結果如下所示:

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

1. 驗證在叢集 cluster1 中的 sleep 服務是否可以正常調用位于叢集 cluster2 中的 httpbin 服務,在叢集 cluster1 執行如下指令:

exec $SLEEP_POD -n app1 -c sleep -- curl httpbin.app2.global:8000/headers

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

至此,叢集 cluster1 與 cluster2 在多控制平面配置下完成了連通。

跨叢集的版本路由

通過前面的文章,我們已經了解了 Istio 的很多功能,例如基本版本的路由等,可以在單個 Kubernetes 叢集上很容易地實作。而很多真實的業務場景中,基于微服務的應用程式并非那麼簡單,而是需要在多個位置跨叢集去配置設定和運作服務。那麼問題就來了,是否 Istio 的這些功能同樣可以很簡單地運作在這些真實的複雜環境中呢?

下面我們将會通過一個示例來了解 Istio 的流量管理功能如何在具有多個控制平面拓撲的多叢集網格中正常運作。

1. 首先,部署版本 v1 的 helloworld 服務到第一個叢集 cluster1 中,執行如下指令:

create namespace hello

label namespace hello istio-injection=enabled

apply -n hello -f samples/sleep/sleep.yaml

apply -n hello -f samples/helloworld/service.yaml

apply -n hello -f samples/helloworld/helloworld.yaml -l version=v1

1. 部署版本 v2 與 v3 的 helloworld 服務到第二個叢集 cluster2 中,執行如下指令:

apply -n hello -f samples/helloworld/helloworld.yaml -l version=v2

apply -n hello -f samples/helloworld/helloworld.yaml -l version=v3

1. 如前面章節中所述,多控制平面下,需要使用以 .global 為字尾的 DNS 名稱通路遠端服務。

在我們的例子中,它是 helloworld.hello.global,是以我們需要在叢集 cluster1 中建立服務條目 ServiceEntry 和目标規則 DestinationRule。服務條目 ServiceEntry 将使用叢集 cluster2 的入口網關作為端點位址來通路服務。

通過使用以下指令在叢集 cluster1 中建立 helloworld 服務對應的服務條目 ServiceEntry 和目标規則DestinationRule:

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由
如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

1. 在兩個叢集上建立目标規則。在叢集 cluster1 中建立子集 v1 對應的目标規則,執行如下指令:

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

而在叢集 cluster2 中建立子集 v2 和 v3 對應的目标規則,執行如下指令:

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

1. 建立虛拟服務以路由流量。

應用下面的虛拟服務将會使得來自使用者 jason 對 helloworld 的流量請求指向位于叢集 cluster2 中的版本 v2 和 v3,其中 v2 比例為 70%,v3 比例為 30%;來自任何其他使用者對 helloworld 的流量請求都将轉到位于叢集 cluster1 中的版本 v1:

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由
如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

執行多次調用,可以從下面的執行結果中看出,上述流量路由的規則生效,這也說明了在多控制平面拓撲下,用于路由的規則定義與在本地叢集的使用方式是一樣的:

如何使用 Istio 進行多叢集部署管理:多控制平面部署控制平面設定 DNS部署示例應用跨叢集的版本路由

設定多叢集網格的最簡單方法是使用多控制平面拓撲,因為它沒有特殊的網絡要求。通過上述示例可以看出,在單個 Kubernetes 叢集上運作的路由功能同樣很容易地在多個叢集中使用運作。

本文轉自<阿裡巴巴雲原生技術圈>——阿裡巴巴雲原生小助手

繼續閱讀