2

大家好,我是张晋涛。

经过前面三篇文章,不仅为大家介绍了什么是 GitOps 也介绍了如何利用 Argo CD 来实施 GitOps。本篇我来为你介绍另一个可用于实施 GitOps 的工具:Flux CD 。

Flux CD

img

Flux 是一组可支持实现 GitOps 的工具,用于使 Kubernetes 集群与配置源(如 Git 仓库)保持同步,并在有代码更新后自动同步配置,面向 Kubernetes 的持续渐进式交付解决方案

img

Flux CD 的发展历史

它奠定了 flux 的两个基调:

    • 集中式运行的服务
    • 以守护进程的方式,在自动模式下运行在 k8s 集群中
  • 2016 年 12 月 15 日,发布《使用 Weave Flux 持续交付》,构建了将 CI 与持续部署 (CD) 联系起来的 Flux。

img

  • 2017 年 8 月 22 日,v1.0.0 版本正式发布。

自 v1.0.0 开始,Flux 致力于将集群与存储在 Git 中的配置同步,并在新版本准备好部署时自动升级镜像。(提出了:Configuration as code)

img

  • 2018 年 5 月 1 日,发布的 alpha 版本中,集成了 Helm Operator 。这是 Flux Helm Operator 的第一个 alpha 标签的版本。
  • 2019 年 8 月 15 日,Flux 宣布加入 CNCF Sandbox。随着各开发者及企业开始落地 GitOps ,Flux 的用户数量不断增长。 彼时已超过 2500 个 GitHub star,也在不断地集成:Helm Operator 、 Kustomize 、 Weave Flagger 、 OpenFaaS 、 Fluxcloud 、 Flux Web UI 等。
  • 2019 年 10 月 2 日发布的版本,正式支持 kustomize 。
  • 2019 年 11 月 14 日,《Argo Flux 简介 - Weaveworks-Intuit-AWS 协作》中,Weaveworks 宣布与 Intuit 合作创建了 Argo Flux。该项目被称为 GitOps-Engine ,现在位于 Argo 项目组织中,由 Intuit、Red Hat 和 GitLab 驱动。(具体可参考:https://www.weave.works/blog/...
  • 2020 年 10 月 5 日,Flux v1(和 Helm Operator v1)宣布处于维护模式(仅提供 6 个月支持),并宣布将致力于 Flux v2 的开发。
  • 2021 年 2 月 17日新版本发布,正式将 issue、PR 指向 v2。
  • 2021 年 3 月 11 日,CNCF 技术监督委员会(TOC) 投票将 Flux 从 Sandbox 提升为孵化项目(Incubation)。自加入 CNCF Sandbox 以来,Flux 的最终用户群增加了 2.75 倍,并将其社区扩大了 2 至 4 倍,包括 Slack 用户、邮件列表订阅者和贡献者。 80 多个组织在生产中使用它,包括 Babylon Health、Fidelity Investments、MyFitnessPal、Starbucks 等等。 CNCF End User Community 将 Flux 纳入持续交付的 Technology Radar。

img

  • 2021 年 8 月 13 日,正式发布了《Flux v2 助力 GitOps 变得更好》,宣告了从 Flux 到 Flux v2 的交替。Flux v2 在 Flux 已有功能的基础上,更适于 Kubernetes 的操作和可观测性,并且功能更强大。Flux v2 的基础是 GitOps Toolkit,这是一组用于构建基于 GitOps 的交付和自动化组件。(也实现了重要组件的解耦,具体可参考:https://www.weave.works/blog/...

img

​ 注:Flux 团队决定在不使用 GitOps Engine 的情况下继续前进,并构建了GitOps Toolkit。Flux v2 参考了 GitOps Engine ,但它不使用 GitOps Engine。

  • 自 2018 年 10 月开始的 Flagger 项目也于 2021 年集成入 Flux v2。

img

img

Flux CD v2 和 GitOps Toolkit

GitOps Toolkit

GitOps Toolkit 是构成 Flux 运行时的一组 APIs 和 controllers 。可以通过 GitOps Toolkit 来扩展 Flux,并构建所需 CD 系统。

Source Controller

Source Controller 主要作用是为工件获取提供通用接口。Source API 定义了一组 Kubernetes 对象,cluster admin 和各种自动化 operator 可以与之交互,以将 Source(如 Git 和 Helm repo)注册、身份验证、验证和资源获取卸载到专用的 controller 。

每个 Flux 和 Helm 的 operator 都以相同的方式使用 Git repositories 中的代码(镜像),但是其他组件可能需要访问到不同的镜像。Flux 和 Helm operator 就可以使用标准的 Kubernetes 机制来构建 Source (通常是 Git repo,但也有 Helm chart 等) 作为 Kubernetes 资源,独立于使用它们的组件进行管理。

img

Git Repository

它为来自 Git 的 artifact 定义了一个源,将来自 Git 的最新状态作为 artifact 公开为 gzip 压缩的 TAR 文件 ( <commit hash>.tar.gz) 。

默认情况会排除,Git 文件 ( .git/ ,.gitignore, .gitmodules, .gitattributes);文件扩展名 ( .jpg, .jpeg, .gif, .png, .wmv, .flv, .tar.gz, .zip);CI 配置 ( .github/, .circleci/, .travis.yml, .gitlab-ci.yml, appveyor.yml, .drone.yml, cloudbuild.yaml, codeship-services.yml, codeship-steps.yml);CLI 配置 ( .goreleaser.yml, .sops.yaml);Flux v1 配置 ( .flux.yaml)。

如果想要自定义排除可以考虑以下两种办法:

  • 通过 .sourceignore 在 repository 的根目录中添加文件 。(遵循 .gitignore 格式,详见 https://git-scm.com/docs/giti...
  • 使用 spec.ignore 字段。
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
  name: podinfo
  namespace: default
spec:
  interval: 5m
  url: https://github.com/stefanprodan/podinfo
  ignore: |
    ## exclude all
    /*
    ## include deploy dir
    !/deploy
    ## exclude file extensions from deploy dir
    /deploy/**/*.md
    /deploy/**/*.txt  

Helm Charts

它为来自 Helm 源 的 Helm chart artifacts 定义了一个源,将作为 artifact 的最新拉取或打包的 chart 公开。

Helm Repositories

它为 Helm repositories 定义了一个源,将作为 artifact 的最新同步的 repository 索引公开。

Object storage buckets

它为来自 S3 兼容的存储(Minio, Amazon S3, Google Cloud Storage, Alibaba Cloud OSS 等等)定义了一个源,将来自 S3 的最新同步状态作为 artifact 公开为 gzip 压缩的 TAR 文件 ( <bucket checksum>.tar.gz) 。

默认及自定义排除文件,可参考 Git Repositories 中的排除文件相关内容。

Kustomize Controller

kustomize-controller 是一个专门用于运行通过使用 Kustomize 组装 Kubernetes 清单和工作负载定义的持续交付pipeline 的 Kubernetes operator。它提供一个自动化的 operator ,可以引导并持续协调来自多个 sources(例如基础设施和应用程序 repositories )的集群状态。

配置新集群时,可以按照特定顺序安装工作负载。当多个团队同时操作集群时,集群管理员可以为每个团队分配角色和服务帐户。团队拥有的 manifests 将使用团队帐户应用于集群,从而确保团队之间的隔离。

处理事件时,可以选择不停止协调器影响整个集群,采用暂停某些工作负载的协调并将其他工作负载的协调固定到指定的 Git 版本的方式进行。

操作集群时,不同的团队可以收到与之相关的 CD pipeline 状态通知。

img

Kustomization API 定义了一个可以获取,解密,构建,验证和应用 Kubernetes manifests 的 pipeline 。

spec.sourceRef 是对 Source Controller 管理的对象的引用 。当 Source (支持类型:GitRepository、Bucket)版本变更时,它会生成一个 Kubernetes 事件,触发 kustomize 的构建和应用。

如果 repository 包含原始的 Kubernetes manifest,会为 spec.path 和子目录中的所有 Kubernetes manifest 自动生成 kustomization.yaml。(建议 kustomization.yaml 自行生成并存储在 Git 仓库中)

spec.interval 告诉 Controller 在哪个时间间隔为 Source 获取 Kubernetes manifest,构建 Kustomization 并将其应用于集群。间隔时间单位是 s(最小值应超过 60 秒,interval: 60s)。

spec.healthChecksspec.waitspec.timeout 可以设置一系列运行状况检查。

  • Kubernetes 内置(Deployment、DaemonSet、StatefulSet、PersistentVolumeClaim、Pod、PodDisruptionBudget、Job、CronJob、Service、Secret、ConfigMap、CustomResourceDefinition)
  • Toolkit (HelmRelease、HelmRepository、GitRepository等)
  • 与 kstatus 兼容的自定义资源 (https://github.com/kubernetes...

spec.dependsOn 可以自定义依赖。多个 Kustomizations 的情况下,可以指定先后顺序及依赖。这就引入了两个必须注意的地方:

  • 避免循环。
  • 与健康检查结合使用时,将在其所有依赖项健康检查通过后运行 Kustomization。

Kustomization 在覆盖自定义配置、变量替换、加解密等也有这很多灵活的设置,感兴趣的小伙伴可以自行阅读官方文档了解。

Helm Controller

Helm Controller 是一个 Kubernetes operator,允许使用 Kubernetes manifests 以声明方式管理 Helm chart Release。它提供一个自动化的 operator ,可以执行 Helm 操作(例如安装、升级、卸载、回滚、测试)并持续协调 Helm Release的状态。

配置新集群时,可以指定顺序安装 Helm Release。处理事件时,可以不必停止协调器影响整个集群,采用暂停一些 Helm Release 的协调即可。操作集群时,不同的团队可以收到与其有关的 Helm Release 状态的通知。
img

img

HelmRelease 对象定义了一个控制器资源通过 Helm 操作(例如安装、升级、测试、卸载和回滚)驱动的 Helm Release 协调。包括发布位置(namespace/name)、发布内容(chart/values overrides)、操作触发器配置、个别操作配置和状态。

可以分别通过 spec.targetNamespacespec.storageNamespacespec.releaseName 覆盖默认部署和存储 Helm Release 的namespace/name。

spec.chart.spec 是创建具有指定 spec 的新 HelmChart 资源的模板。spec.chart.spec.sourceRef 是对 Source Controller 管理的对象的引用。 当 source(支持类型:HelmRepository、GitRepository、Bucket) 版本变更时,会生成触发新版本的 Kubernetes 事件。

如果没有找到具有匹配 namespace/name 的 Helm Release,将安装配置中的 Helm Release 。

当出现以下状态更新时,Helm Release 将升级:

  • spec (以及 metadata.generation )
  • 最新的 HelmChart 修订版可用
  • ConfigMap 和 Secret 值覆盖(为了避免在更新多个资源时发生大量升级,不会立即进行,会在spec.interval 间隔后进行)

Helm 支持安装 CRD,由于存在数据丢失的风险,目前暂不支持使用 Helm 升级或删除 CRD。

更多 Helm Controller 的详细内容欢迎参考官方文档。

Notification Controller

Notification Controller 是一个 Kubernetes operator,专门处理出入口事件。

它提供一个通知服务,可以通过 HTTP 接收事件并根据事件严重性和涉及的对象将它们分派到外部系统(Slack、Microsoft Teams、Discord、Rocker)。

GitOps Controller 本质上是基于拉取的,为了通知 Controllers 有关 Git 或 Helm 库中的变更,可以支持设置 webhooks 在每次源更改时触发集群协调。

img

Image reflector and automation controllers

image-reflector-controller 和 image-automation-controller 协同工作,在新的容器镜像可用时更新 Git repository。

  • image-reflector-controller 扫描镜像仓库,并与 K8S 资源中的元数据进行对比。
  • image-automation-controller 根据扫描到的最新镜像,更新 YAML 文件 并且提交变更到指定的 Git repository。

img

Flux CD 使用要求

Kubernetes 版本

使用 Flux CD,最好 Kubernetes 集群版本在 v1.19 或更高版本。旧版本也支持,但官方不建议在生产中运行 EOL Kubernetes 版本。

img

注:如果你正在使用 APIService(例如 metrics-server),Kubernetes 集群版本至少需要 v1.18.18,v1.19.10,v1.20.6 或 v1.21.0 。

Git Repo 权限

通过设置 SSH 部署密钥或使用基于令牌的身份验证,将目标集群配置为与 Git 库进行同步。

  • GitLab 使用示例
//将 GitLab personal access token 导出为环境变量:
export GITLAB_TOKEN=<your-token>
//在 GitLab 账号上运行 git 库的引导程序:
flux bootstrap gitlab \
  --owner=my-gitlab-username \
  --repository=my-repository \
  --branch=master \
  --path=clusters/my-cluster \
  --token-auth \
  --personal
//使用部署密钥进行身份验证运行 git 库的引导程序,必须指定 SSH hostname:
flux bootstrap gitlab \
  --ssh-hostname=gitlab.com \
  --owner=my-gitlab-username \
  --repository=my-repository \
  --branch=master \
  --path=clusters/my-cluster
//为 GitLab 团队的 git 库运行引导程序:
flux bootstrap gitlab \
  --owner=my-gitlab-group/my-gitlab-subgroup \
  --repository=my-repository \
  --branch=master \
  --path=clusters/my-cluster
//为托管在本地或企业 GitLab 上的 git 库运行引导程序,必须指定 GitLab hostname:
flux bootstrap gitlab \
  --hostname=my-gitlab.com \
  --token-auth \
  --owner=my-gitlab-group \
  --repository=my-repository \
  --branch=master \
  --path=clusters/my-cluster
  • GitHub 使用示例
//将 GitHub personal access token 导出为环境变量:
export GITHUB_TOKEN=<your-token>
//flux bootstrap 命令会创建一个 SSH 密钥,并存储在 Kubernetes 集群中。
//该密钥还用于在 GitHub 库中创建部署密钥。
//在 GitHub 账号上运行 git 库的引导程序:
flux bootstrap github \
  --owner=my-github-username \
  --repository=my-repository \
  --path=clusters/my-cluster \
  --personal
//当指定团队列表时,这些团队将被授予对 git 库的维护者访问权限。
//为 GitHub 中团队拥有的 git 库运行引导程序:
flux bootstrap github \
  --owner=my-github-organization \
  --repository=my-repository \
  --team=team1-slug \
  --team=team2-slug \
  --path=clusters/my-cluster

总结

本篇主要介绍了 Flux CD 的发展历史和其核心组件及其功能,后续文章中将陆续介绍如何使用 Flux CD 来实践 GitOps,敬请期待。


张晋涛
1.7k 声望19.7k 粉丝