天天看點

第2篇----Istio架構概述篇

Istio的工作機制

Istio的工作機制和架構,分為控制面和資料面兩部分。控制面主要包括Pilot、Mixer、Citadel等服務元件;資料面由伴随每個應用程式部署的代理程式Envoy組成,執行針對應用程式的治理邏輯。

通過一個動态場景來了解工作機制,即觀察frontend服務對 forecast 服務進行一次通路時,在 Istio 内部都發生了什麼,以及 Istio 的各個元件是怎樣參與其中的,分别做了哪些事情。

帶圓圈的數字代表在資料面上執行的若幹重要動作。雖然從時序上來講,控制面的配置在前,資料面執行在後,但為了便于了解,在下面介紹這些動作時以資料面上的資料流為入口,介紹資料面的功能,然後講解涉及的控制面如何提供對應的支援,進而了解控制面上元件的對應功能。

第2篇----Istio架構概述篇

(1)自動注入:指在建立應用程式時自動注入 Sidecar代理。在 Kubernetes場景下建立 Pod時,Kube-apiserver調用管理面元件的 Sidecar-Injector服務,自動修改應用程式的描述資訊并注入Sidecar。在真正建立Pod時,在建立業務容器的同時在Pod中建立Sidecar容器。

(2)流量攔截:在 Pod 初始化時設定 iptables 規則,當有流量到來時,基于配置的iptables規則攔截業務容器的Inbound流量和Outbound流量到Sidecar上。應用程式感覺不到Sidecar的存在,還以原本的方式進行互相通路。流出frontend服務的流量會被 frontend服務側的 Envoy攔截,而當流量到達forecast容器時,Inbound流量被forecast服務側的Envoy攔截。

(3)服務發現:服務發起方的 Envoy 調用管理面元件 Pilot 的服務發現接口擷取目标服務的執行個體清單。frontend 服務側的 Envoy 通過 Pilot 的服務發現接口得到forecast服務各個執行個體的位址,為通路做準備。

(4)負載均衡:服務發起方的Envoy根據配置的負載均衡政策選擇服務執行個體,并連接配接對應的執行個體位址。資料面的各個Envoy從Pilot中擷取forecast服務的負載均衡配置,并執行負載均衡動作。

(5)流量治理:Envoy 從 Pilot 中擷取配置的流量規則,在攔截到 Inbound 流量和Outbound 流量時執行治理邏輯。frontend 服務側的 Envoy 從 Pilot 中擷取流量治理規則,并根據該流量治理規則将不同特征的流量分發到forecast服務的v1或v2版本。當然,這隻是Istio流量治理的一個場景,更豐富的流量治理能力後續講解。

(6)通路安全:在服務間通路時通過雙方的Envoy進行雙向認證和通道加密,并基于服務的身份進行授權管理。Pilot下發安全相關配置,在frontend服務和forecast服務的Envoy上自動加載證書和密鑰來實作雙向認證,其中的證書和密鑰由另一個管理面元件Citadel維護。

(7)服務遙測:在服務間通信時,通信雙方的Envoy都會連接配接管理面元件Mixer上報通路資料,并通過Mixer将資料轉發給對應的監控後端。frontend服務對forecast服務的通路監控名額、日志和調用鍊都可以通過這種方式收集到對應的監控後端。

(8)政策執行:在進行服務通路時,通過Mixer連接配接後端服務來控制服務間的通路,判斷對通路是放行還是拒絕。Mixer後端可以對接一個限流服務對從frontend服務到forecast服務的通路進行速率控制。

(9)外部通路:在網格的入口處有一個Envoy扮演入口網關的角色。外部服務通過Gateway通路入口服務 frontend,對 frontend服務的負載均衡和一些流量治理政策都在這個Gateway上執行。

總結以上過程中涉及的動作和動作主體,可以将其中的每個過程都抽象成一句話:服務調用雙方的Envoy代理攔截流量,并根據管理面的相關配置執行相應的治理動作,這也是Istio的資料面和控制面的配合方式。

Istio的服務模型

Istio支援将由服務、服務版本和服務執行個體構造的抽象模型映射到不同的平台上,這裡重點關注基于Kubernetes的場景。可以認為,Istio的幾個資源對象就是基于Kubernetes的相應資源對象建構的,加上部分限制來滿足Istio服務模型的要求。

Istio 官方對這幾個限制的描述如下:

◎ 端口命名:對 Istio 的服務端口必須進行命名,而且名稱隻允許是<protocol>[-<suffix>]這種格式,其中<protocol>可以是tcp、http、http2、https、grpc、tls、mongo、mysql、redis等,Istio根據在端口上定義的協定來提供對應的路由能力。例如“name:http2-forecast”和“name:http”是合法的端口名,但是“name:http2forecast”是非法的端口名。如果端口未命名或者沒有基于這種格式進行命名,則端口的流量會被當作TCP流量來處理。

◎ 服務關聯:Pod 需要關聯到服務,如果一個 Pod 屬于多個 Kubernetes 服務,則要求服務不能在同一個端口上使用不同的協定。在 Istio 0.8 之前的版本中要求一個Pod 隻能屬于一個 Kubernetes 服務,這種限制更簡單,也更能滿足絕大多數使用要求。

◎ Deployment使用app和version标簽:建議Kubernetes Deployment顯式地包含app和 version 标簽。每個 Deployment 都需要有一個有業務意義的 app 标簽和一個表示版本的version标簽。在分布式追蹤時可以通過app标簽來補齊上下文資訊,還可以通過app和version标簽為遙測資料補齊上下文資訊。

Istio的服務

從邏輯上看,服務是Istio主要管理的資源對象,是一個抽象概念,主要包含HostName和Ports等屬性,并指定了Service的域名和端口清單。每個端口都包含端口名稱、端口号和端口的協定。

在 Istio 中對不同的協定也有不同的治理規則集合,這也是Istio關于端口命名限制的機制層面的原因,具體來講就是要求将端口的協定通過“-”連接配接符加在端口名稱上。

從實體層面看,Istio服務的存在形式就是Kubernetes的Service,在啟用了Istio的叢集中建立 Kubernetes的 Service時隻要滿足以上限制,就可以轉換為 Istio的 Service并配置規則進行流量治理。

Service是Kubernetes的一個核心資源,使用者通過一個域名或者虛拟的IP就能通路到後端Pod,避免向使用者暴露Pod位址的問題,特别是在Kubernetes中,Pod作為一個資源建立、排程和管理的最小部署單元的封裝,本來就是動态變化的,在節點删除、資源變化等多種情況下都可能被重新排程,Pod的後端位址也會随之變化。

一個最簡單的Service示例如下:

apiVersion: v1
kind: Service
metadata:
  name: forecast
spec:
  ports:
  - port: 3002
    targetPort: 3002
  selector:
    app: forecast
           

如上所示建立了一個名稱為 forecast 的 Service,通過一個 ClusterIP 的位址就可以通路這個Service,指向有“app:forecast”标簽的Pods。Kubernetes自動建立一個和Service同名的Endpoints對象,Service的selector會持續關注屬于Service的Pod,結果會被更新到相應的Endpoints對象。

Istio的Service比較簡單,可以看到差别就是要滿足Istio服務的限制,并在端口名稱上指定協定。例如,在以下示例中指定了forecast服務的3002端口是HTTP,對這個服務的通路就可以應用HTTP的諸多治理規則:

apiVersion: v1
kind: Service
metadata:
  name: forecast
spec:
  ports:
  - port: 3002
    targetPort: 3002
    bane: http
  selector:
    app: forecast
           

Istio雖然依賴于Kubernetes的Service定義,但是除了一些限制,在定位上還有些差别。

在 Kubernetes中,一般先通過 Deploymnent建立工作負載,再通過建立 Service關聯這些工作負載,進而暴露工作負載的接口。因而看上去主體是工作負載,Service隻是一種通路方式,某些背景執行的負載若不需要被通路,就不用定義Service。

在Istio中,Service是治理的對象,是Istio中的核心管理實體,是以在Istio中,Service是一個提供了對外通路能力的執行體,可以将其了解為一個定義了服務的工作負載,沒有通路方式的工作負載不是Istio的管理對象,Kubernetes的Service定義就是Istio服務的中繼資料。

Istio的服務版本

在Istio的應用場景中,灰階釋出是一個重要的場景,即要求一個Service有多個不同版本的實作。而 Kubernetes在文法上不支援在一個 Deployment上定義多個版本,在 Istio中多個版本的定義是将一個Service關聯到多個Deployment,每個Deployment都對應服務的一個版本。

第2篇----Istio架構概述篇

在下面的執行個體中,forecast-v1 和 forecast-v2 這兩個 Deployment 分别對應服務的兩個版本:

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: forecast-v1
  labels:
    app: forecast
    version: v1
spec: 
  replicas: 3
  template:
    metadata:
      labels:
        app: forecast
        version: v1
    spec:
      containers:
      - name: forecast
        image: istioweather/forecast:v1
        ports:
        - containerPort: 3002
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: forecast-v2
  labels:
    app: forecast
    version: v2
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: forecast
        version: v2
    spec:
      containers:
      - name: forecast
        image: istioweather/forecast:v2
        ports:
        - containerPort: 3002
           

觀察和比較這兩個Deployment的描述檔案,可以看到:

◎ 這兩個Deployment都有相同的“app:forecast”标簽,正是這個标簽和Service的标簽選擇器一緻,才保證了Service能關聯到兩個Deployment對應的Pod。

◎ 這兩個 Deployment 都有不同的鏡像版本,是以各自建立的 Pod 也不同;這兩個Deployment的version标簽也不同,分别為v1和v2,表示這是服務的不同版本,這個不同的版本标簽用來定義不同的Destination,進而執行不同的路由規則。

下面根據對Service和兩個Deployment的如上定義分别建立3個Pod和兩個Pod,假設5個Pod都運作在兩個不同的Node上。在對Service進行通路時,根據配置的流量規則,可以将不同的流量轉發到不同版本的Pod上,如下圖所示:

第2篇----Istio架構概述篇

Istio的服務執行個體

服務執行個體是真正處理服務請求的後端,就是監聽在相同端口上的具有同樣行為的對等後端。服務通路時由代理根據負載均衡政策将流量轉發到其中一個後端處理。Istio 的ServiceInstance 主要包括 Endpoint、Service、Labels、AvailabilityZone 和 ServiceAccount等屬性,Endpoint 是其中最主要的屬性,表示這個執行個體對應的網絡後端(ip:port),Service表示這個服務執行個體歸屬的服務。

Istio的服務發現基于Kubernetes建構,Istio的Service對應Kubernetes的Service,Istio的服務執行個體對應Kubernetes的Endpoint。

第2篇----Istio架構概述篇

Kubernetes提供了一個 Endpoints對象,這個 Endpoints對象的名稱和 Service的名稱相同,它是一個<Pod IP>:<targetPort>清單,負責維護Service後端Pod的變化。如前面例子中介紹的,forecast服務對應如下Endpoints對象,包含兩個後端Pod,後端位址分别是172.16.0.16和 172.16.0.19,當執行個體數量發生變化時,對應的Subsets清單中的後端數量會動态更新;同樣,當某個Pod遷移時,Endpoints對象中的後端IP位址也會更新:

Istio的主要元件

如下所示是Istio 1.1在典型環境下的完整元件清單,本節将介紹其中每個元件的功能和機制。

第2篇----Istio架構概述篇

Istio-pilot

服務清單中的 istio-pilot是 Istio 的控制中樞 Pilot服務。如果把資料面的 Envoy 也看作一種Agent,則Pilot類似傳統C/S架構中的服務端Master,下發指令控制用戶端完成業務功能。和傳統的微服務架構對比,Pilot 至少涵蓋服務注冊中心和 Config Server 等管理元件的功能。

Pilot 直接從運作平台提取資料并将其構造和轉換成 Istio 的服務發現模型,是以Pilot隻有服務發現功能,無須進行服務注冊。這種抽象模型解耦了Pilot和底層平台的不同實作,可支援Kubernetes、Consul等平台。Istio 0.8還支援Eureka,但随着Eureka停止維護,Istio在1.0之後的版本中也删除了對Eureka的支援。

第2篇----Istio架構概述篇

除了服務發現,Pilot 更重要的一個功能是向資料面下發規則,包括 VirtualService、DestinationRule、Gateway、ServiceEntry 等流量治理規則,也包括認證授權等安全規則。Pilot 負責将各種規則轉換成 Envoy 可識别的格式,通過标準的 xDS 協定發送給 Envoy,指導Envoy完成動作。在通信上,Envoy通過gRPC流式訂閱Pilot的配置資源。如下圖所示,Pilot将 VirtualService表達的路由規則分發到 Evnoy上,Envoy根據該路由規則進行流量轉發。

第2篇----Istio架構概述篇