在这篇指南中,你将获得使用 KubernetesIstio 使用 GitOps 进行渐进式交付(Progressive Delivery)的实际经验。

介绍

gitops-istio

GitOps 是什么?

GitOps 是一种进行持续交付的方式,它使用 Git 作为声明性(declarative)基础设施和工作负载(workloads)的真实来源。 对于 Kubernetes,这意味着使用 git push 而不是 kubectl apply/deletehelm install/upgrade

在这个 workshop 中,您将使用 GitHub 来托管配置存储库,并将 Flux 作为 GitOps 交付解决方案。

什么是渐进式交付?

渐进交付是高级部署模式(如金丝雀canaries、功能标志feature flags和A/B测试A/B testing)的总称。渐进交付技术通过让应用程序开发人员和 SRE 团队对爆炸半径blast radius进行细粒度控制,从而降低在生产中引入新软件版本的风险。

在这个 workshop 中,您将使用 FlaggerPrometheus 为您的应用程序自动执行 Canary 发布和 A/B Testing

准备工作

您将需要具有 LoadBalancer 支持的 Kubernetes 集群 v1.16 或更高版本。 出于测试目的,您可以使用带有 2CPU4GB 内存的 Minikube

使用 Homebrew 安装 flux CLI:

  1. brew install fluxcd/tap/flux

macOS AMD64/ARM64Linux AMD64/ARMWindows 的二进制文件可在 flux2 release page 下载。

验证您的集群是否满足前提条件:

  1. flux check --pre

使用 Homebrew 安装 jqyq

  1. brew install jq yq

Fork 这个仓库并克隆它:

  1. git clone https://github.com/<YOUR-USERNAME>/gitops-istio
  2. cd gitops-istio

Cluster bootstrap

使用 flux bootstrap 命令,您可以在 Kubernetes 集群上安装 Flux 并将其配置为从 Git 存储库管理自身。如果集群上存在 Flux 组件,则 bootstrap 命令将在需要时执行升级。

通过指定您的 GitHub 存储库 fork URL 来引导 Flux

  1. flux bootstrap git \
  2. --author-email=<YOUR-EMAIL> \
  3. --url=ssh://git@github.com/<YOUR-USERNAME>/gitops-istio \
  4. --branch=main \
  5. --path=clusters/my-cluster

上面的命令需要 ssh-agent,如果您使用的是 Windows,请参阅 flux bootstrap github 文档。

在引导时,Flux 生成一个 SSH key 并打印 public key

为了用 git 同步你的集群状态,你需要复制 public key 并使用 write 创建一个 deploy key 访问你的 GitHub 仓库。在 GitHub 上转到 Settings > Deploy keys 点击 Add deploy key

勾选️ Allow write access,粘贴 Flux public key 并单击 Add key

Flux 访问你的存储库时,它会做以下事情:

  • 安装 Istio operator
  • 等待 Istio 控制平面准备好
  • 安装 FlaggerPrometheusGrafana
  • 创建 Istio 公共网关
  • 创建 prod 命名空间namespace
  • 创建负载测试器(load tester) deployment
  • 创建前端(frontend) deployment 和金丝雀canary
  • 创建后端(backend) deployment 和金丝雀canary

使用 Istio 引导集群时,定义 apply 顺序很重要。对于要使用 Istio sidecar 注入的应用程序 podIstio 控制平面必须在应用程序之前启动并运行。

Flux v2 中,你可以通过定义对象之间的依赖关系来指定执行顺序。例如,在 clusters/my-cluster/apps.yaml 中我们告诉 Fluxapps 的协调取决于一个 istio-system

  1. apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
  2. kind: Kustomization
  3. metadata:
  4. name: apps
  5. namespace: flux-system
  6. spec:
  7. interval: 30m0s
  8. dependsOn:
  9. - name: istio-system
  10. sourceRef:
  11. kind: GitRepository
  12. name: flux-system
  13. path: ./apps

首先观测 Flux 安装 Istio,然后观测 demo apps

  1. watch flux get kustomizations

您可以使用以下命令跟踪 Flux reconciliation 日志:

  1. flux logs --all-namespaces --follow --tail=10

Istio 定制和升级

您可以使用位于 istio/system/profile.yamlIstioOperator 资源自定义 Istio 安装:

  1. apiVersion: install.istio.io/v1alpha1
  2. kind: IstioOperator
  3. metadata:
  4. name: istio-default
  5. namespace: istio-system
  6. spec:
  7. profile: demo
  8. components:
  9. pilot:
  10. k8s:
  11. resources:
  12. requests:
  13. cpu: 10m
  14. memory: 100Mi

修改 Istio 设置后,您可以将更改推送到 gitFlux 将在集群上应用它。Istio operator 将根据您的更改重新配置 Istio 控制平面。

当新的 Istio 版本可用时,update-istio GitHub Action workflow 工作流将打开一个pull request,其中包含升级 Istio Operator 所需的清单更新。新的 Istio 版本通过 e2e workflowKubernetes Kind 上进行测试,当 PR 合并到主分支时,Flux 将在集群内升级 Istio

应用程序引导

FluxGit 存储库与您的集群同步时,它将创建前端/后端部署(frontend/backend deployment)、HPA 和一个金丝雀对象canary objectFlagger 使用 canary 定义创建了一系列对象:Kubernetes deploymentsClusterIP servicesIstio 目标规则(destination rules)和虚拟服务(virtual services)。这些对象在网格(mesh)上公开(expose)应用程序,并推动金丝雀分析(canary analysis)和推广(promotion)。

  1. # applied by Flux
  2. deployment.apps/frontend
  3. horizontalpodautoscaler.autoscaling/frontend
  4. canary.flagger.app/frontend
  5. # generated by Flagger
  6. deployment.apps/frontend-primary
  7. horizontalpodautoscaler.autoscaling/frontend-primary
  8. service/frontend
  9. service/frontend-canary
  10. service/frontend-primary
  11. destinationrule.networking.istio.io/frontend-canary
  12. destinationrule.networking.istio.io/frontend-primary
  13. virtualservice.networking.istio.io/frontend

检查 Flagger 是否成功初始化了金丝雀:

  1. kubectl -n prod get canaries
  2. NAME STATUS WEIGHT
  3. backend Initialized 0
  4. frontend Initialized 0

frontend-primary 部署上线时,Flager 会将所有流量路由到主 Pod,并将 frontend 部署 scale 到零。

使用以下命令查找 Istio 入口网关(ingress gateway)地址:

  1. kubectl -n istio-system get svc istio-ingressgateway -ojson | jq .status.loadBalancer.ingress

打开浏览器并导航到入口地址,您将看到前端 UI

金丝雀发布

Flagger 实现了一个控制循环,该控制循环在测量关键性能指标(如 HTTP 请求成功率、请求平均持续时间和 pod 运行状况)的同时,逐步将流量转移到金丝雀。在分析 KPI 的基础上,将金丝雀升级或中止,并将分析结果发布到 Slack

金丝雀分析由以下任何对象的更改触发:

  • 部署 PodSpec(容器镜像、命令、端口、环境等)
  • ConfigMapsSecrets 作为卷(volumes)挂载或映射到环境变量

对于不接收恒定流量的工作负载,Flagger 可以配置一个 webhook,当它被调用时,将启动一个目标工作负载的负载测试。canary 配置可以在 apps/backend/canary.yaml 上找到。

从 GitHub 拉取更改:

  1. git pull origin main

要触发后端应用程序的金丝雀部署,请碰撞容器镜像:

  1. yq e '.images[0].newTag="5.0.1"' -i ./apps/backend/kustomization.yaml

提交和推送更改:

  1. git add -A && \
  2. git commit -m "backend 5.0.1" && \
  3. git push origin main

告诉 Flux 拉取更改或等待一分钟让 Flux 自行检测更改:

  1. flux reconcile source git flux-system

观测 Flux 将您的集群与最新提交进行协调:

  1. watch flux get kustomizations

几秒钟后,Flager 检测到部署修订(deployment revision)已更改并开始新的 rollout

  1. $ kubectl -n prod describe canary backend
  2. Events:
  3. New revision detected! Scaling up backend.prod
  4. Starting canary analysis for backend.prod
  5. Pre-rollout check conformance-test passed
  6. Advance backend.prod canary weight 5
  7. ...
  8. Advance backend.prod canary weight 50
  9. Copying backend.prod template spec to backend-primary.prod
  10. Promotion completed! Scaling down backend.prod

在分析过程中,Grafana 可以监控金丝雀的进程。您可以通过端口转发访问仪表板:

  1. kubectl -n istio-system port-forward svc/flagger-grafana 3000:80

Istio 仪表板的 URL

http://localhost:3000/d/flagger-istio/istio-canary?refresh=10s&orgId=1&var-namespace=prod&var-primary=backend-primary&var-canary=backend

请注意,如果在金丝雀分析(canary analysis)期间对部署应用了新的更改,Flagger 将重新启动分析阶段。

A/B 测试

除了加权路由(weighted routing),Flagger 还可以配置为根据 HTTP 匹配条件将流量路由到金丝雀。在 A/B 测试场景中,您将使用 HTTP headerscookie 来定位用户的特定部分。这对于需要会话(session)关联的前端应用程序特别有用。

您可以通过指定 HTTP 匹配条件和迭代次数来启用 A/B 测试:

  1. analysis:
  2. # schedule interval (default 60s)
  3. interval: 10s
  4. # max number of failed metric checks before rollback
  5. threshold: 10
  6. # total number of iterations
  7. iterations: 12
  8. # canary match condition
  9. match:
  10. - headers:
  11. user-agent:
  12. regex: ".*Firefox.*"
  13. - headers:
  14. cookie:
  15. regex: "^(.*?;)?(type=insider)(;.*)?$"

上述配置将针对 Firefox 用户和拥有内部 cookie 的用户运行两分钟的分析。 前端配置可以在 apps/frontend/canary.yaml 中找到。

通过更新前端容器镜像触发部署:

  1. yq e '.images[0].newTag="5.0.1"' -i ./apps/frontend/kustomization.yaml
  2. git add -A && \
  3. git commit -m "frontend 5.0.1" && \
  4. git push origin main
  5. flux reconcile source git flux-system

Flager 检测到部署修订已更改并开始 A/B 测试:

  1. $ kubectl -n istio-system logs deploy/flagger -f | jq .msg
  2. New revision detected! Scaling up frontend.prod
  3. Waiting for frontend.prod rollout to finish: 0 of 1 updated replicas are available
  4. Pre-rollout check conformance-test passed
  5. Advance frontend.prod canary iteration 1/10
  6. ...
  7. Advance frontend.prod canary iteration 10/10
  8. Copying frontend.prod template spec to frontend-primary.prod
  9. Waiting for frontend-primary.prod rollout to finish: 1 of 2 updated replicas are available
  10. Promotion completed! Scaling down frontend.prod

您可以通过以下方式监控所有金丝雀:

  1. $ watch kubectl get canaries --all-namespaces
  2. NAMESPACE NAME STATUS WEIGHT
  3. prod frontend Progressing 100
  4. prod backend Succeeded 0

基于 Istio 指标的回滚

Flagger 使用 Istio 遥测提供的指标来验证金丝雀工作负载。 前端应用 analysis 定义了两个指标检查:

  1. metrics:
  2. - name: error-rate
  3. templateRef:
  4. name: error-rate
  5. namespace: istio-system
  6. thresholdRange:
  7. max: 1
  8. interval: 30s
  9. - name: latency
  10. templateRef:
  11. name: latency
  12. namespace: istio-system
  13. thresholdRange:
  14. max: 500
  15. interval: 30s

用于检查错误率(error rate)和延迟的 Prometheus 查询,位于 flagger-metrics.yaml

在金丝雀分析期间,您可以生成 HTTP 500 errors 和高延迟(high latency)来测试 Flagger 的回滚。

生成 HTTP 500 errors:

  1. watch curl -b 'type=insider' http://<INGRESS-IP>/status/500

生成延迟:

  1. watch curl -b 'type=insider' http://<INGRESS-IP>/delay/1

当失败的检查次数达到金丝雀分析阈值(threshold)时,流量将路由回主服务器,金丝雀缩放为零,并将推出(rollout)标记为失败。

  1. $ kubectl -n istio-system logs deploy/flagger -f | jq .msg
  2. New revision detected! Scaling up frontend.prod
  3. Pre-rollout check conformance-test passed
  4. Advance frontend.prod canary iteration 1/10
  5. Halt frontend.prod advancement error-rate 31 > 1
  6. Halt frontend.prod advancement latency 2000 > 500
  7. ...
  8. Rolling back frontend.prod failed checks threshold reached 10
  9. Canary failed! Scaling down frontend.prod

您可以使用针对 PrometheusDatadogAmazon CloudWatch 的自定义指标检查来扩展分析。

有关为 SlackMS TeamsDiscordRocket 配置 canary 分析警报的信息,请参阅文档

  1. 我是为少
  2. 微信:uuhells123
  3. 公众号:黑客下午茶
  4. 加我微信(互相学习交流),关注公众号(获取更多学习资料~)

使用 Flux+Flagger+Istio+Kubernetes 实战 GitOps 云原生渐进式(金丝雀)交付的更多相关文章

  1. 使用 flux2+kustomize+helm+github 进行多集群 GitOps 云原生渐进式交付

    对于此示例,我们假设有两个集群的场景:暂存(staging)和生产(production). 最终目标是利用 Flux 和 Kustomize 来管理两个集群,同时最大限度地减少重复声明. 我们将配置 ...

  2. Kubernetes 入门必备云原生发展简史

    作者|张磊 阿里云容器平台高级技术专家,CNCF 官方大使 "未来的软件一定是生长于云上的"这是云原生理念的最核心假设.而所谓"云原生",实际上就是在定义一条能 ...

  3. 从 Spark 到 Kubernetes — MaxCompute 的云原生开源生态实践之路

    2019年5月14日,喜提浙江省科学技术进步一等奖的 MaxCompute 是阿里巴巴自研的 EB 级大数据计算平台.该平台依托阿里云飞天基础架构,是阿里巴巴在10年前做飞天系统的三大件之分布式计算部 ...

  4. 使用 Iceberg on Kubernetes 打造新一代云原生数据湖

    背景 大数据发展至今,按照 Google 2003年发布的<The Google File System>第一篇论文算起,已走过17个年头.可惜的是 Google 当时并没有开源其技术,& ...

  5. kubernetes实战-配置中心(二)交付apollo配置中心到k8s

    apollo官网:官方地址 apollo架构图: apollo需要使用数据库,这里使用mysql,注意版本需要在5.6以上: 本次环境mysql部署在10.4.7.11上,使用mariadb:10.1 ...

  6. 云原生项目实践DevOps(GitOps)+K8S+BPF+SRE,从0到1使用Golang开发生产级麻将游戏服务器—第1篇

    项目初探 项目地址: 原项目:https://github.com/lonng/nanoserver 调过的:https://github.com/Kirk-Wang/nanoserver 这将是一个 ...

  7. 如何将云原生工作负载映射到 Kubernetes 中的控制器

    作者:Janakiram MSV 译者:殷龙飞 原文地址:https://thenewstack.io/how-to-map-cloud-native-workloads-to-kubernetes- ...

  8. 《Kubernetes与云原生应用》系列之容器设计模式

    http://www.infoq.com/cn/articles/kubernetes-and-cloud-native-app-container-design-pattern <Kubern ...

  9. 003/kubernetes基础:开启云原生之门(Mooc)

    一.简介:(https://www.imooc.com/learn/978) 在2017年Kubernetes战胜了两个强大的竞争对手Swarm和Mesos,成为容器管理与调度编排领域的首选平台和事实 ...

随机推荐

  1. day19.进程通信与线程1

    1 进程Queue介绍 1 进程间数据隔离,两个进程进行通信,借助于Queue 2 进程间通信:IPC -借助于Queue实现进程间通信 -借助于文件 -借助于数据库 -借助于消息队列:rabbitm ...

  2. SpringCloud(六)Bus消息总线

    Bus 消息总线 概述 分布式自动刷新配置功能 Spring Cloud Bus 配合 Spring Cloud Config使用可以实现配置的动态刷新 Bus支持两种消息代理:RabbitMQ和Ka ...

  3. Tomcat PUT方法任意文件上传(CVE-2017-12615)

    目录 漏洞复现: 漏洞利用工具: 漏洞环境:当 Tomcat运行在Windows操作系统,且启用了HTTP PUT请求方法(例如,将 readonly 初始化参数由默认值设置为 false),攻击者将 ...

  4. 【flutter学习】基础知识(一)

    今天开始学习一下flutter 学习思路:首先由一个简单的例子引出每次学习的对象,一点一点加入元素,针对于代码去了解学习详细知识. 看完本篇博客能够快速的读懂flutter简单代码. flutter ...

  5. (邹博ML)矩阵和线性代数

    主要内容 矩阵 特征值和特征向量 矩阵求导 矩阵 SVD的提法 奇异值分解(Singular Value Decomposition)是一种重要的矩阵分解方法,可以看做对称方阵在任意矩阵上的推广. 假 ...

  6. Object划分

    Object划分 1.PO(persistantobject)持久对象 PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合.PO中应该不包 含任何对数据库的操作. 2.DO(Domain ...

  7. 简单使用高德地图开放平台API

    需求说明 输入经纬度,得到城市名 挑选API 使用高德逆地理编码API,点击查看文档 demo <?php /** * 根据输入的经纬度返回城市名称 * @param $longitude 终点 ...

  8. Java解析xml文件遇到特殊符号&会出现异常的解决方案

    文/朱季谦 在一次Java解析xml文件的开发过程中,使用SAX解析时,出现了这样一个异常信息: Error on line 60 of document : 对实体 "xxx" ...

  9. MongoDB评论管理

    MongoDB简介 文章评论数据分析 相较于一般数据,文章评论一般有如下特点: 数据量巨大.通常评论量要比帖子.文章大很多 写入操作频繁. 价值较低.一般来说,我们的主要目标还是在帖子(文章)本身. ...

  10. 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容

    上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...