【 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

相关推荐
曦夜日长2 分钟前
Linux系统篇,进程概念(三):进程状态详解、僵尸进程与孤儿进程的深度解析、Slab机制的了解
linux·运维·服务器
wdfk_prog12 分钟前
VMware Ubuntu 虚拟机从 124 GB 压缩到 33 GB
运维·缓存·docker·容器
2601_9663771325 分钟前
等保2.0最新标准新增安全数据处理要求后怎么办?等保一体机数据安全模块来助力
运维·网络·安全·等保一体机
2601_9639067832 分钟前
桌面自动化工具|零代码录制自动化,无需联网本地离线用
运维·自动化
海宇AI33 分钟前
零信任架构实战:基于海宇公安二要素认证即时版构建自动化灵活用工准入网关
运维·人工智能·架构·自动化
杨云龙UP1 小时前
MySQL Host is blocked because of many connection errors 导致 JDBC 连接失败排查与解决
linux·运维·网络·数据库·sql·mysql·登录失败
snow@li1 小时前
CA证书是什么/数字证书/互联网上的电子身份证/Certificate Authority
运维
Allstar_432 小时前
全星研发项目管理APQP系统支持本地/私有云,开放API对接ERP/MES/PLM/OA,分级权限、版本追溯、ECN闭环,低代码配置,便于研发质量一体化扩展
运维
colourmind3 小时前
K3S+Hami+Higress+Vip(nginx+keepalived)搭建云原生高可用的大模型部署平台
运维·nginx·云原生
团子股股东峥哥3 小时前
day38-RHEL-管理存储堆栈
linux·运维·服务器