大家好,我是張晉濤。
經過前面三篇文章,不僅為大家介紹了什麼是 GitOps 也介紹瞭如何利用 Argo CD 來實施 GitOps。本篇我來為你介紹另一個可用於實施 GitOps 的工具:Flux CD 。
Flux CD
Flux 是一組可支持實現 GitOps 的工具,用於使 Kubernetes 集羣與配置源(如 Git 倉庫)保持同步,並在有代碼更新後自動同步配置,面向 Kubernetes 的持續漸進式交付解決方案。
Flux CD 的發展歷史
- 2016 年 10 月 28 日,Flux single-user service 版本發佈。
它奠定了 flux 的兩個基調:
-
- 集中式運行的服務
- 以守護進程的方式,在自動模式下運行在 k8s 集羣中
- 2016 年 12 月 15 日,發佈《使用 Weave Flux 持續交付》,構建了將 CI 與持續部署 (CD) 聯繫起來的 Flux。
- 2017 年 8 月 22 日,v1.0.0 版本正式發佈。
自 v1.0.0 開始,Flux 致力於將集羣與存儲在 Git 中的配置同步,並在新版本準備好部署時自動升級鏡像。(提出了:Configuration as code)
- 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 的開發。
-
- Flux v1 is in maintenance mode #3320 https://github.com/fluxcd/flu...
- Helm Operator (v1) is in maintenance mode #546 https://github.com/fluxcd/hel...
-
- V1 in maintenance #25 https://github.com/fluxcd/web...
- 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。
- 2021 年 8 月 13 日,正式發佈了《Flux v2 助力 GitOps 變得更好》,宣告了從 Flux 到 Flux v2 的交替。Flux v2 在 Flux 已有功能的基礎上,更適於 Kubernetes 的操作和可觀測性,並且功能更強大。Flux v2 的基礎是 GitOps Toolkit,這是一組用於構建基於 GitOps 的交付和自動化組件。(也實現了重要組件的解耦,具體可參考:https://www.weave.works/blog/...)
注:Flux 團隊決定在不使用 GitOps Engine 的情況下繼續前進,並構建了GitOps Toolkit。Flux v2 參考了 GitOps Engine ,但它不使用 GitOps Engine。
- 自 2018 年 10 月開始的 Flagger 項目也於 2021 年集成入 Flux v2。
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 資源,獨立於使用它們的組件進行管理。
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 狀態通知。
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.healthChecks 、spec.wait 和 spec.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 狀態的通知。
HelmRelease 對象定義了一個控制器資源通過 Helm 操作(例如安裝、升級、測試、卸載和回滾)驅動的 Helm Release 協調。包括髮布位置(namespace/name)、發佈內容(chart/values overrides)、操作觸發器配置、個別操作配置和狀態。
可以分別通過 spec.targetNamespace、spec.storageNamespace 和 spec.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 在每次源更改時觸發集羣協調。
Image reflector and automation controllers
image-reflector-controller 和 image-automation-controller 協同工作,在新的容器鏡像可用時更新 Git repository。
- image-reflector-controller 掃描鏡像倉庫,並與 K8S 資源中的元數據進行對比。
- image-automation-controller 根據掃描到的最新鏡像,更新 YAML 文件 並且提交變更到指定的 Git repository。
Flux CD 使用要求
Kubernetes 版本
使用 Flux CD,最好 Kubernetes 集羣版本在 v1.19 或更高版本。舊版本也支持,但官方不建議在生產中運行 EOL Kubernetes 版本。
注:如果你正在使用 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,敬請期待。