【 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

相关推荐
各类产品分享20 小时前
电力行业AR智能运维哪个品牌好
运维·ar·ar巡检
贾天佑忆月 迷失的昵20 小时前
客户端与服务器持续同步解析(轮询,comet,WebSocket)
运维·服务器·websocket
刘某的Cloud20 小时前
Galera Cluster mariadb 生产环境常见问题排查与运维指南
linux·运维·数据库·mariadb·集群高可用
雨辰AI21 小时前
K8s 国产数据库慢 SQL 自动监控|Prometheus+Grafana 可视化全落地
数据库·sql·安全·容器·kubernetes·grafana·prometheus
GGG76621 小时前
k8s的 Node and Cluster实战
容器·kubernetes
70asunflower21 小时前
Linux 性能排查分析完全教程
linux·运维
半支烟隐 pzishuo1 天前
Kubernetes Gateway API 完全指南
容器·kubernetes·gateway
兵bing1 天前
Docker Compose 配置文件归纳总结-千问
运维·docker·容器
INNOVIX稳石机器人1 天前
从“存得下”到“管得活”:稳石四向穿梭车如何重塑密集仓储新逻辑?
大数据·运维
2401_858286111 天前
OS81.【Linux】基于环形队列的多生产者-多消费者模型
linux·运维·服务器·环形队列