文章目錄
- 原理
- 實現
- Deployment
- VirtualService
- DestinationRule
- 約束
- 部署
目的: 根據不同的引擎版本,可以把請求發送到指定的引擎上。可以實現版本降級。
原理
Istio通過VirtualService和DestinationRule兩個資源對象來實現流量管理,其中VirtualService用于定義流量路由規則,而DestinationRule用于定義服務的負載均衡策略和TLS設置
- VirtualService: 實現服務請求路由規則的動能
- DestinationRule: 實現?標服務的負載均衡、服務發現、故障處理和故障注?的功能
- Gateway: 讓服務?格內的服務,可以被全世界看到
- ServiceEntry: 讓服務?格內的服務,可以看到外?的世界
實現
Deployment
{{- $revisionHistoryLimit := .Values.revisionHistoryLimit -}}
{{- $replicaCount := .Values.replicaCount -}}
{{- $autoscaling := .Values.autoscaling.enabled -}}
{{- $podAnnotations := .Values.podAnnotations -}}
{{- $imagePullSecrets := .Values.imagePullSecrets -}}
{{- $podSecurityContext := .Values.podSecurityContext -}}
{{- $securityContext := .Values.securityContext -}}
{{- $pullPolicy := .Values.pullPolicy -}}
{{- $port := .Values.service.port -}}
{{- $resources := .Values.resources -}}
{{- $nodeSelector := .Values.nodeSelector -}}
{{- $repository := .Values.image.repository -}}
{{- $affinity := .Values.affinity -}}
{{- $tolerations := .Values.tolerations -}}
{{- range $num,$tag := .Values.image.tag -}}
{{- $version := add $num 1 -}}
apiVersion: apps/v1
kind: Deployment
metadata:name: {{ include "grpc-manifest.fullname" $ }}-v{{ $version }}labels:{{- include "grpc-manifest.labels" $ | nindent 4 }}app.kubernetes.io/tag: v{{ $version }}app.kubernetes.io/type: grpc
spec:revisionHistoryLimit: {{ $revisionHistoryLimit | default 5 }}{{- if not $autoscaling }}replicas: {{ $replicaCount }}{{- end }}selector:matchLabels:{{- include "grpc-manifest.selectorLabels" $ | nindent 6 }}app.kubernetes.io/tag: v{{ $version }}app.kubernetes.io/type: grpc...{{end }}
作用:可以根據版本生成對應的服務
VirtualService
{{- define "grpc-manifest.gateway" -}}
{{- $port := .Values.services.port }}
{{- range $num,$image := .Values.image.tag }}
{{- $version := add $num 1 }}- match:- headers:grpcsvc:exact: v{{ $version }}route:- destination:host: {{ include "grpc-manifest.fullname" $ }}port:number: {{ $port }}subset: v{{ $version }}
{{- end }}
{{- end }}
例子中,虛擬服務將流量分發服務的兩個子集:v$version
。也可設置權重默認是 100
,表示 攜帶 header為grpcsvc: v$version
的流量將全量被路由到 v$version
DestinationRule
目標規則定義了如何將請求路由到實際的服務實例。每個目標規則關聯到一個虛擬服務的子集
{{- define "grpc-manifest.route" -}}
{{- range $num,$image := .Values.image.tag }}
{{- $version := add $num 1 }}- name: v{{ $version }}labels:app.kubernetes.io/instance: {{ include "grpc-manifest.fullname" $ }}app.kubernetes.io/tag: v{{ $version }}
{{- end }}
{{- end }}
例子中,目標規則將子集 v$version
分別映射到具有相應標簽的實際服務實例。
需要多個版本同時部署時,會根據鏡像自動更新資源配置
[root@ycloud grpc-manifest]# cat env/devel/image_tag.yaml
image:tag:- v1.0.1- v1.0.2- v1.0.3- v1.0.4
約束
根據定義好的行為實現
訪問通過添加metadata
的方式來選擇指定的版本,并且如果訪問中 metadata
指定有誤要做降級策略,給默認且可正常運行的版本
eg: (案例僅限測試,生產根據實際需求更新)
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: {{ include "grpc-manifest.fullname" . }}
spec:workloadSelector:labels:app: istio-ingressgatewayconfigPatches:- applyTo: HTTP_FILTERmatch:context: GATEWAYlistener:filterChain:filter:name: "envoy.filters.network.http_connection_manager"subFilter:name: "envoy.filters.http.router"patch:operation: INSERT_BEFOREvalue:name: envoy.filters.http.luatyped_config:"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"inlineCode: |function envoy_on_request(request_handle)local contentType = request_handle:headers():get("content-type")if contentType and string.find(contentType, "grpc") thenlocal grpcSvcHeader = request_handle:headers():get("grpcsvc")local allowedVersions = {"v1", "v2", "v3", "v4"}local isInAllowedVersions = falsefor _, allowedVersion in ipairs(allowedVersions) doif grpcSvcHeader == allowedVersion thenisInAllowedVersions = truebreakendendif not isInAllowedVersions thenrequest_handle:headers():replace("grpcsvc", "v1")endendend
部署
待實現 自動部署和之前服務有出入,需要針對這個服務做調整,主要判斷,通過版本引擎來自動更新舊版本
具體 Helm 案例屆時會更新到
GitHub