前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flagger 在 Kubernetes 集群上是如何工作的?

Flagger 在 Kubernetes 集群上是如何工作的?

原创
作者头像
philentso
修改2022-12-26 15:10:50
2.1K0
修改2022-12-26 15:10:50
举报
文章被收录于专栏:philentso

通过前面一节的 Flagger基本学习,这节学习它的工作原理,以帮助加深理解应用!

Flagger 是如何工作的-工作原理?

可以通过一个名为 canary 的自定义资源来配置 Kubernetes 工作负载的自动化发布过程.

Canary resource

Canary 自定义资源定义了在 Kubernetes 上运行的应用程序的释放过程,并且可以across clusters, service meshes 和 ingress providers 进行移植.

对于名为 podinfo 的 deployment ,带有渐进式流量转移的 Canary 发布可以定义为:

代码语言:javascript
复制
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  service:
    port: 9898
  analysis:
    interval: 1m
    threshold: 10
    maxWeight: 50
    stepWeight: 5
    metrics:
      - name: request-success-rate
        thresholdRange:
          min: 99
        interval: 1m
      - name: request-duration
        thresholdRange:
          max: 500
        interval: 1m
    webhooks:
      - name: load-test
        url: http://flagger-loadtester.test/
        metadata:
          cmd: "hey -z 1m -q 10 -c 2 http://podinfo-canary.test:9898/"

当 deployment 一个新版本的应用时,Flagger 会逐渐将流量转移到 Canary,同时测量请求成功率以及平均响应时间,可以通过自定义指标、验收和负载测试来扩展 Canary 的分析,以加强应用发布过程的验证过程

如果在同一个集群中运行多个服务网格或入口控制器,可以用 spec.provider 覆盖特定 canary 的全局提供者

Canary target

Canary 资源可以针对 Kubernetes Deployment 或 DaemonSet

Kubernetes Deployment 的例子:

代码语言:javascript
复制
spec:
  progressDeadlineSeconds: 60
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  autoscalerRef:
    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    name: podinfo

基于上述配置,Flagger 生成了以下 Kubernetes对象:

. deployment/<targetRef.name>-primary

. hpa/<autoscalerRef.name>-primary

primary deployment 被认为是应用程序的稳定版本,默认情况下,所有流量都被路由到这个版本,而 target deployment 被扩展为 0, Flagger 会检测到target deployment 的变化(包括secrets 和 configmaps),并在将新版本提升为 primary 版本之前进行 Canary 分析.

注意,target deployment 必须有一个单一的 label selector,格式为 app: <DEPLOYMENT-NAME>:

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: podinfo
spec:
  selector:
    matchLabels:
      app: podinfo
  template:
    metadata:
      labels:
        app: podinfo

除了 app 之外,Flagger 还支持 name 和 app.kubernetes.io/name 选择器, 如果使用不同的约定,可以在 Flagger deployment 清单中容器 args 下的 -selector-labels=my-app-label 命令标志来指定标签,或者在用 Helm 安装 Flagger 时设置 --set selectorLabels=my-app-label

如果 target deployment 使用 secrets 或 configmaps,Flagger 将使用 -primary 后缀创建每个对象的副本并在 primary deployment 中引用这些对象,

如果用 flagger.app/config-tracking: disabled 来注释 ConfigMap 或 Secret,Flagger 将在 primary deployment 中使用相同的对象而不是制作 primary 副本,

可以在 Flagger deployment 清单中的 containers args 下使用 -enable-config-tracking=false 命令标志全局禁用 secrets/configmaps 跟踪,或者在用 Helm 安装 Flagger 时设置,

-set configTracking.enabled=false,但使用每个 Secret/ConfigMap 注释禁用 config-tracking 可能更符合使用情况

autoscaler 的引用是可选的,当指定时, Flagger 将暂停流量的增加,同时 target 和 primary deployment 被放大或缩小, HPA 可以帮助减少在 canary 分析过程中的资源使用,

当指定 autoscaler 参考时,对 autoscaler 的任何改变只有在 deployment 的 rollout 开始并成功完成时才会在 primary autoscaler 中被激活,

可以选择创建两个 HPA,一个用于 canary,一个用于 primary,以更新 HPA 而不做新的展开, 由于 Canary 的 deployment 将被缩减到 0,Canary 上的 HPA 将不活跃

注意: Flagger 需要 HPA 的 autoscaling/v2 或 autoscaling/v2beta2 API 版本

进度截止日期表示 Canary deployment 在回滚前取得进展的最大时间(秒),默认为 10 分钟。

Canary service

Canary 资源决定了 target 工作负载在集群内的暴露方式, Canary target 应该暴露一个 TCP 端口,该端口将被 Flagger 用来创建 ClusterIP 服务:

代码语言:javascript
复制
spec:
  service:
    name: podinfo
    port: 9898
    portName: http
    appProtocol: http
    targetPort: 9898
    portDiscovery: true

来自 target 工作负载的容器端口应该与 service.port 或 service.targetPort 匹配, service.name 是可选的,默认为 spec.targetRef.name, service.targetPort 可以是一个容器端口号或名称service.portName 是可选的(默认为 http),如果工作负载使用 gRPC,则将端口名称设为 grpc, service.appProtocol 是可选的,更多细节可以在 这里 找到

如果启用了端口发现功能,Flagger 会扫描 target 工作负载并提取容器端口,但不包括 canary service 和 service mesh sidecar 端口中指定的端口, 这些端口将在生成 ClusterIP 服务时使用。

基于 canary 规格的服务,Flagger 创建以下 Kubernetes ClusterIP 服务:

. <service.name>.<namespace>.svc.cluster.local

代码语言:txt
复制
selector app=<name>-primary

. <service.name>-primary.<namespace>.svc.cluster.local

代码语言:txt
复制
selector app=<name>-primary

. <service.name>-canary.<namespace>.svc.cluster.local

代码语言:txt
复制
selector app=<name>

这确保了到 podinfo.test:9898 的流量将被路由到应用程序的最新稳定版本, podinfo-canary.test:9898 地址只在 canary 分析期间可用,可用于一致性测试或负载测试

可以配置 Flagger 来为生成的服务设置annotations 和 labels:

代码语言:javascript
复制
spec:
  service:
    port: 9898
    apex:
      annotations:
        test: "test"
      labels:
        test: "test"
    canary:
      annotations:
        test: "test"
      labels:
        test: "test"
    primary:
      annotations:
        test: "test"
      labels:
        test: "test"

请注意,apex 注解被添加到生成的 Kubernetes 服务和生成的 service mesh/ingress 对象, 这允许在 Istio VirtualService 和 TraefikServices 中使用外部 DNS,

要注意 这里 的配置冲突

除了端口映射和元数据,service specification 可以包含 URI 匹配和重写规则、超时和重试策略:

代码语言:javascript
复制
spec:
  service:
    port: 9898
    match:
      - uri:
          prefix: /
    rewrite:
      uri: /
    retries:
      attempts: 3
      perTryTimeout: 1s
    timeout: 5s

当使用 Istio 作为网格提供者时,还可以指定 HTTP头操作、CORS 和流量策略、Istio 网关和 hosts, Istio 的路由配置可以在 这里 找到

Canary status

可以使用 kubectl 来获取集群范围内 canary deployment 的当前状态:

代码语言:javascript
复制
kubectl get canaries --all-namespaces

状态条件反映了 Canary 分析的最后已知状态:

代码语言:javascript
复制
kubectl -n test get canary/podinfo -oyaml | awk '/status/,0'

一个成功的 rollout 状态:

代码语言:javascript
复制
status:
  canaryWeight: 0
  failedChecks: 0
  iterations: 0
  lastAppliedSpec: "14788816656920327485"
  lastPromotedSpec: "14788816656920327485"
  conditions:
  - lastTransitionTime: "2019-07-10T08:23:18Z"
    lastUpdateTime: "2019-07-10T08:23:18Z"
    message: Canary analysis completed successfully, promotion finished.
    reason: Succeeded
    status: "True"
    type: Promoted

促成状态条件可以有以下原因之一:Initialized(初始化)、Waiting(等待)、Progressing(进展)、WaitingPromotion(等待推广)、Promotion(推广)、Finalising(最终完成)、Succeeded(成功)或 Failed(失败),失败的 Canary 将把推广状态设置为 false,原因为 failed,最后应用的规格将与最后推广的规格不同

等待成功推广:

代码语言:javascript
复制
kubectl wait canary/podinfo --for=condition=promoted

CI example:

代码语言:javascript
复制
# update the container image
kubectl set image deployment/podinfo podinfod=stefanprodan/podinfo:3.0.1

# wait for Flagger to detect the change
ok=false
until ${ok}; do
    kubectl get canary/podinfo | grep 'Progressing' && ok=true || ok=false
    sleep 5
done

# wait for the canary analysis to finish
kubectl wait canary/podinfo --for=condition=promoted --timeout=5m

# check if the deployment was successful 
kubectl get canary/podinfo | grep Succeeded

Canary finalizers

Flagger 在 Canary 删除时的默认行为是让不属于控制器的资源保持其当前状态, 这简化了删除动作并避免了在资源最终确定时可能出现的死锁,

如果 Canary 与现有资源(即服务、虚拟服务等)一起被引入,它们将在初始化阶段被突变,不再反映其初始状态,

如果删除时希望的功能是将资源恢复到它们的初始状态,可以启用 revertOnDeletion 属性

代码语言:javascript
复制
spec:
  revertOnDeletion: true

当一个删除动作被提交给集群时,Flagger 将尝试恢复以下资源:

. Canary target 副本将被更新为 primary 副本数量

. Canary service 选择器将被恢复

. Mesh/Ingress 流量被路由到 target 上

禁用 Canary 分析的推荐方法是利用 skipAnalysis 属性,它限制了对资源调节的需求, 当不打算再依赖 Flagger进行 deployment 管理时,应启用 revertOnDeletion 属性

注意: 当这个特性被启用时,由于调节的原因,删除动作会有延迟

Canary analysis

Canary 分析定义了:

. Deployment 策略的类型

. 用来验证 Canary 版本的指标

. 用于一致性测试、负载测试和手动门控的 webhooks

. 警报设置

代码语言:javascript
复制
Spec:

  analysis:
    # schedule interval (default 60s)
    interval:
    # max number of failed metric checks before rollback
    threshold:
    # max traffic percentage routed to canary
    # percentage (0-100)
    maxWeight:
    # canary increment step
    # percentage (0-100)
    stepWeight:
    # promotion increment step
    # percentage (0-100)
    stepWeightPromotion:
    # total number of iterations
    # used for A/B Testing and Blue/Green
    iterations:
    # threshold of primary pods that need to be available to consider it ready
    # before starting rollout. this is optional and the default is 100
    # percentage (0-100)
    primaryReadyThreshold: 100
    # threshold of canary pods that need to be available to consider it ready
    # before starting rollout. this is optional and the default is 100
    # percentage (0-100)
    canaryReadyThreshold: 100
    # canary match conditions
    # used for A/B Testing
    match:
      - # HTTP header
    # key performance indicators
    metrics:
      - # metric check
    # alerting
    alerts:
      - # alert provider
    # external checks
    webhooks:
      - # hook

Canary 分析周期性地运行,直到达到最大流量权重或迭代次数。在每次运行时,Flagger 都会调用 webhooks,检查指标,如果达到失败检查的阈值,则停止分析并回滚 canary。如果配置了警报,Flagger 将使用警报提供者发布分析结果

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Flagger 是如何工作的-工作原理?
    • Canary resource
      • Canary target
        • Canary service
          • Canary status
            • Canary finalizers
              • Canary analysis
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档