【 Kubernetes 风云录 】- Istio 应用多版本流量控制

文章目录

目的: 根据不同的引擎版本,可以把请求发送到指定的引擎上。可以实现版本降级。

原理

Istio通过VirtualService和DestinationRule两个资源对象来实现流量管理,其中VirtualService用于定义流量路由规则,而DestinationRule用于定义服务的负载均衡策略和TLS设置

  • VirtualService: 实现服务请求路由规则的动能
  • DestinationRule: 实现⽬标服务的负载均衡、服务发现、故障处理和故障注⼊的功能
  • Gateway: 让服务⽹格内的服务,可以被全世界看到
  • ServiceEntry: 让服务⽹格内的服务,可以看到外⾯的世界

实现

Deployment

shell 复制代码
{{- $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

yaml 复制代码
{{- 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

目标规则定义了如何将请求路由到实际的服务实例。每个目标规则关联到一个虚拟服务的子集

yaml 复制代码
{{- 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 分别映射到具有相应标签的实际服务实例。

需要多个版本同时部署时,会根据镜像自动更新资源配置

yaml 复制代码
[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: (案例仅限测试,生产根据实际需求更新)

yaml 复制代码
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name:  {{ include "grpc-manifest.fullname" . }}
spec:
  workloadSelector:
    labels:
      app: istio-ingressgateway
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: GATEWAY
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
              subFilter:
                name: "envoy.filters.http.router"
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.http.lua
          typed_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") then
                  local grpcSvcHeader = request_handle:headers():get("grpcsvc")
                  
                  local allowedVersions = {"v1", "v2", "v3", "v4"}
                  
                  local isInAllowedVersions = false
                  for _, allowedVersion in ipairs(allowedVersions) do
                    if grpcSvcHeader == allowedVersion then
                      isInAllowedVersions = true
                      break
                    end
                  end
                  
                  if not isInAllowedVersions then
                    request_handle:headers():replace("grpcsvc", "v1")
                  end
                end
              end

部署

待实现 自动部署和之前服务有出入,需要针对这个服务做调整,主要判断,通过版本引擎来自动更新旧版本

具体 Helm 案例届时会更新到 GitHub

相关推荐
蓝胖的四次元口袋18 分钟前
Docker Compose多容器编排与Nginx集群实战
运维·nginx·docker compose
懂软件的胡子个哥32 分钟前
微信 API 消息回调怎么设计,才能避免丢消息和重复处理
运维·微信·架构·wechatapi·个人微信号二次开发
吉甫作诵38 分钟前
Redis 常用命令大全:11 大类命令速查手册
运维·数据库·redis·缓存·nosql
Acrellea2 小时前
告别粗放式能耗管理!安科瑞EIOT平台助力产业园区智慧低碳运营
运维·安全·能源
Databuff3 小时前
五款主流 SSH 免费工具介绍
运维·ssh·运维开发
菜鸟学编程o3 小时前
Linux常见指令
linux·运维·服务器
pt10434 小时前
AIOps机器学习——当警报阈值被调高之后
运维·人工智能·自动化
迪康coolmu4 小时前
企业文件外发管控落地实践 —— 基于迪康端点安全一体化管理系统
运维·网络·经验分享·安全
见闻小天地5 小时前
四方电气DL300变频器面向雕铣机多工况的技术参数与适配验证
运维·人工智能·业界资讯
千舟软件6 小时前
【宿舍管理小程序】新生入住不靠纸质表
大数据·运维·服务器·科技·业界资讯