Pipelines
本文包括如下内容:
- GitOps CI/CD管道中的各个阶段
- code、image、environment
- 回滚
- Compliance Pipeline
本文讨论如何创建管道(pipelines)来构建和测试应用程序代码,然后将其部署到不同的环境中,了解不同的提升策略以及如何恢复、重置或回滚应用程序更改。
CI/CD Pipelines的各个阶段
持续集成(CI)是一种软件开发实践,所有开发人员在中央存储库(Git)中合并代码更改。使用CI,每次代码更改(提交)都会触发给定repo的自动构建和测试阶段,并向做出更改的开发人员提供反馈。GitOps与传统CI之间的主要区别在于,使用GitOps时,CI管道还会在构建和测试阶段成功完成后,使用新的镜像更新应用程序manifest。
持续交付(CD)是自动化整个软件发布过程的实践。除了部署之外,CD还包括基础设施配置。GitOps CD与传统CD的不同之处在于使用GitOps operator监控manifest更改并协调部署。只要CI构建完成并更新了manifest,GitOps operator就会负责最终的部署。
本文深入探讨了全面的CI/CD管道,以及它对软件开发的重要性。CI/CD管道是阶段的集合,每个阶段执行特定的任务,以实现以下目标:
- Productivity-在开发周期的早期就设计、编码风格和质量方面向开发人员提供有价值的反馈,而不需要切换上下文。代码审查、单元测试、代码覆盖、代码分析、集成测试和运行时漏洞是向开发人员提供设计、质量和安全反馈的关键阶段。
- Security-检测作为攻击代码和组件漏洞,以便进行潜在的利用。漏洞扫描可以检测第三方库的安全问题。运行时漏洞扫描可以检测代码的运行时安全问题。
- Defect escape-减少客户交互的失败和昂贵的回滚。一个新版本通常提供新的特性或增强现有的特性。如果特性不能提供正确的功能,结果将是客户不满和潜在的收入损失。单元测试在模块级别验证正确性,功能测试在两个或多个模块之间验证正确性。
- Scalability-在产品发布之前发现可伸缩性问题。单元测试和功能测试可以验证特性的正确性,但这些阶段不能检测诸如内存泄漏、线程泄漏或资源争用问题等问题。Canary发布是一种部署新版本的方法,可以使用生产流量和依赖关系检测可伸缩性问题。
- Time to market-更快地向客户提供功能。有了完全自动化的CI/CD管道,部署软件就不需要耗费大量时间的手工工作。只要代码通过了管道中的所有阶段,就可以发布它。
- Reporting-对可审核性的持续改进和度量的洞察。CI/CD管道的执行时间是几分钟,而不是几小时,这会影响开发人员的行为和生产率。持续监控和改进管道执行时间可以极大地提高团队的生产力。收集和存储构建度量标准也是许多监管审查所需要的。
GitOps持续集成
图1展示GitOps CI/CD上构建的全面CI管道。灰色的方框是完整CI解决方案的新阶段。本文将根据复杂性、成熟度和遵从性需求规划和设计与业务相关的阶段。

PREBUILD阶段
以下阶段也称为静态分析阶段,它们是在代码构建和打包到Docker镜像之前对代码进行手动和自动扫描的组合。
Pull request/code review
所有CI/CD管道都应该以pull请求开始,这允许代码审查,以确保设计和实现之间的一致性,并捕捉其他潜在的错误。代码评审还有助于分享最佳实践、编码标准和团队凝聚力。
Vulnerability scan
开源库可以在不进行定制开发的情况下提供许多功能,但这些库也可能存在漏洞、缺陷和许可问题。集成一个开源库扫描工具,如Nexus Vulnerability Scanner,可以在开发周期的早期检测已知的漏洞和许可问题,并通过升级库或使用替代库来纠正这些问题。
开放源码库的漏洞每天都在被发现,因此要谨慎地尽快升级,以避免暴露在漏洞之下。
Code analysis
虽然手动代码检查对于设计和实现的一致性非常好,但代码标准、重复代码和代码复杂性问题更适合自动检查或代码分析工具,如SonarQube。这些工具不是代码检查的替代品,但它们可以更有效地捕捉日常问题。
Build stages
在静态分析之后,就该构建代码了。除了构建和创建可部署组件(即Docker镜像)之外,单元(模块)测试和单元测试的有效性(代码覆盖率)也是构建过程中不可分割的部分。
Build
构建阶段通常在实际编译项目源代码之前开始下载依赖项库。(像Python和Node.js这样的脚本语言不需要编译。)对于像Java、Ruby和Go这样的编译语言,代码使用各自的编译器编译成字节码/机器二进制文件。此外,生成的二进制文件及其依赖库需要打包到可部署单元(如Java中的jar或war)中进行部署。构建中最耗时的部分是下载依赖项,强烈建议在构建系统中缓存依赖项,以减少构建时间。
Unit test
单元测试用于验证一小段代码执行它应该执行的任务。单元测试不应该依赖于单元测试之外的代码。单元测试主要关注单个单元的功能测试,而不会发现不同模块相互交互时出现的问题。在单元测试期间,通常会“模拟”外部调用,以消除依赖关系问题并减少测试执行时间。
Code coverage
代码覆盖率度量由自动化单元测试覆盖的代码的百分比。代码覆盖率度量简单地确定代码体中哪些语句已经通过测试运行执行,哪些语句没有执行。通常,代码覆盖系统检测源代码并收集运行时信息,以生成关于测试套件代码覆盖的报告。
代码覆盖率是开发过程中反馈循环的关键部分。在开发测试时,代码覆盖率突出了代码中可能没有充分测试和需要额外测试的方面。这个循环一直持续到覆盖达到某个指定的目标。当增加覆盖率变得困难并且回报减少时,覆盖率应该遵循80-20规则。覆盖率度量不是彻底的代码检查和编程最佳实践的替代品。
Docker build
Docker镜像是Kubernetes的可部署单元。一旦代码构建完成,你就可以通过创建Dockerfile并执行docker build
命令,为构建工件创建具有唯一镜像id的Docker镜像。一个Docker镜像应该有它唯一的命名约定,并且每个版本都应该用唯一的版本号标记。此外,你还可以在此阶段运行Docker镜像扫描工具,以检测基本镜像和依赖项的潜在漏洞问题。
由于Git会为每次提交创建一个唯一的哈希值,所以建议使用Git哈希值来标记Docker镜像,而不是创建一个任意的版本号。除了唯一性,每个Docker镜像都可以很容易地使用Git hash来确定Docker镜像中的确切代码来追溯Git repo历史。
Docker push
新构建的Docker镜像需要发布到Docker仓库,以便Kubernetes编排最终的部署。Docker仓库是一种无状态、高度可伸缩的服务器端应用程序,可以存储和分发Docker镜像。对于内部开发,最佳实践是托管一个私有仓库中心,以严格控制镜像存储的位置。
GITOPS CI STAGES
对于传统CI,管道将在构建阶段之后结束。使用GitOps,需要额外的GitOps特定阶段来为最终部署更新manifest。
Git clone config repo
假设Kubernetes配置存储在一个单独的repo中,这个阶段执行一个Git克隆,将Kubernetes配置克隆到构建环境中,以便后续阶段更新manifest。
Update manifests
一旦在构建环境中获得了manifest,就可以使用Kustomize等配置管理工具,使用新创建的镜像id更新manifest。根据你的部署策略,将使用新的镜像id更新一个或多个特定于环境的manifest。
Git commit and push
用新的镜像id更新了manifest之后,最后一步是将manifest提交回Git repo。此时,CI管道已经完成。你的GitOps operator检测到manifest中的更改,并将更改部署到Kubernetes集群。
POSTBUILD STAGES
在完成GitOps CI的所有工作之后,还需要其他阶段来收集持续改进和审计报告的度量标准,并将构建状态通知团队。
Publish CI metrics
CI指标应该存储在单独的数据存储中:
- Build issues-开发团队需要相关的数据来筛选构建失败或单元测试失败的问题。
- CI-长构建时间会影响团队的行为和生产力。代码覆盖率的减少可能会导致更多的产品缺陷。拥有历史构建时间和代码覆盖率度量使团队能够监控趋势,减少构建时间,并增加代码覆盖率。
- Compliance requirements-对于SOC2或PCI需求,构建信息(如测试结果、发布者以及发布的内容)需要维护14个月至7年。
Build notification
对于CI/CD部署,大多数团队更喜欢“没有消息就是好消息”模型,这意味着如果所有阶段都是成功的,他们不需要为构建状态而烦恼。在构建问题的情况下,应该立即通知团队,以便他们能够得到反馈并纠正问题。此阶段通常使用团队消息传递或电子邮件系统实现,因此只要CI/CD管道完成,团队就可以得到通知。

图2预构建将涉及代码评审和静态分析。构建完成后,GitOps CI将更新manifest(随后由GitOps operator部署)。
GitOps阶段有两个挑战:
- 应该使用哪个Git用户来跟踪manifest更新和提交?
- 如何处理能够同时更新repo的并发CI构建?
以下示例使用本地计算机构建系统:
从Git克隆repo。
root@gwz:/data/github-repo# git clone https://github.com/gongwanzhang/resources.git正克隆到 'resources'... remote: Enumerating objects: 379, done. remote: Total 379 (delta 0), reused 0 (delta 0), pack-reused 379接收对象中: 100% (379/379), 54.39 KiB | 121.00 KiB/s, 完成. 处理 delta 中: 100% (156/156), 完成.使用
git config
指定提交用户的电子邮件和名称。根据你的需求,你可以使用服务帐户或实际提交帐户:root@gwz:/data/github-repo/resources# git config --global user.email gongwanzhang@gmail.comroot@gwz:/data/github-repo/resources# git config --global user.name gongwanzhang让我们假设新的Docker镜像具有Git标签
zhangge
。我们将用zhangge
标签更新manifest:root@gwz:/data/github-repo/resources# sed -i 's+acme.co.3m/guestbook:.*$*+acme.com/guestbook:zhangge+' chapter-04/exercise4.4/guestbook.yaml接下来,我们将把更改提交到manifest:
git commit -am "update container for QAL during build zhangge"考虑到repo可以被其他人更新,我们将运行
git rebase
来下拉任何新的提交到我们的本地分支:root@gwz:/data/github-repo/resources# git pull --rebase https://github.com/gongwanzhang/resources.git master现在,我们准备将更新后的manifest推repo,并让GitOps operator执行它的部署:
root@gwz:/data/github-repo/resources# git push https://github.com/gongwanzhang/resources.git master
GitOps连续交付
图3展示了在GitOps CI/CD上构建的一个全面的CD管道。灰色的方框是一个完整的CD解决方案的新阶段。根据复杂性、成熟度和遵从性需求,可以为业务选择相关的阶段。

GitOps CD stages
这些都是GitOps CI根据明显变化执行部署的逻辑阶段。
Git clone config repo
GitOps operator检测到你的repo中的变化,并执行一个Git克隆来获得你的Git repo的最新manifest。
Discover manifests
GitOps operator还确定Kubernetes中的manifest与来自Git repo的最新manifest之间的任何增量。如果没有差异,GitOps operator将在此停止。
Kubectl apply
如果GitOps operator确定了Kubernetes manifest和Git repo manifest之间的差异,GitOps operator使用kubectl apply
命令将新的manifest应用到Kubernetes。
Postdeployment stages
在部署镜像之后,我们可以针对依赖项和运行时漏洞对新代码端到端进行测试。
Integration tests
集成测试是一种测试类型,用于检查不同的模块是否能够正常工作。一旦将镜像部署到QA环境中,集成测试就可以跨多个模块和其他外部系统(如数据库和服务)进行测试。集成测试的目的是发现不同模块交互以执行单元测试无法覆盖的高级功能时所产生的问题。
Run-time vulnerability
运行时漏洞,传统上是通过渗透测试检测的。渗透测试,是对计算机系统、网络或网络应用程序进行测试,以发现攻击者可能利用的安全漏洞。典型的运行时漏洞是SQL注入、命令注入或发出不安全的cookie。QA环境可以使用像Contrast这样的代理工具进行测试,而不是在生产系统中进行渗透测试,同时执行集成测试以在开发周期的早期检测任何运行时漏洞。
Publish CD metrics
CD指标应该存储在单独的数据存储中:
- Run-time issues-开发团队需要相关的数据来筛选与部署、集成测试失败或运行时漏洞有关的问题。
- Compliance requirements-对于SOC2或PCI需求,构建信息(如测试结果、发布者以及发布的内容)需要维护14个月至7年。
以下示例将介绍如何确保将更改应用到Kubernetes并成功完成部署。我们将使用前端部署。Yaml作为我们的manifest。
root@gwz:/data/manifest# cat frontend-deployment.yaml apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: frontend labels: app: guestbook spec: selector: matchLabels: app: guestbook tier: frontend replicas: 3 template: metadata: labels: app: guestbook tier: frontend spec: containers: - name: php-redis image: gcr.io/google-samples/gb-frontend:v4 resources: requests: cpu: 100m memory: 100Mi env: - name: GET_HOSTS_FROM value: dns # Using `GET_HOSTS_FROM=dns` requires your cluster to # provide a dns service. As of Kubernetes 1.3, DNS is a built-in # service launched automatically. However, if the cluster you are using # does not have a built-in DNS service, you can instead # access an environment variable to find the master # service's host. To do so, comment out the 'value: dns' line above, and # uncomment the line below: # value: env ports: - containerPort: 80
运行
kubectl diff
来确定前端部署是否,yaml manifest应用于Kubernetes。exit status1
表示manifest不在Kubernetes中:$ kubectl diff -f frontend-deployment.yaml diff -u -N /var/folders/s5/v3vpb73d6zv01dhxknw4yyxw0000gp/T/LIVE-057767296/apps.v1.Deployment.gitops.frontend /var/folders/s5/v3vpb73d6zv01dhxknw4yyxw0000gp/T/MERGED-602990303/apps.v1.Deployment.gitops.frontend --- /var/folders/s5/v3vpb73d6zv01dhxknw4yyxw0000gp/T/LIVE-057767296/apps.v1.Deployment.gitops.frontend 2020-01-06 14:23:40.000000000 -0800+++ /var/folders/s5/v3vpb73d6zv01dhxknw4yyxw0000gp/T/MERGED-602990303/apps.v1.Deployment.gitops.frontend 2020-01-06 14:23:40.000000000 -0800@@ -0,0 +1,53 @@ +apiVersion: apps/v1 +kind: Deployment ... +status: {}exit status 1将manifest应用到Kubernetes:
$ kubectl apply -f frontend-deployment.yaml重新运行
kubectl diff
,你应该看到应用了退出状态为0的清单。Kubernetes将在manifest更新后启动部署:$ kubectl diff -f frontend-deployment.yaml反复运行
kubectl rollout status
,直到部署完全完成:$ kubectl rollout status deployment.v1.apps/frontend Waiting for deployment "frontend" rollout to finish: 0 of 3 updated replicas are available...
在生产环境中,可以使用一个带有循环的脚本自动化这项工作:
#!/bin/bashRETRY=0 ❶ STATUS="kubectl rollout status deployment.v1.apps/frontend" ❷ until $STATUS || [ $RETRY -eq 120 ]; do ❸ $STATUS ❹ RETRY=$((RETRY + 1)) ❺ sleep 10 ❻done
❶将RETRY变量初始化为0
❷定义kubectl rollout status命令
❸当kubectl rollout status为true或RETRY变量等于120时,循环退出条件。
❹执行kubectl rollout status命令
❺将RETRY变量增加1
❻休眠10秒
现在我们已经介绍了CI/CD管道中的所有阶段,我们可以看看CI/CD管道如何自动提升代码、镜像和环境。自动化环境提升的主要好处是使团队能够更快、更可靠地将新代码部署到生产环境中。
Code vs. manifest vs. app config
有几个用于维护环境配置的选项:
- Docker image-所有特定于环境的应用配置文件都可以绑定到Docker镜像中。这种策略最有效地将遗留应用程序(与所有环境应用程序配置绑定)快速打包到Kubernetes中。缺点是创建一个新的环境需要完整的构建,并且不能重用现有的镜像。
- ConfigMaps-ConfigMaps是Kubernetes中的本地资源,存储在Kubernetes
etcd
数据库中。缺点是,如果ConfigMap更新,pod需要重新启动。 - Config repo-在单独的repo中存储应用程序配置可以达到与ConfigMap相同的结果。额外的好处是Pod可以动态地接收应用程序配置中的更改(例如在Java中使用Spring Cloud Config)。
Code and image
假设你正在构建一个包含加减函数的数学库。你将首先克隆主分支,以创建一个名为add的新分支。一旦完成了添加功能的实现,就可以将代码提交到添加分支,并生成一个pull请求以合并到主分支。GitOps CI将创建一个新镜像并更新manifest。GitOps CI最终将部署新镜像。然后可以重复这个过程来实现减法功能。
Single-branch strategy
单分支策略也称为特征分支工作流,在这个策略中,主分支是正式的项目历史。开发人员创建用于开发的短期特性分支。一旦开发人员完成了该功能,更改就会通过PR过程合并回主分支。当PR被批准将新代码捆绑到一个新的Docker镜像中时,CI构建将被触发。
通过单分支开发,CI构建中的每个镜像都可以提升到任何环境中,并用于生产版本。如果需要回滚,可以使用Docker仓库中的任何旧镜像重新部署。如果你的服务可以独立部署(也就是微服务),并使你的团队能够频繁地进行生产发布,那么这个策略非常出色,效果最好。

Multibranch strategy
多分支策略通常适用于需要密切协调外部依赖关系和发布计划的大型项目。多分支策略有许多变体,对于本文的讨论,我们使用Gitflow工作流作为示例。使用Gitflow,开发分支有官方的项目历史,而主分支有最近的生产版本历史。CI构建是为c的开发分支配置的。对于特性开发,开发人员创建短期的特性分支,并在特性完成后合并对开发分支的更改。
当计划发布一个版本时,一个短命的版本分支将从最新的开发分支派生出来,并且在这个分支中继续进行测试和bug修复,直到代码准备好用于生产部署为止。因此,需要配置一个单独的CI构建,以从发布分支构建新的Docker镜像。一旦发布完成,所有的变更都合并到开发和主分支中。
与单分支策略不同,只有发布版CI构建镜像可以部署到生产环境中。所有来自开发分支的镜像只能用于预生产测试和集成。如果需要回滚,则只能使用从发布分支构建的镜像。如果生产问题需要前滚(或热修复),则必须从主分支派生热修复分支,并为热修复镜像创建单独的CI构建。

图5中在多分支策略中,将有多个长期存在的分支,每个长期存在的分支都有自己的CI管道。在本例中,长期存在的分支是develop、master和hotfix。
Environment
以下将讨论如何将镜像从预生产环境提升到生产环境。使用多个环境并推动更改的原因是在较低的环境中尽可能多地进行测试,这样就可以在开发周期的早期检测和纠正错误。
环境促进有两个方面。第一个是环境基础设施。正如前面中讨论的,Kustomize是将新镜像推广到每个环境的首选配置管理工具,而GitOps操作符将完成剩下的工作。
第二个方面是应用程序本身。由于Docker镜像是不可变的二进制文件,注入特定于环境的应用配置将配置应用程序以适应特定的环境。
前面介绍了QA、E2E、Stage和Prod环境,并讨论了每个环境在开发周期中的独特用途。让我们回顾一下每个环境中重要的阶段。
QA
QA环境是运行新镜像的第一个环境,用于在执行过程中用外部依赖关系验证代码的正确性。以下几个阶段对QA环境至关重要:
- 功能测试
- 运行时的vulnerability
- 发布标准
E2E
E2E环境主要用于其他应用程序测试现有的或预发布的特性。端到端加密环境的监控和操作应该类似于Prod环境,因为端到端加密中断可能会阻塞其他服务的CI/CD管道。可选的验证阶段(使用功能测试子集进行健全测试)适用于E2E环境,以确保其正确性。
STAGE
Stage环境通常会连接到生产依赖项,以确保在生产发布之前所有的生产依赖项都到位。例如,新版本在部署之前可能依赖于DB模式更新或要配置的消息队列。使用分段测试可以保证所有产品依赖项是正确的,并避免产品问题。
PROD
Canary release
Canary release是一种降低在生产中引入新软件版本的风险的技术,方法是在将更改扩展到整个基础设施并使所有人都可以使用之前,先缓慢地将更改扩展到一小部分用户。
Release ticket
考虑到应用程序服务的复杂性和分布式特性,在发生生产事件时,发布ticket对于你的生产支持团队来说是至关重要的。发布ticket将帮助生产事故团队了解谁部署/更改了什么,以及在需要时回滚到什么。此外,发布ticket跟踪对于遵从性需求是必须的。
Other pipelines
CI/CD管道主要用于部署,在这种部署中,更改按照预期工作,但我们都知道这不是现实。生产环境中不时会出现意想不到的问题,我们需要回滚环境或发布热修复程序来缓解问题。对于软件即服务(SaaS),最高优先级是尽快从生产问题中恢复过来;在大多数情况下,为了及时恢复,需要回滚到先前已知的良好状态。
对于特定的合规标准,如paycard Industry (PCI),产品发布需要第二个人的批准,以确保没有一个人可以发布对生产的更改。PCI还要求进行年度审计,要求报告批准记录。鉴于我们的原始CI/CD管道将对每个PR的生产部署更改,我们需要加强我们的管道,以支持合规和可审核性。

图6中一个CI/CD管道完成了单分支开发的环境提升。对于多分支开发,分支推广需要额外的阶段。
回滚
即使你已经计划好了CI/CD管道中的所有检查、分析和测试阶段,消除所有生产问题仍然是不可能的。根据问题的严重程度,你可以使用修复程序进行前滚,也可以通过回滚将服务恢复到以前已知的良好状态。由于我们的生产环境由manifest(包含Docker镜像id)和环境的应用程序配置组成,因此回滚过程可以回滚应用程序配置、manifest,或者两者都回滚。使用GitOps,我们的回滚过程再次由Git更改控制,GitOps操作符将负责最终的部署。(如果app配置repo也需要回滚,你只需要在回滚manifest之前先回滚app配置中的更改,因为只有manifest的更改才能触发部署,而不是app配置的更改。)Git Revert和Git Reset是两种回滚Git更改的方法。
git revert
命令可以被认为是撤消命令。它并没有从项目历史中删除提交,而是弄清楚如何反转提交所引入的更改,并添加一个新的提交,以得到相反的内容。这可以防止Git丢失历史记录,这对于修改历史记录的完整性(遵从性和可审核性)以及可靠的协作至关重要。
根据调用方式的不同,git reset
命令会做一些事情。它修改索引(所谓的暂存区),或者修改当前分支头所指向的提交对象。这个命令可以改变现有的历史(通过改变分支引用的提交)。由于这个命令可以改变历史记录,如果遵从性和可审核性很重要,我们不建议使用git reset
。

图7 git revert
的工作方式类似于undo
命令,但保留了历史记录。另一方面,Git reset
会修改历史记录以重置更改。
图8是回滚管道的一个示例。这个管道将从git revert
和git commit
开始,将清单回滚到之前已知的良好状态。从“回复”提交生成拉请求后,审批者可以批准PR并将其合并到manifest主分支。同样,GitOps operator将执行它的魔法,并基于更新的清单回滚应用程序。

以下将介绍将镜像id从“zhangge”恢复为“yyyyyy”所需的步骤。这个示例将使用git revert
,以保留提交历史。
从Git克隆repo。
git clone https://github.com/gongwanzhang/resources.git使用
git config
指定提交用户的电子邮件和名称。根据你的需求,你可以使用服务帐户或实际提交帐户:$ git config --global user.email gongwanzhang@gmail.com $ git config --global user.name gongwanzhang让我们回顾一下Git的历史:
$ git log --pretty=oneline eb1a692029a9f4e4ae65de8c11135c56ff235722 (HEAD -> master) guestbook with image hash zzzzzz95384207cbba2ce46ee2913c7ea51d0f4e958890 guestbook with image hash yyyyyy4dcb452a809d99f9a1b5a24bde14116fad9a4ded (upstream/master, upstream/HEAD, origin/master) exercise 4.6 and 4.10e62161043d5a3360b89518fa755741c6be7fd2b3 exercise 4.6 and 4.1074b172c7703b3b695c79f270d353dc625c4038ba guestbook for exercise 4.4...从log中,可以看到“eb1a692029a9f4e4ae65de8c11135c56ff23 5722”表示镜像哈希zzzzzz。如果我们恢复这个提交,manifest将会有一个镜像散列yyyyyy:
$ git revert eb1a692029a9f4e4ae65de8c11135c56ff235722现在,我们准备通过推回repo来回退manifest的恢复,并让GitOps operator执行它的部署:
$ git push https://github.com/gongwanzhang/resources.gitmaster
总结
git rebase
可以检查并发管道执行引起的冲突。- 持续运行
kubectl rollout status
可以确保部署完成,并为在GitOps CD中运行功能测试做好准备。 - 将代码、manifest和app配置分别放在单独的repo中可以给你带来最好的灵活性,因为基础设施和代码可以分别发展。
- 单分支策略对于较小的项目非常有用,因为每个CI镜像都可以在零分支管理的情况下推广到生产中。
- 多分支策略对于具有外部依赖关系和发布计划的大型项目来说非常好。缺点是必须维护多个长期存在的分支,并且只能将发布镜像部署到生产环境中。
- 一个完整的CI/CD管道将包括环境推广和静态分析、构建、单元/集成测试以及发布构建度量/通知的阶段。
- 使用GitOps回滚生产环境只是将清单恢复到以前的提交(镜像id)。
- GitOps管道自然支持遵从性和可审核性,因为所有的更改都是通过具有批准和历史的拉请求生成的。
感兴趣的关注如下公众号!





