ServiceMesh 3:路由控制(圖文總結)

Hello-Brand發表於2024-10-12

ServiceMesh系列

1 Istio部署

1.1 連線測試機

進入測試機伺服器...

1.2 安裝Istio

1.2.1 透過官方網站下載Istio

 # 下載最新版本的Istio
$ curl -L https://istio.io/downloadIstio | sh -

# 或者下載指定版本:
$ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.8.6 TARGET_ARCH=x86_64 sh -

1.2.2 檢查安裝目錄

如果安裝的是1.8.6的版本,我們就可以直接進入到這個目錄下,並檢視該目錄下的檔案資訊

[CCE~]$ cd /
[CCE~]$ cd /home/work/istio-1.8.6
[CCE~]$ ls -l

total 48
drwxr-x---  2 work work  4096 Nov  4 15:13 bin   # istioctl 客戶端二進位制檔案
-rw-r--r--  1 work work 11348 Nov  4 15:13 LICENSE
drwxr-xr-x  5 work work  4096 Nov  4 15:13 manifests
-rw-r-----  1 work work   767 Nov  4 15:13 manifest.yaml
-rw-r--r--  1 work work  4183 Nov  4 15:13 productpage
-rw-r--r--  1 work work  5866 Nov  4 15:13 README.md
drwxr-xr-x 19 work work  4096 Nov 16 10:49 samples  # 示例應用程式
drwxr-x---  3 work work  4096 Nov  4 15:20 tools  

1.2.3 環境變數配置

使用export生成環境變數PATH,將 istioctl 客戶端加入搜尋路徑

$ export PATH=$PWD/bin:$PATH

1.2.4 安裝Istio

使用 istioctl 安裝 Istio,可以看出,它不僅安裝了Istio核心主程式,還包含了以下幾個核心元件:

  • Istiod # 核心控制面
  • Egress gateways # 出流量路由
  • Ingress gateways # 入流量路由
[CCE~]$ istioctl install --set profile=demo -y

✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete

1.2.5 檢查是否安裝成功

預設的namespace 和 pod 應該已經正常建立(安裝istio的時候,會預設建立 istio-system 名稱空間),這邊確認下:

[root@k8s-master ~]# kubectl get ns |grep istio
istio-system      Active   82m
[root@k8s-master ~]# kubectl get pods -n istio-system
NAME                                    READY   STATUS    RESTARTS   AGE
istio-egressgateway-xxxxxxxxxx-xxxxx    1/1     Running   0          2m33s
istio-ingressgateway-xxxxxxxxxx-xxxxx   1/1     Running   0          2m33s
istiod--xxxxxxxxxx-xxxxx                1/1     Running   0          3m7s

1.2.6 安裝Istio自帶示例BookInfo

因為我們要測試圖書示例系統,所以我們建設一個恰當的名稱空間名稱:istio-booking-demo

[CCE~]$ kubectl create namespace istio-booking-demo  # Create a namespace
[CCE~]$ kubectl get namespace

NAME                 STATUS   AGE
default              Active   23d
icp                  Active   14d
ingress-nginx        Active   23d
istio-booking-demo   Active   16s
istio-system         Active   22d
kube-node-lease      Active   23d
kube-public          Active   23d
kube-system          Active   23d
local-path-storage   Active   23d

1.2.7 設定Pod自動注入SideCar

給名稱空間加上標籤,指示Istio在部署應用的時候,自動注入Evnoy SideCard代理。

[CCE~]$ kubectl label namespace istio-booking-demo istio-injection=enabled
namespace/istio-booking-demo labeled

★ 說明:這個代表該名稱空間(istio-booking-demo)下部署的Pod中都會自動注入Envoy資料面,即使沒有配置任何策略,流量依舊會被資料面Envoy攔截並透傳給服務。

1.2.8 設定別名,簡化操作

可以對某些名稱空間下的操作設定別名,避免每一次都輸入太長

[CCE~]$ alias kb='kubectl -n istio-booking-demo -o wide'  # 設定別名
[CCE~]$ alias kb  # 檢視別名
alias kb='kubectl -n istio-booking-demo -o wide'

1.3 部署例項應用

1.3.1 檢查示例目錄

檢視下Istio 自帶的BookInfo示例的地址,可以看到有好幾個目錄,如下:

[CCE~ kube]$ cd /
[CCE~ /]$ cd /home/work/istio-1.8.6/samples/bookinfo/
[CCE~ bookinfo]$ ls -l
total 32
-rwxr-xr-x 1 work work 4029 Nov  4 15:13 build_push_update_images.sh
drwxr-xr-x 2 work work 4096 Nov 16 10:11 networking
drwxr-xr-x 3 work work 4096 Nov  4 15:13 platform
drwxr-xr-x 2 work work 4096 Nov 16 15:04 policy
-rw-r--r-- 1 work work 1306 Nov  4 15:13 README.md
drwxr-xr-x 8 work work 4096 Nov 16 15:06 src
-rw-r--r-- 1 work work 6329 Nov  4 15:13 swagger.yaml

1.3.2 部署

部署Bookinfo 示例應用,應用bookinfo的yaml配置:

$ kb apply -f platform/kube/bookinfo.yaml

service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created

1.3.3 檢查部署結果

應用部署之後,檢查 Services 和 Pods 的部署情況,就可以發現,Pod準備就緒時,Istio的 邊車Envoy 會一起打包部署進去。
確保所有的 Pod 達到此狀態: 就緒狀態(READY)的值為 2/2 、狀態(STATUS)的值為 Running 。

[CCE~ bookinfo]$ kb get services
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE   SELECTOR
details       ClusterIP   10.11.12.111   <none>        9080/TCP   28d   app=details
productpage   ClusterIP   10.11.12.112   <none>        9080/TCP   28d   app=productpage
ratings       ClusterIP   10.11.12.113   <none>        9080/TCP   28d   app=ratings
reviews       ClusterIP   10.11.12.114    <none>        9080/TCP   28d   app=reviews
[CCE~ bookinfo]$ kb get pods
NAME                              READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
details-v1-xxxxxxxxxx-xxxxx        2/2     Running   0          28d   10.233.67.8    CCE.01   <none>           <none>
productpage-v1-xxxxxxxxxx-xxxxx   2/2     Running   0          28d   10.233.67.10   CCE.01   <none>           <none>
ratings-v1-xxxxxxxxxx-xxxxx        2/2     Running   0          22d   10.233.67.11   CCE.01   <none>           <none>
reviews-v1-xxxxxxxxxx-xxxxx       2/2     Running   0          28d   10.233.68.4    CCE.02   <none>           <none>
reviews-v2-xxxxxxxxxx-xxxxx       2/2     Running   0          22d   10.233.68.6    CCE.02   <none>           <none>
reviews-v3-xxxxxxxxxx-xxxxx         2/2     Running   0          28d   10.233.67.9    CCE.02   <none>           <none>

1.3.4 驗證安裝是否成功

驗證下是否安裝成功,看下是否某個頁面可以被讀取到

[CCE~ bookinfo]$ kubectl -n istio-booking-demo exec "$(kubectl -n istio-booking-demo get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>

1.3.5 配置流量Inbound

關聯Istio閘道器,並確保配置檔案正常,應用 bookinfo-gateway的yaml配置:

$ kubectl apply -f networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created
$ istioctl analyze
✔ No validation issues found when analyzing namespace: default.

1.3.6 繫結NodePort

獲取ingressgateway的詳細資訊,會發現 EXTERNAL-IP 為none,就直接改yaml,繫結nodePort的埠,對映為8601。驗證訪問

[CCE~]$ kb get svc istio-ingressgateway -n istio-system
NAME                   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                     AGE   SELECTOR
istio-ingressgateway   NodePort   10.233.32.219   <none>        15021:24534/TCP,80:8601/TCP,443:31159/TCP,31400:23074/TCP,15443:13324/TCP   28d   app=istio-ingressgateway,istio=ingressgateway
#  ========================================================

[CCE ~]$ kubectl edit svc istio-ingressgateway -n istio-system   # 編輯完輸入 :wq 退出
spec:
  clusterIP: 10.233.32.219
  externalTrafficPolicy: Cluster
  ports:
  - name: status-port
    nodePort: 24534
    port: 15021
    protocol: TCP
    targetPort: 15021
  - name: http2
    nodePort: 8601
    port: 80
    protocol: TCP
    targetPort: 8080
  - name: https
    nodePort: 31159
    port: 443
    protocol: TCP
    targetPort: 8443
  - name: tcp
    nodePort: 23074
    port: 31400
    protocol: TCP
    targetPort: 31400
  - name: tls
    nodePort: 13324
    port: 15443
    protocol: TCP
    targetPort: 15443
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  sessionAffinity: None
  type: NodePort

1.4 安裝儀表盤

應用服務安裝完成之後,需要安裝很多相關儀表板進行視覺化管理。包括 kiali監控 、k8s 儀表盤、Grafana(BI報表)、Jaeger Trace系統

1.4.1 Kiali 儀表盤安裝

[CCE~ samples]$ cd samples/addons
[CCE~ addons]$ ls -l # 包含4個視覺化系統:grafana、jaeger、kiali、prometheus
total 304
drwxr-xr-x 2 work work   4096 Nov  4 15:13 extras
-rw-r--r-- 1 work work 240054 Nov  4 15:13 grafana.yaml
-rw-r--r-- 1 work work   2317 Nov  4 15:13 jaeger.yaml
-rw-r--r-- 1 work work  35080 Nov  4 15:13 kiali.yaml
-rw-r--r-- 1 work work  13250 Nov  4 15:13 prometheus.yaml
-rw-r--r-- 1 work work   5186 Nov  4 15:13 README.md

# 安裝Kiali和其他外掛,等待部署完成!
$ kubectl apply -f samples/addons
$ kubectl rollout status deployment/kiali -n istio-system
Waiting for deployment "kiali" rollout to finish: 0 of 1 updated replicas are available...
deployment "kiali" successfully rolled out


# 訪問儀表盤,ctl+c 退出當前讀取
[CCE~ addons]$ istioctl dashboard kiali
http://localhost:20001/kiali
[CCE~ addons]$ istioctl dashboard grafana
http://localhost:3000
[CCE~ addons]$ istioctl dashboard jaeger
http://localhost:16686
[CCE~ addons]$ istioctl dashboard prometheus
http://localhost:9090
# 實際上的外部訪問地址跟 1.3.6 的做法一致
# 先查一下整個叢集的所有namespace的情況
$ kb get service --all-namespaces
# 查一下具體的服務資訊
$ kb get service --all-namespaces | grep grafana
# 進行nodePart埠繫結
$ kubectl edit svc grafana -n istio-system  # nodePort的埠繫結 8663
$ kubectl edit svc kiali -n istio-system  # nodePort的埠繫結 8661
$ kubectl edit svc prometheus -n istio-system # nodePort的埠繫結 8664
$ kubectl edit svc tracing -n istio-system # nodePort的埠繫結 8665,jaeger

備註:官方也提供了部署的步驟,可以參考下 搭建步驟

2 Istio能力介紹

2.1 簡要介紹

Istio具備豐富的流量治理能力,可以參考官方提供的豐富的測試案例,包含但不限於請求路由配置、故障注入、流量轉移、TCP 流量轉移、請求超時、熔斷、流量映象、地域負載均衡、Ingress+Egress

2.2 請求路由配置

2.2.1 請求路由排程

請求路由中有一種普遍的需求:就是把讓不同的使用者群體看到的資訊不一樣,比如VIP使用者和普通使用者看到的內容不一樣,折扣價也不一樣;又比如登入使用者和未登入使用者看到的資訊也不一樣。

2.2.1 路由初始化

先應用 virtual-service-all-v1,會把所有請求流量都指向版本1的服務(即Virtual Service版本都指向v1),virtual-service-all-v1.yaml

應用yaml

[CCE ~]$ cd /
[CCE /]$ cd /home/work/istio-1.8.6/samples/bookinfo/
[CCE bookinfo]$ kubectl -n istio-booking-demo apply -f networking/virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage unchanged
virtualservice.networking.istio.io/reviews unchanged
virtualservice.networking.istio.io/ratings unchanged
virtualservice.networking.istio.io/details unchanged

路由規則

[CCE bookinfo]$ kb get virtualservices -o yaml # 檢視所有的virtualservices
[CCE bookinfo]$ kb get destinationrules -o yaml # 檢視所有的destinationrules
[CCE bookinfo]$ kb get virtualservices reviews -o yaml # 檢視reviews的virtualservices
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata: # 資料不重要,這邊遮蔽掉
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination: # 指向 reviews 服務的v1版本
        host: reviews
        subset: v1
[CCE bookinfo]$ kb get virtualservices ratings -o yaml # 檢視ratings的virtualservices
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata: # 資料不重要,這邊遮蔽掉
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:  # 指向 ratings 服務的v1版本
        host: ratings
        subset: v1

開啟 介面,你會發現無論怎麼重新整理頁面,都不會顯示星級,那是因為reviews:v1版本不會訪問星級評分服務。
image

2.2.2 基於使用者身份的路由

做一下調整,讓Jason使用者的流量轉發到 reviews:v2,具體做法是請求Header中 end-user 有具體的人員名稱Jason。 virtual-service-reviews-test-v2.yaml

[CCE bookinfo]$ kubectl -n istio-booking-demo apply -f networking/virtual-service-reviews-test-v2.yaml
virtualservice.networking.istio.io/reviews configured
[CCE bookinfo]$ kb get virtualservices reviews -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata: # 資料不重要,這邊遮蔽掉
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers: # header中帶end-user並且值為jason使用者的流量走v2版本,其他走v1版本
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

對比一下2.2.1,你會發現差別,這邊的reviews服務的在特定的jason使用者下會走到v2版本中,效果如下,可以看到ratings服務的星星評價了。

  • productpage → reviews:v2 → ratings (針對 jason 使用者)
  • productpage → reviews:v1 (其他使用者)

image

image

2.2.3 清除應用程式 Virtual Service

如果不需要規則可以直接刪除,刪除完,所有的路由規則都不存在了,只剩各個Pod之間的SideCar攔截。

[CCE bookinfo]$ kubectl -n istio-booking-demo delete -f networking/virtual-service-all-v1.yaml

3 總結

本文介紹了Istio的部署和簡單的路由實現,後續的章節將探索更多精彩的內容。

  • 複雜路由排程
  • 故障注入
  • 流量轉移
  • TCP 流量轉移
  • 請求超時
  • 熔斷
  • 流量映象
  • 地域負載均衡
  • Ingress+Egress
  • ServiceEntry

相關文章