【 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

相关推荐
bitbrowser7 小时前
Facebook 验证反复回到原页面,应该从哪里排查
运维·服务器·facebook
Land03298 小时前
AI网页元素变化无法自动修复?自带元素自愈的自动化解决方案
运维·人工智能·ai·自动化·rpa
fengyehongWorld8 小时前
Jenkins 安装与简单配置
运维·jenkins
云智慧AIOps社区8 小时前
2026 国产化 ITSM 替代指南:横向测评 ServiceNow、轻帆云、Jira等五款主流IT服务管理平台
运维·人工智能·运维开发·it服务管理·itsm平台
Urbano8 小时前
针织卫衣全流程生产工序科普:自动化替代、产能优化与设备选型实战方案
运维·自动化
AC赳赳老秦9 小时前
招投标公开数据自动化采集实战:基于 OpenClaw 的定时抓取与业务关键词精准推送
运维·服务器·数据库·自动化·测试用例·deepseek·openclaw
小的博客9 小时前
windows下安装Docker Desptop
运维·docker·容器
酷可达拉斯9 小时前
Linux操作系统-shell编程(0)
linux·运维·服务器·python·云计算
2301_777998349 小时前
Linux中断机制:操作系统如何高效运行
linux·运维·服务器
Zhu7589 小时前
在k8s环境部署Apache zookeeper3.9.5,高可用,多pod
容器·kubernetes·apache