★ 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版本不會訪問星級評分服務。
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 (其他使用者)
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