
前 言
GitOps 于 2017 年由 weavewoks 率先推出,是一种进行 Kubernetes 集群管理和应用程序交付的方式。GitOps 使用 Git 作为声明性基础设施和应用程序的单一事实来源。借助 GitOps,软件代理的使用可以针对 Git 与集群中运行的内容之间的任何差异发出警报,如果存在差异,Kubernetes (下文简称为 K8s)协调器会根据情况自动更新或回滚集群。以 Git 作为交付管道的中心,开发人员可以使用熟悉的工具来发出拉取请求,以加速和简化 K8s 的应用程序部署和操作任务。
目前我们团队已经全面使用GitOps,结合团队使用的经验,今天我们对 GitOps 进行基本的介绍以及 Flux 的实践演示。
GitOps 是如何工作的?
GitOps 由三部分组成,分别为:IaC 、 MRs 、 CICD。我们首先介绍一下IaC,IaC 在维基百科的定义如下:
Infrastructure as code (IaC) is the process of managing and provisioning computer data centers through machine-readable definition files, rather than physical hardware configuration or interactive configuration tools.
基础设施即代码 (IaC)是通过机器可读的定义文件而不是物理硬件配置或交互式配置工具来管理和配置计算机数据中心的过程。
这里所指的基础设施包括了物理设备、例如物理服务器、虚拟机以及相关的资源,而这里所指的定义一般是脚本或者声明式的定义,而不是手工地操作,这样就可以存在版本控制系统中,例如 Git。
而 K8s 则天然具备了这个特征,就像马克思所说的,货币天然是黄金。
K8s 对于对象的管理有两种方式,一种是 Imperative command 的方式,就是传统的命令方式,另外一种就是 Declarative Object configuration,声明式对象配置,即所有信息都在配置文件中,这样调用的命令是一致的,是根据配置文件的不同,做不同的事情,这其实是符合设计模式的原理的,把变化的东西往前推(例如 K8s 的命令:kubectl apply -f xxx.yaml)。
而 Flux 的实现再次遵循了此概念,后续详细介绍。
GitOps 的另外两部分是 MRs 和 CICD,MRs 指 Git 的 merge request;CICD 指持续集成和持续部署(交付),一般指 GitLab、Jenkins 这些工具。
GitOps 是如何工作的?
2.1 使用 Git 仓库来做环境配置
2.2 于 pull 和 基于 push 的部署
GitOps 有两种部署方式,基于 pull 和基于 push 的部署方式。
2.2.1 基于 push 的部署
基于 push 的部署策略是由流行的 CI/CD 工具(例如 Jenkins、CircleCI、Travis CI )来实现的。应用程序的源代码和用来部署 K8s 的 YAML 文件都在应用仓库中。只要应用程序得到更新,构建管道就会被触发,构建管道会构建容器的镜像,最终环境配置仓库也会用新的镜像名称来更新。
环境配置仓库的变化会触发部署管道。这个管道来负责对把所有的环境中的清单应用到所有基建上去,这就不可避免地要提供部署环境的证书,所以这个管道只能是上帝模式,我们在操作过程中要小心操作,防止出错。


2.2.2 基于 pull 的部署
基于 pull 的部署流程如下:


GitOps 原则

3.1 整个系统是以声明的方式被描述。
传统的部署是运维编写脚本来执行一系列的指令(Instructions),这里不同,需要提供的仅仅是变化的配置,这里其实是分离出来变化的内容,放在了仓库中的配置文件中,而固定的行为则是根据配置去部署。
3.2 系统所需要的状态被版本化地记录在 Git 中。
3.3 批准过的修改可以自动化地被应用到系统上。
3.4 软件代理来保证正确性,并且在出现不一致的情况下给出警告。
Flux 实践

上面是 Flux 的源代码的 README,从这里可以看到,Flux 将 kubectl 包裹了起来,fluxctl 所做的事情,其实就是由 flux 来根据声明式的配置定义来完成的,而 fluxctl 的方式就是 iperative 的方式,是传统的方式,而 flux 的方式是 declarative 的方式,是声明式的方式,符合了 IaC 的原则,至此,整条链路达成了一致。

4.2 Fluxctl 命令操作实践

创建 flux 命名空间
通过 Fluxctl 安装 flux,这里涉及到一个 Flux 的学习仓库,首先 fork 这个项目到你自己的 GitHub 空间
配置 deploy key,通过下面的命令获得公钥,然后使用这个公钥,配置项目的 deploy key
对这个仓库进行小改动后,可等待5分钟,或执行 fluxctl sync 命令告诉 Flux 立即更新
通过接口请求得知,项目更新内容生效。


接下来,我们进行 fluxctl 常用命令的练习和理解。
查看管理的工作负载(Workloads)

在 K8s 中,可以把资源对象分为两类:Workloads(工作负载)、Controllers(控制器)。
Workloads 主要包含:Pod, Deployment, StatefulSet, Service, ConfigMap, Secret, DaemonSet, Job/CronJob, HPA, Namespace, PV/PVC, Node 等,主要是将各类型资源按需求和特性分类。
Controllers 主要包含:Node Controller, Replication Controller, Namespace Controller, ServiceAccount Controller, Service Controller, Endpoint Controller 等,主要作用是在资源自动化控制中,将各类型资源真实值(Actual)调谐(Reconcile)到期望值(Expect)。
Namespace in which fluxd is running, for creating a port forward to access the API.
检查 workloads 的版本

更新 workloads
开启自动部署
这样只要 GitHub 中的配置库发生变化,Flux 就会同步到这里的部署。
关闭自动部署
回滚 workloads
# 查看容器版本 fluxctl --k8s-fwd-ns=flux list-images --workload=demo:deployment/podinfo # 关闭自动部署 fluxctl deautomate --workload=demo:deployment/podinfo --k8s-fwd-ns=flux # release 部署到指定回滚的版本 fluxctl release --workload=demo:deployment/podinfo --k8s-fwd-ns=flux --update-image=quay.io/weaveworks/helloworld:master-a000001 |
锁定 workloads

将 image 发布到锁定的 workloads
为了不必修改锁定策略(包括作者和原因),可以使用 --force
解锁 workloads
解锁工作负载允许它进行手动或自动发布(再次)。


指定 image tag 部署
如果只想使用项目中的'prod'分支构建的镜像进行部署,进行如下设置即可:
如果 pod 包含多个容器,那么您可以单独标记每个容器
没有明确提及目标镜像的手动发布也将遵守标签过滤器。这只会发布与标签过滤器匹配的最新镜像
要在标签过滤器之外发布镜像,需要指定镜像
请注意,上面的自动化(automate)可能会立即撤消此操作。
根据条件过滤
The glob ( *
) filter is the simplest filter Flux supports, a filter can contain multiple globs:
就是使用"*"通配符来进行匹配,这个是最简单的匹配方式。
Semver
If your images use semantic versioning you can filter by image tags that adhere to certain constraints:
正则匹配
总结
本文总结了对于 GitOps 原理的一些学习,通过对 GitOps 中的 Flux 进行实践,深度理解了一下部分原理。
https://fluxcd.io/
https://kubernetes.io/
https://www.weave.works/technologies/gitops/

建议收藏!|关于【数据存储】的干货





















