Service Mesh之Istio基礎入門

2023-04-03 21:02:33

  技術背景

  分散式服務治理

  所謂分散式服務治理就是對服務不斷增長的複雜度的管控和管理;管控及管理包含網路拓撲變動、網路延時、通訊安全、API閘道器、服務註冊和發現、服務熔斷容錯、服務超時重試、服務部署、資料呼叫、分散式鏈路追蹤等等;

  服務治理歷程

  第一代服務治理(內嵌應用程式中)

  提示:第一代服務治理能力的程式碼是內嵌在業務程式碼中,即所有的服務治理功能需要程式設計師自己編寫;典型技術:SOA、ESB;這種服務治理的優勢就是簡單使用依賴少;劣勢是程式碼耦合,重複性較高,運維複雜,解耦差,開發要求高;

  第二代服務治理(統一抽象成SDK)

  提示:第二代服務治理是把服務治理能力抽象到統一SDK實現,開發人員可以根據SDK中的api來寫業務程式碼,從而使對應業務具有服務治理的功能;典型技術:Spring Cloud、Dubbo等;這種服務治理的優勢是程式碼重複少,治理邏輯程式碼和業務程式碼分開;劣勢是SDK語言繫結,程式碼侵入;基於SDK開發學習門檻較高;系統改造代價大,治理能力升級影響使用者業務(即SDK升級,會導致業務程式碼的升級);

  第三代服務治理(統一到Sidecar)

  提示:第三代服務治理能力統一到服務網格上;即服務治理的能力,通過在業務程式碼周邊執行一個獨立的sidecar來完成;程式設計師只需要關注自己的業務程式碼的開發,服務治理能力就交給sidecar服務網格來完成;第三代服務治理的優勢是獨立程序,使用者業務非侵入,開發和語言無關(只要能夠完成對應的業務功能,用什麼語言都可以);治理邏輯升級對業務沒有影響;可以漸進的微服務化;劣勢就是效能和資源的開銷;

  服務網格(Service Mesh)
  服務網格概念源於Buoyant公司的CEO Willian Morgan的文章「What's a service mesh? And do I need one?」;是指專注於處理服務間通訊的基礎設施,它負責在現代雲原生應用組成的複雜拓撲中可靠地傳遞請求;治理模式除了處理業務邏輯的相關功能外,每個微服務還必須實現此前單體應用模型中用於網路間通訊的基礎功能,甚至還包括分散式應用程式之間的通訊環境中應該實現的其它網路功能,例如熔斷、限流、應用跟蹤、指標採集、服務發現和負載均衡等;
  服務網格的基本功能
  控制服務間通訊: 熔斷、重試、超時、故障注入、負載均衡和故障轉移等;
  服務發現:通過專用的服務匯流排發現伺服器端點;
  可觀測:指標資料採集、監控、分散式紀錄檔記錄和分散式追蹤;
  安全性:TLS/SSL通訊和金鑰管理;
  身份認證和授權檢查:身份認證,以及基於黑白名單或RBAC的存取控制功能;
  部署:對容器技術的原生支援,例如Docker和Kubernetes等;
  服務間的通訊協定:HTTP 1.1、HTTP 2.0和gRPC等;
  健康狀態檢測:監測上游服務的健康狀態;
  Service Mesh的雛形

  提示:在微服務體系架構中,我們為每個服務都使用一個專用的代理Sidecar來完成高階網路功能;各服務間僅通過Sidecar代理互相通訊,各個代理代理之間形成一個網狀網路,2017年,William為其建立一個專用的定義,並稱之為Service Mesh;

  提示:新一代服務網格架構分為控制平面和資料平面兩個部分;資料平面觸及系統中的每個封包或請求,負責服務發現、健康檢查、路由、負載均衡、身份驗證/授權和可觀測性等;控制平面主要為網格中的所有正在執行的資料平面提供策略和設定,從而將所有資料平面聯合構建為分散式系統,它不接觸系統中的任何封包或請求;控制平面負責的任務包括例如確定兩個服務Service X到Sevice Y之間的路由,Service Y相關叢集的負載均衡機制、斷路策略、流量轉移機制等,並將決策下發給Service X和Service Y的Sidecar;

  控制平面元件

  工作負載排程程式:藉助於底層的基礎設施(例如kubernetes)完成服務及其Sidecar執行位置的排程決策;
  服務發現:服務網格中的服務發現;
  Sidecar代理設定API:各Sidecar代理以最終一致的方式從各種系統元件獲取設定;
  控制平面UI:管理人員的操作介面,用於設定全域性級別的設定,例如部署、身份認證和授權、路由及負載均衡等;
  Service Mesh解決方案極大降低了業務邏輯與網路功能之間的耦合度,能夠快捷、方便地整合到現有的業務環境中,並提供了多語言、多協定支援,運維和管理成本被大大壓縮,且開發人員能夠將精力集中於業務邏輯本身,而無須再關注業務程式碼以外的其它功能;一旦啟用Service Mesh,服務間的通訊將遵循以下通訊邏輯;
  1、微服務彼此間不會直接進行通訊,而是由各服務前端的稱為Service Mesh的代理程式進行;
  2、Service Mesh內建支援服務發現、熔斷、負載均衡等網路相關的用於控制服務間通訊的各種高階功能;
  3、Service Mesh與程式語言無關,開發人員可以使用任何程式語言編寫微服務的業務邏輯,各服務之間也可以使用不同的程式語言開發;
  4、服務間的通訊的區域性故障可由Service Mesh自動處理;
  5、Service Mesh中的各服務的代理程式由控制平面(Control Plane)集中管理;各代理程式之間的通訊網路也稱為資料平面(Data Plane);
  6、部署於容器編排平臺時,各代理程式會以微服務容器的Sidecar模式執行;
  服務網格和K8S間的關係

  提示:k8s主要負責解決容器編排與排程的問題,本質上是應用程式生命週期工具,為服務網格提供基礎支撐;Service Mesh 主要解決分散式應用間的通訊問題,本質上服務通訊治理工具,是k8s在網路功能方面的擴充套件和延伸;

  Istio是什麼?

  Istio是Envoy Data Plane的控制平面實現之一,Istio是一個開源的獨立服務網格,可為使用者成功執行分散式微服務架構提供所需的基礎設施;Istio可以輕鬆建立帶有負載均衡、service-to-service的身份認證、細粒度的可觀測性等功能的服務網格,而應用程式程式碼卻無須或很少為些而作出改變;通過在整個服務環境中為每一個應用部署一個特殊的Sidecar形式的Proxy攔截各服務之間的所有網路通訊,並由控制平面Istio進行設定和管理,進而為服務無侵入式新增如下功能;
  1、HTTP、gRPC、WebSocket和TCP通訊的自動負載均衡;
  2、通過豐富的路由規則、重試、故障轉移和故障注入對流量進行細粒度控制;
  3、支援存取控制、速率限制和配額的可插拔的策略層及設定API;
  4、叢集內所有流量的自動度量、記錄紀錄檔和分散式跟蹤跟蹤,包括叢集的入口和出口;
  5、強大身份驗證和授權,以及在群集中進行安全的服務間通訊;
  在kubernetes環境中,服務網格就像一個儀表板,用於解決問題、執行流量策略、分配限制和測試程式碼,它允許一箇中央節點來監視、跟蹤和控制所有服務之間的互動;
  Istio系統架構

  提示:Istio服務網格主要有兩部分組成,控制平面和資料平面;控制平面核心程式istiod,主要是用於管控資料平面envoy proxy;資料平面envoy proxy主要管控主容器的進出流量;envoy proxy由控制平面istiod下發設定實現流量管控,同時它還能夠發現服務網格中的其他設定和服務,也能夠收集對應的指標資料;

  istio體驗環境部署

  環境說明

  kubernetes:v1.26.3

  docker :23.0.1

  cri-dockerd:0.3.0

  istio:1.17.1

  下載istio使用者端程式包

root@k8s-master01:/usr/local# curl -L https://istio.io/downloadIstio | sh -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   102  100   102    0     0    100      0  0:00:01  0:00:01 --:--:--   100
100  4856  100  4856    0     0   2347      0  0:00:02  0:00:02 --:--:--  9429

Downloading istio-1.17.1 from https://github.com/istio/istio/releases/download/1.17.1/istio-1.17.1-linux-amd64.tar.gz ...

Istio 1.17.1 Download Complete!

Istio has been successfully downloaded into the istio-1.17.1 folder on your system.

Next Steps:
See https://istio.io/latest/docs/setup/install/ to add Istio to your Kubernetes cluster.

To configure the istioctl client tool for your workstation,
add the /usr/local/istio-1.17.1/bin directory to your environment path variable with:
         export PATH="$PATH:/usr/local/istio-1.17.1/bin"

Begin the Istio pre-installation check by running:
         istioctl x precheck 

Need more information? Visit https://istio.io/latest/docs/setup/install/ 
root@k8s-master01:/usr/local# 

  提示:使用上述命令,請先確定你的終端是否能夠正常連線到istio的官方網站;

  建立連結,將istioctl命令連結至/usr/bin/目錄下

root@k8s-master01:/usr/local# ls
bin  etc  games  include  istio-1.17.1  lib  man  sbin  share  src
root@k8s-master01:/usr/local# ln -sv istio-1.17.1 istio
'istio' -> 'istio-1.17.1'
root@k8s-master01:/usr/local# ls
bin  etc  games  include  istio  istio-1.17.1  lib  man  sbin  share  src
root@k8s-master01:/usr/local# cd istio
root@k8s-master01:/usr/local/istio# ls
bin  LICENSE  manifests  manifest.yaml  README.md  samples  tools
root@k8s-master01:/usr/local/istio# ln -sv /usr/local/istio/bin/istioctl /usr/bin/
'/usr/bin/istioctl' -> '/usr/local/istio/bin/istioctl'
root@k8s-master01:/usr/local/istio# 

  提示:連結至/usr/bin/目錄下是因為後續方便istioctl命令的使用;

  列出profile

root@k8s-master01:/usr/local/istio# cd
root@k8s-master01:~# istioctl profile list
Istio configuration profiles:
    ambient
    default
    demo
    empty
    external
    minimal
    openshift
    preview
    remote
root@k8s-master01:~# 

  提示:測試環境我們使用demo即可,生產環境使用default;

  安裝istio

root@k8s-master01:~# istioctl install --set profile=demo -y
✔ Istio core installed                                                                                                                     
✔ Istiod installed                                                                                                                         
✔ Egress gateways installed                                                                                                                
✔ Ingress gateways installed                                                                                                               
✔ Installation complete                                                                                                                    
Making this installation the default for injection and validation.

Thank you for installing Istio 1.17.  Please take a few minutes to tell us about your install/upgrade experience!  https://forms.gle/hMHGiwZHPU7UQRWe9

  驗證:istio-system名稱空間中是否有pod running?

root@k8s-master01:~# kubectl get pods -n istio-system
NAME                                   READY   STATUS    RESTARTS   AGE
istio-egressgateway-774d6846df-fv97t   1/1     Running   0          21m
istio-ingressgateway-69499dc-pdgld     1/1     Running   0          21m
istiod-65dcb8497-9skn9                 1/1     Running   0          26m
root@k8s-master01:~# 

  驗證:istio 版本資訊

root@k8s-master01:~# istioctl version 
client version: 1.17.1
control plane version: 1.17.1
data plane version: 1.17.1 (2 proxies)
root@k8s-master01:~# 

  提示:可以看到現在資料平面有兩個代理,這是因為我們安裝istio時,在istio-system名稱空間下執行了一個ingressgateway和egressgateway pod,這兩個pod就是istio的資料平面,istiod是控制平面;

  檢視istio-system名稱空間下建立的服務資源

  提示:可以看到ingressgateway 處於pending狀態,這是因為沒有設定外部IP地址;

  修改ingressgateway閘道器地址

~# kubectl edit svc istio-ingressgateway -n istio-system

  提示:在spec欄位下,找一個位置加上externalIPs欄位,來指定一個IP地址即可;這個IP地址必須是叢集節點空餘IP地址;

  驗證:檢視istio-system名稱空間下的svc 看看對應ingressgateway 外部IP地址是否修改?

root@k8s-master01:~# kubectl get svc -n istio-system                      
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                                                      AGE
istio-egressgateway    ClusterIP      10.106.179.126   <none>          80/TCP,443/TCP                                                               34m
istio-ingressgateway   LoadBalancer   10.102.211.120   192.168.0.252   15021:32639/TCP,80:31338/TCP,443:30597/TCP,31400:31714/TCP,15443:32154/TCP   34m
istiod                 ClusterIP      10.96.6.69       <none>          15010/TCP,15012/TCP,443/TCP,15014/TCP                                        39m
root@k8s-master01:~# 

  提示:可以看到ingressgateway 對應外部IP地址就修改成我們剛才指定的IP地址了;

  為default名稱空間打標籤,允許istio注入envoy sidecar

root@k8s-master01:~# kubectl label namespace default istio-injection=enabled
namespace/default labeled
root@k8s-master01:~# kubectl get ns --show-labels
NAME              STATUS   AGE   LABELS
default           Active   14h   istio-injection=enabled,kubernetes.io/metadata.name=default
istio-system      Active   47m   kubernetes.io/metadata.name=istio-system
kube-node-lease   Active   14h   kubernetes.io/metadata.name=kube-node-lease
kube-public       Active   14h   kubernetes.io/metadata.name=kube-public
kube-system       Active   14h   kubernetes.io/metadata.name=kube-system
root@k8s-master01:~# 

  提示:這個名稱空間可以根據自己的環境來;我們在給那個名稱空間打上上述標籤,對應在那個名稱空間下部署pod都會注入一個sidecar而實現service mesh功能;

  測試:在defuault名稱空間下,部署一個pod,看看對應是否會給注入一個sidecar呢?

root@k8s-master01:~# kubectl run test --image=nginx --restart=Never 
pod/test created
root@k8s-master01:~# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
test   2/2     Running   0          37s
root@k8s-master01:~# 

  提示:可以看到我們在default名稱空間下跑了一個nginx pod,對應pod裡有兩個容器;

  驗證:檢視pod的詳細資訊,是否注入了envoy proxy容器?

  提示:我們可以看到pod裡除了有nginx映象,還有一個istio/proxy,這個容器就是istiod注入至nginx pod中,從而實現高階流量管理;至此istio的部署就基本完成;