您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么使用Istio進行多集群部署管理”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么使用Istio進行多集群部署管理”吧!
在多控制平面拓撲的配置中,每個 Kubernetes 集群都會安裝相同的 Istio 控制平面,并且每個控制平面只會管理自己集群內的服務端點。通過使用 Istio 網(wǎng)關、公共根證書頒發(fā)機構(CA)以及服務條目 ServiceEntry,可以將多個集群配置組成一個邏輯上的單一服務網(wǎng)格。這種方法沒有特殊的網(wǎng)絡要求,因此通常被認為是在 Kubernetes 集群之間沒有通用網(wǎng)絡連接時的一種最簡單方法。
在這種拓撲配置下,Kubernetes 跨集群通信需要服務之間的雙向 TLS 連接,要在集群之間啟用雙向 TLS 通信,每個集群的 Citadel 將配置由共享的根 CA 生成的中間 CA 證書,如圖所示。
(多控制平面)
從共享的根 CA 為每個集群的 Citadel 生成中間 CA 證書,共享的根 CA 啟用跨不同集群的雙向 TLS 通信。為了便于說明,我們將 samples/certs 目錄下 Istio 安裝中提供的示例根 CA 證書用于兩個集群。在實際部署中,你可能會為每個集群使用不同的 CA 證書,所有 CA 證書都由公共根 CA 簽名。
在每個 Kubernetes 集群中實施以下步驟,以在所有集群中部署相同的 Istio 控制平面配置。
使用以下的命令為生成的 CA 證書創(chuàng)建 Kubernetes 密鑰,如下所示:
kubectl create namespace istio-system kubectl 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
安裝 Istio 的 CRD 并等待幾秒鐘,以便將它們提交給 Kubernetes API 服務器,如下所示:
for i in install/kubernetes/helm/istio-init/files/crd*yaml; do kubectl apply -f $i; done
部署 Istio 控制平面:如果 helm 依賴項缺失或者不是最新的,可以通過 helm dep update 來更新這些依賴項。注意因為沒有使用 istio-cni,可以暫時將其從依賴項 requirements.yaml 中去掉再執(zhí)行更新操作。具體執(zhí)行命令如下:
helm template install/kubernetes/helm/istio --name istio --namespace istio-system \ -f install/kubernetes/helm/istio/values-istio-multicluster-gateways.yaml > ./istio.yaml kubectl apply -f ./istio.yaml
確保上述步驟在每個 Kubernetes 集群中都執(zhí)行成功。當然,通過 helm 生成 istio.yaml 的命令執(zhí)行一次即可。
為遠程集群中的服務提供 DNS 解析,則現(xiàn)有應用程序不需要做修改就可以運行,因為應用程序通常期望通過其 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 的集群,請創(chuàng)建以下配置項或更新現(xiàn)有的配置項:
kubectl apply -f - <<EOF 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 的集群,請創(chuàng)建以下配置項或更新現(xiàn)有的配置項:
kubectl apply -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: 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}) } EOF
為了演示跨集群訪問,在一個 Kubernetes 集群中部署 sleep 應用服務,在第二個集群中部署 httpbin 應用服務,然后驗證 sleep 應用是否可以調用遠程集群的 httpbin 服務。
部署 sleep 服務到第一個集群 cluster1 中,執(zhí)行如下命令:
kubectl create namespace app1 kubectl label namespace app1 istio-injection=enabled kubectl apply -n app1 -f samples/sleep/sleep.yaml export SLEEP_POD=$(kubectl get -n app1 pod -l app=sleep -o jsonpath={.items..metadata.name})
部署 httpbin 服務到第二個集群 cluster2 中,執(zhí)行如下命令:
kubectl create namespace app2 kubectl label namespace app2 istio-injection=enabled kubectl apply -n app2 -f samples/httpbin/httpbin.yaml
獲取集群 cluster2 的入口網(wǎng)關地址,如下所示:
export CLUSTER2_GW_ADDR=$(kubectl get svc --selector=app=istio-ingressgateway \ -n istio-system -o jsonpath="{.items[0].status.loadBalancer.ingress[0].ip}")
為了讓在集群 cluster1 中的服務 sleep 能夠訪問集群 cluster2 中的服務 httpbin,我們需要在集群 cluster1 中為服務 httpbin 創(chuàng)建一個服務條目 ServiceEntry 資源。服務條目 ServiceEntry 的主機名應該是..globalname,其中 name 和 namespace 分別對應于集群 cluster2 中的遠程服務的名稱和命名空間。
對于 *.global 域下服務的 DNS 解析,需要為這些服務分配一個 IP 地址,并且保證 .globalDNS 域中的每個服務在集群中必須具有唯一的 IP 地址。這些 IP 地址在 pod 之外是不可路由的。在這個例子中,我們將使用網(wǎng)段 127.255.0.0/16 來避免與其他的IP沖突。這些 IP 的應用流量將由 Sidecar 代理捕獲并路由到適當?shù)钠渌h程服務。
在集群 cluster1 中創(chuàng)建該 httpbin 服務對應的 ServiceEntry,執(zhí)行如下命令:
kubectl apply -n app1 -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: httpbin-app2 spec: hosts: # must be of form name.namespace.global - httpbin.app2.global # Treat remote cluster services as part of the service mesh # as all clusters in the service mesh share the same root of trust. location: MESH_INTERNAL ports: - name: http1 number: 8000 protocol: http resolution: DNS addresses: # the IP address to which httpbin.bar.global will resolve to # must be unique for each remote service, within a given cluster. # This address need not be routable. Traffic for this IP will be captured # by the sidecar and routed appropriately. - 127.255.0.2 endpoints: # This is the routable address of the ingress gateway in cluster2 that # sits in front of sleep.bar service. Traffic from the sidecar will be # routed to this address. - address: ${CLUSTER2_GW_ADDR} ports: http1: 15443 # Do not change this port value EOF
上面的配置將會使集群 cluster1 中訪問 httpbin.app2.global 的所有流量,包括訪問它的任何端口的流量,都會被路由到啟用了雙向 TLS 連接的端點 :15443 上。
端口 15443 的網(wǎng)關是一個特殊的 SNI 感知的 Envoy 代理,它是在前面開始部分中作為多集群 Istio 安裝步驟的一部分預先配置和安裝的。進入端口 15443 的流量將在目標集群的適當內部服務的 pod 中進行負載均衡。
在集群 cluster1 下執(zhí)行如下命令查看容器 istiocoredns,可以看到上述 ServiceEntry 的域名映射關系已經(jīng)被加載:
export ISTIO_COREDNS=$(kubectl get -n istio-system po -l app=istiocoredns -o jsonpath={.items..metadata.name}) kubectl logs --tail 2 -n istio-system ${ISTIO_COREDNS} -c istio-coredns-plugin
執(zhí)行結果如下所示:
驗證在集群 cluster1 中的 sleep 服務是否可以正常調用位于集群 cluster2 中的 httpbin 服務,在集群 cluster1 執(zhí)行如下命令:
kubectl exec $SLEEP_POD -n app1 -c sleep -- curl httpbin.app2.global:8000/headers
執(zhí)行結果如下所示:
至此,集群 cluster1 與 cluster2 在多控制平面配置下完成了連通。
通過前面的文章,我們已經(jīng)了解了 Istio 的很多功能,例如基本版本的路由等,可以在單個 Kubernetes 集群上很容易地實現(xiàn)。而很多真實的業(yè)務場景中,基于微服務的應用程序并非那么簡單,而是需要在多個位置跨集群去分配和運行服務。那么問題就來了,是否 Istio 的這些功能同樣可以很簡單地運行在這些真實的復雜環(huán)境中呢?
下面我們將會通過一個示例來了解 Istio 的流量管理功能如何在具有多個控制平面拓撲的多集群網(wǎng)格中正常運行。
首先,部署版本 v1 的 helloworld 服務到第一個集群 cluster1 中,執(zhí)行如下命令:
kubectl create namespace hello kubectl label namespace hello istio-injection=enabled kubectl apply -n hello -f samples/sleep/sleep.yaml kubectl apply -n hello -f samples/helloworld/service.yaml kubectl apply -n hello -f samples/helloworld/helloworld.yaml -l version=v1
部署版本 v2 與 v3 的 helloworld 服務到第二個集群 cluster2 中,執(zhí)行如下命令:
kubectl create namespace hello kubectl label namespace hello istio-injection=enabled kubectl apply -n hello -f samples/helloworld/service.yaml kubectl apply -n hello -f samples/helloworld/helloworld.yaml -l version=v2 kubectl apply -n hello -f samples/helloworld/helloworld.yaml -l version=v3
如前面章節(jié)中所述,多控制平面下,需要使用以 .global 為后綴的 DNS 名稱訪問遠程服務。
在我們的例子中,它是 helloworld.hello.global,所以我們需要在集群 cluster1 中創(chuàng)建服務條目 ServiceEntry 和目標規(guī)則 DestinationRule。服務條目 ServiceEntry 將使用集群 cluster2 的入口網(wǎng)關作為端點地址來訪問服務。
通過使用以下命令在集群 cluster1 中創(chuàng)建 helloworld 服務對應的服務條目 ServiceEntry 和目標規(guī)則DestinationRule:
kubectl apply -n hello -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: helloworld spec: hosts: - helloworld.hello.global location: MESH_INTERNAL ports: - name: http1 number: 5000 protocol: http resolution: DNS addresses: - 127.255.0.8 endpoints: - address: ${CLUSTER2_GW_ADDR} labels: cluster: cluster2 ports: http1: 15443 # Do not change this port value --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: helloworld-global spec: host: helloworld.hello.global trafficPolicy: tls: mode: ISTIO_MUTUAL subsets: - name: v2 labels: cluster: cluster2 - name: v3 labels: cluster: cluster2 EOF
在兩個集群上創(chuàng)建目標規(guī)則。在集群 cluster1 中創(chuàng)建子集 v1 對應的目標規(guī)則,執(zhí)行如下命令:
kubectl apply -n hello -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: helloworld spec: host: helloworld.hello.svc.cluster.local trafficPolicy: tls: mode: ISTIO_MUTUAL subsets: - name: v1 labels: version: v1 EOF
而在集群 cluster2 中創(chuàng)建子集 v2 和 v3 對應的目標規(guī)則,執(zhí)行如下命令:
kubectl apply -n hello -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: helloworld spec: host: helloworld.hello.svc.cluster.local trafficPolicy: tls: mode: ISTIO_MUTUAL subsets: - name: v2 labels: version: v2 - name: v3 labels: version: v3 EOF
創(chuàng)建虛擬服務以路由流量。
應用下面的虛擬服務將會使得來自用戶 jason 對 helloworld 的流量請求指向位于集群 cluster2 中的版本 v2 和 v3,其中 v2 比例為 70%,v3 比例為 30%;來自任何其他用戶對 helloworld 的流量請求都將轉到位于集群 cluster1 中的版本 v1:
kubectl apply -n hello -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: helloworld spec: hosts: - helloworld.hello.svc.cluster.local - helloworld.hello.global http: - match: - headers: end-user: exact: jason route: - destination: host: helloworld.hello.global subset: v2 weight: 70 - destination: host: helloworld.hello.global subset: v3 weight: 30 - route: - destination: host: helloworld.hello.svc.cluster.local subset: v1 EOF
執(zhí)行多次調用,可以從下面的執(zhí)行結果中看出,上述流量路由的規(guī)則生效,這也說明了在多控制平面拓撲下,用于路由的規(guī)則定義與在本地集群的使用方式是一樣的:
設置多集群網(wǎng)格的最簡單方法是使用多控制平面拓撲,因為它沒有特殊的網(wǎng)絡要求。通過上述示例可以看出,在單個 Kubernetes 集群上運行的路由功能同樣很容易地在多個集群中使用運行。
感謝各位的閱讀,以上就是“怎么使用Istio進行多集群部署管理”的內容了,經(jīng)過本文的學習后,相信大家對怎么使用Istio進行多集群部署管理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。