后浪-GitOps

说到GitOps就一定要提DevOps了,如果说DevOps是前浪,那GitOps就是后浪了。为了表达对前辈的尊重,我们再次回顾一下DevOps:

DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

诚然,DevOps是一种讲究合作的文化,一定程序上打破了开发、运维、测试等软件开发的职能界限,让整个软件开发的流程更快,以此为标尺,我们可以度量一个公司是存在DevOps文化,是否在推动、践行DevOps文化。

回归正题,说到浪,没有前浪,哪来后浪,没有DevOps, GitOps也只是空谈,那么GitOps到底是翻的是哪种浪花?

GitOps的思想源自于一家叫做Weaveworks的公司,这家公司开源了一个名为Flux的GitOps的Operator,它运行在Kubernetes或OpenShift集群内。作用是提供自动监控,保证Kubernetes集群的状态与Git中提供的配置相匹配。

但GitOps不仅仅是Flux,也不仅仅是ArgoCD等同类工具。得益于从DevOps以及可靠性工程的思想经验,GitOps已经成为云原生开发的最新热点趋势。

如果它不是简单的工具,那么GitOps到底是什么?采用它所倡导的最佳实践会给DevOps团队及其构建的应用带来哪些优势?

GitOps到底是什么?

Weaveworks将GitOps总结为Kubernetes和其他用于云原生开发的技术的一种运营模式,

  • 提供一套最佳实践,为容器化集群和应用统一部署、管理和监控。
  • 提供了一条端到端的CI/CD管道以及Git工作流。
image.png

对GitOps的扩展定义是,它是一个为云原生应用实现持续部署的标准,它注重以开发者为中心的基础设施运营体验。通过使用开发者已经熟悉的工具--Git以及持续部署工具(可选工具很多,比如我们正在用的Jenkins,但我推荐GitLab)--来实现Kubernetes集群管理及应用交付。

Git担负起声明式基础设施和应用的唯一定义工具。任何Git和K8s集群中实际运行的内容之间的差异都会被监测到。然后Kubernetes控制器可以回滚集群以与Git相匹配,或自动更新它。

将Git置于交付管道的中心,允许开发人员使用他们熟悉的工具(不用重新学习,没有认知负担)进行拉取请求。一个自动化的流程将仓库中的描述状态与生产环境进行匹配。 GitOps被描述为 "在生产环境中管理应用程序的控制器"。

GitOps原则分解

GitOps管理Kubernetes集群的工作流程基于以下4个原则。

1 声明式描述整个系统

GitOps与包括Kubernetes在内的云原生工具经常代表的声明式系统合作。声明式系统可以被视为代码,因为配置是由事实而不是指令来保证的。当一个应用程序用声明的方式在Git中进行版本化时,那它就一定是明确的-这就是GitOps的核心所在。

由于声明或者说是定义真实明确的记录在Git中,应用程序可以很容易地从Kubernetes部署或者回滚。在最坏的情况下,集群的基础架构可以从Git仓库中准确而快速地恢复。

2 Git决定了系统状态

如果生产版本的声明(K8s中的资源部署)与Git版本(声明式定义)有出入,就应该发出警报。如果需要回滚,简单的Git还原就能恢复正确的系统声明。

Git强大的安全性意味着代码的作者和出处始终是可追踪的,这意味着系统的每一次变更都有迹可寻。

3 自动化部署

以Git作为生产集群必须准确反映声明的状态,对该状态的更改可以自动更新部署。由于状态定义存在于生产环境之外的Git中,所以系统变更时不需要集群凭证。所以,GitOps可以实现做什么和怎么做的分离。

4 软件代理如果出现分歧就会报警

如果生产集群的实际情况与你所期望的系统软件不一致,可以发出警报。这样就能整个系统的自我修复,包括在发生人为错误的情况下。

GitOps工作流

image.png

为什么要在云原生开发中采用 GitOps?

我们已经介绍了GitOps的特点,但具体的商业案例对系统的好处是什么?你很难找到一种持续部署技术或方法论不承诺更快、更频繁的部署(真实需求就是快速频繁的迭代和部署)。GitOps也不例外,但有很多东西可以支持这个承诺。

自动交付管道会将Git上的变更推送到你的基础架构中。GitOps更进一步。它使用像 Weaveworks 的 Flux 这样的工具来自动比较集群的状态和 Git 配置。集群中的操作者会触发Kubernetes内部的部署,从而使任何其他CD工具的需求变得多余。

这意味着CI不需要访问集群。每一次更新都是原子的、事务性的,并且在Git提交日志中。要么成功,要么失败。由于完全基于代码,不需要增加新的基础设施。

image.png

Git作为基础架构和应用代码的 "真相之源",可以加快部署和可靠性,因为任何错误都会被迅速发现。这样一来,无论是回滚生产状态还是从Git上更新,都非常容易

XOps

无论是DevOps还是GitOps亦或是AIOpx,最终的目的都是为了Ops,将软件产品提供给受众,在X这一端也可以说是部署之前有很多种方法以及工具,我们姑且将X理解为CI,那Jenkins作为这一领域的前浪,依旧发挥着能量,不过后浪GitLab的发展也是迅猛

image.png

公司目前使用的CI工具正是Jenkins,当我试图使用jenkins去实践DevOps甚至是GitOps, 我需要做以下几件事

  1. 登录Jenkins平台上,新建一个PipeLine流水线;
  2. 配置好代码仓库demo以及代码访问权限;
  3. 编写Jenkinsfile;
  4. 因为测试环境Jenkins暂时没有与我们的代码仓库GitLab做集成,所以我不得不找到自己的项目,新建一个webhook,指向步骤1)的任务
  5. 因为需要知道流水线最终的运行结果,还需要配置任务通知

对于我而言,有以下几个问题:

  1. 我给项目demo配置了Jenkins流水线,这个项目也可能有其它贡献者,如果我不写文档,他们可能并不知道这件事,结果就需要问我,如同我给其它项目贡献需要问其它人一样。
  2. 其它人就算知道我配置了Jenkins流水线,总还得知道Jenkins服务的地址以及开通对应的权限

所以测试环境常规发布过程归纳起来就是:

  1. 开发完成,push代码;
  2. 登录Jenkins,选择分支,并完成发布
  3. 关注发布结果

当然,这样做依然可以达到最终完成部署的目的。

可以设想一下,当一个新人开发者拿到代码仓库时,他没法快速知道整个CI/CD流程,但是实际上这些CI/CD流程是相对固定,是有规律可循可以用语言描述的的,是可以固化在代码仓库里面的,这就是为什么我更倾向于使用GitLab CI/CD的原因。

  1. 天然与GitLab集成(与GitLab同出一家)
  2. 符合Iac(基础设施即代码)的哲学
image.png

CI/CD各阶段需要做的事情在.gitlab-ci.yml文件中

.....
stages:
  - test
  - build
  - deploy-dev
  - deploy-prod
lint:
  stage: test
  image: harbor.yourprivate.com/base/golangci-lint:v1.21-alpine
  script:
    - golangci-lint run -v
  allow_failure: false
build:
  stage: build
  script:
    - docker build . -t harbor.yourprivate.com/alert-service/gitops:$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA
    - docker login --username=$DOCKER_PRIVATE_USEE harbor.yourprivate.com --password $DOCKER_PRIVATE_KEY
    - docker push harbor.yourprivate.com/alert-service/gitops:$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA
deploy-dev:
  stage: deploy-dev
  image: cnych/kustomize:v1.0
  before_script:
    - git remote set-url origin https://${CI_USERNAME}:${CI_TOKEN}@git.myprivate.com/wuql/gitops.git
    - git config --global user.email "gitlab@git.k8s.local"
    - git config --global user.name "GitLab CI/CD"
  script:
    - git checkout -B $CI_COMMIT_BRANCH
    - git pull origin $CI_COMMIT_BRANCH
    - cd deployment/dev
    - kustomize edit set image harbor.yourprivate.com/alert-service/gitops:$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA
    - cat kustomization.yaml
    - git commit -am '[skip ci] DEV image update'
    - git push origin $CI_COMMIT_BRANCH
  only:
    - dev

deploy-prod:
  stage: deploy-prod
  image: cnych/kustomize:v1.0
  before_script:
    - git remote set-url origin https://${CI_USERNAME}:${CI_TOKEN}@git.myprivate.com/wuql/gitops.git
    - git config --global user.email "gitlab@git.k8s.local"
    - git config --global user.name "GitLab CI/CD"
  script:
    - git checkout -B $CI_COMMIT_BRANCH
    - git pull origin $CI_COMMIT_BRANCH
    - cd deployment/prod
    - kustomize edit set image harbor.yourprivate.com/alert-service/gitops:$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA
    - cat kustomization.yaml
    - git commit -am '[skip ci] PROD image update'
    - git push origin $CI_COMMIT_BRANCH
  only:
    - master
  when: manual

忽略细节部分,这段描述可以相对容易地理解为做了以下几件事

  1. Test:此处是静态检查)
  2. Build:构建镜像
  3. Deploy:根据分支名部署到对应环境(master分支的部署需要手动执行)
image.png

虽然Weaveworks最早提出了GitOps这一理念,也有许多GitOps工具,比如flux、argocd、jenkins-X, 我们选用其中的argocd。

目前公司的CI/CD平台使用的是jenkins, 虽然也可以用,但是需要在jenkins配置任务以及仓库的代码访问权限,相对繁琐,其实公司的代码托管平台gitlab不仅仅可以用来做代码仓库,也可以做CI/CD, 因此,我自己搭建了gitlab runner将集成到公司的gitlab,项目代码目录如下

image.png

其中main.go为http server代码

Dockerfile将仓库代码通过Multistage打包成开箱即用的窗口镜像

deployment为k8s部署的资源描述,dev为开发环境,prod为生产环境,对应的,我们需要在argocd的管理平台上新建两个应用

image.png

背后就是在k8s中创建了applications.argoproj.io这个crd的实例

应用的描述如下所示

...
spec:
  destination:
    namespace: dev
    server: https://kubernetes.default.svc
  project: default
  source:
    path: deployment/dev
    repoURL: https://git.myprivate.com/wuql/gitops.git
    targetRevision: dev
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
...

当有人误将生产应用删除的时候,

kubectl delete deploy gitops -n dev

argocd会监测到这一情况


图片

并重新将应用资源建立起来

图片

至此,算是实践了一下gitops的思想。

解决了什么问题?

仔细想想,如果我们不用gitops这一套思路,gitlab runner本身就在k8sk, 我可以在gitlab的ci完成后直接apply部署,这样最终也能达到部署这一目的,gitops思路很大的一点不同在于【部署】这件事由opertaor来保证,并且持续检查部署状态是否与git仓库定义的是否一致,如果说在gitlab runner中可以一气呵成完成CI/CD, 那么gitops就是将CI/CD解耦了,这样带来的好处是否大于收益,个人认为需要看基础设施是否完善,如果本身CI/CD本身都做的很好,可以尝试,但是根据笔者的观察,IaC的思路并不是那么容易被接受的,思路可以借鉴,自动化确实很美好,不过也是道阻且长,最重要还是能解决团队当时当下的具体问题。

参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352