前言
GitOps 是實現持續部署的云原生方式。它的名字來源于標準且占主導地位的版本控制系統 Git。GitOps 的 Git 在某種程度上類似于 Kubernetes 的 etcd,但更進一步,因為 etcd 本身不保存版本歷史記錄。毋庸置疑,任何源代碼管理服務,包括 GitLab、GitHub、Bitbucket、Azure DevOps 或類似的服務,都可以使用。在 GitOps 中,VCS 是單一事實來源。
作為開發人員,我們以聲明式的方式實現基礎設施定義、數據庫模式、應用程序配置和策略,然后將代碼推送到 Git 倉庫。運維人員獲取所需狀態并將其應用到我們的控制平面。這個控制平面主要是一個 Kubernetes 控制平面。GitOps 是一個伴隨云原生生態系統而出現和發展的術語。因此,所有 GitOps 提供商都與 Kubernetes 集成。Kubernetes 正在發展成為統領所有其他控制平面的唯一控制平面。在接下來的文章中,我會詳細討論這個術語。
OpenGitOps
?
我們從 OpenGitOps 社區開始討論GitOps 。OpenGitOps 旨在標準化 GitOps 原則,定義并幫助采用 GitOps 的最佳實踐。OpenGitOps 同時也是 CNCF 的沙盒級項目。它由七個成員創立:亞馬遜、Azure、Github、RedHat、CodeFresh、WeaveWorks 和 Crayon。可以說,這些成員是對 GitOps 生態系統貢獻最大的公司之一。OpenGitOps 社區定義了四個主要的 GitOps 原則:
- 由 GitOps 管理的系統必須以聲明式的方式表達其期望狀態:聲明式狀態是近年來基礎設施即代碼 (IaC) 工具的標志之一。聲明式意味著描述要實現的目標,而不是命令要做什么。舉個例子,“我希望兩臺服務器運行”是聲明式的,但“運行兩臺服務器”是命令式的。當你重復這兩個句子時,第一個句子會導致兩臺服務器運行,而第二個句子會導致四臺服務器運行。聲明式語句天生具有冪等性,這在 IaC 領域至關重要。
- 所需狀態的存儲方式強制執行不變性、版本控制并保留完整的版本歷史記錄:不變性、版本控制和完整的版本歷史記錄表明需要使用版本控制系統,因為 VCS 上保存的配置默認是版本控制的。它只能通過提交、推送和/或拉取請求進行更改。這保證了所需級別的不變性,并且所有更改都可以追溯并在需要時回滾。
- 軟件代理自動從源頭拉取所需狀態聲明:在傳統的 CI/CD 方法中,容器鏡像被構建并推送到容器注冊表。資源定義文件(原始清單、Helm Charts、Kustomize 文件)使用鏡像標簽進行修改。之后,使用 helm、kubectl ?將它們推送到集群。這需要將服務帳戶令牌存儲在集群外部并用于應用更改。因此,密碼必須安全地保存在 CI/CD 管道中。與此不同,GitOps 工具提供了基于拉取的方法,這意味著 GitOps 操作員在集群中運行并定期從 git 存儲庫拉取配置更改,或訂閱 git 存儲庫事件并等待觸發更改。檢測到更改后,操作員通過調用 kubeapi 將其應用到集群。這更安全、更自然。
- 軟件代理持續觀察實際系統狀態并嘗試應用所需狀態:GitOps 操作員從 git 存儲庫拉取更改,并定期將所需狀態與集群狀態進行比較。這稱為漂移檢測。任何更改都會應用于集群。任何人對其管理的資源所做的手動更改都將被還原。這稱為協調。Git 拉取請求是更改正在運行的集群狀態的唯一方法。這有助于將容器級別的不變性擴展到基礎設施級別,從而避免許多問題。
GitOps 的爆炸式增長
早在2017 年,Weaveworks公司(是一家由 Alexis Richardson 聯合創立的公司)就發表關于?GitOps 的文章,強調了我們如今使用的很多原則,例如一切皆代碼、所有期望狀態必須以聲明式定義、自動偏差檢測等等。在這篇文章之后,又陸續發表了另外三篇文章。正如文章中提到的,它們也使用了自動協調功能。Weaveworks 引入了 GitOps 的概念,將 Git、Kubernetes 和持續交付 (CD) 融合成一個統一的運維模型。
Weaveworks 積極參與開源社區,組織活動、參加會議并參與 GitOps 相關的討論。這種社區建設工作有助于促進整個生態系統的協作和知識共享。
Weaveworks 提出Ansiblediff、Terradiff 和 Kubediff 作業,用于檢測 Kubernetes 集群上的漂移,并自動協調提交給 Git 的各種資源定義的所需狀態提出檢測偏差(集群的實際狀態與 Git 中定義的期望狀態存在偏差)。
我們可以將 WeaveWorks 所做的工作視為持續交付最佳實踐與我們環境中實際應用情況之間的偏差檢測。他們將我們的持續交付生態系統與這些最佳實踐進行了協調。我們可以說,那些文章中提到的很多內容在當時也是共識,但將它們全部用到我們今天使用的名稱上,并以 git 作為主題,才是 GitOps 的真正意義所在。
GitOps 工具
從那時起,GitOps 的原則基本保持不變,但涌現出了許多不同的工具。在包括科技巨頭在內的開源社區的大力貢獻下,標準化逐漸成型。
GitOps 領域出現了兩個最重要的工具:Argo CD 和 Flux。在撰寫本文時,它們都是 CNCF 孵化級項目,并且都提供了許多強大的功能和輔助工具。GitOps 僅解決了 CI/CD 中的持續部署部分,因此我們需要來自不同產品的其他部分。這些其他部分包括漸進式交付工具(藍綠部署、金絲雀部署)、持續集成工具、鏡像控制器(等待新鏡像推送并更新資源定義)等等。
Argo 項目家族包括工作流(持續集成)、事件(事件驅動的工作流自動化)、部署(漸進式交付)工具,除了 CD 工具之外,它還包含許多輔助工具。另一方面,Flux 項目家族除了 Flux 本身之外,還包含 Flagger 作為漸進式交付工具,并且在 GitOps Toolkit 框架下擁有許多輔助工具。當我們比較持續交付 (CD) 工具時,這兩個項目都是非常出色的項目;如果我們將這種比較擴展到其他工具,Argo 家族似乎更加完整,因為 Argo Workflows(任何持續交付 (CI) 工具都可以與 Argo CD 或 Flux 配合使用)。它還有一個儀表板,雖然對大多數人來說意義不大,但在某些情況下確實很有幫助。如果您已經掌握了其他可觀察性和可視化工具,則無需再添加太多儀表板。
還有一些 GitOps 工具,它們不如這兩個工具成熟,但確實很有前景。Rancher Fleet 就是其中之一。他們秉持“規模化 GitOps”的理念,并致力于管理集群 Fleet,就像 Rancher 多年來一直在嘗試的那樣。但我們必須承認,如果沒有 GitOps,這一切都不可能實現。你也可以使用 Argo CD 和 Flux 來管理集群。
GitOps 項目的數量呈爆炸式增長。除了我們熟悉的項目之外,還有 PipeCD、Werf、Atlantis 等等。
Argo CD 和 Flux 已經成為許多企業級 PAAS 服務的基石。例如,Azure Arc 和 WeaveCloud(不出所料)使用了 Flux,Openshift GitOps 和 Codefresh 使用了 Argo CD。
?
Flux 演示
要遵循本指南,您需要以下資源:
- 一個 Kubernetes 集群。。
- 一個具有代碼庫權限的 GitHub 個人訪問令牌。請參閱 GitHub 文檔,了解如何創建個人訪問令牌。
- Flux CLI
導出您的憑據
導出您的 GitHub 個人訪問令牌和用戶名:
export GITHUB_TOKEN=<your-token>
export GITHUB_USER=<your-username>
驗證kubernetes 集群?
ninjamac@ninjamacdeMacBook-Air fluxcd % flux check --pre
? checking prerequisites
? Kubernetes 1.32.2 >=1.30.0-0
? prerequisites checks passed
在集群中安裝flux?
ninjamac@ninjamacdeMacBook-Air fluxcd % flux bootstrap github \ --owner=$GITHUB_USER \ --repository=fluxcd \--branch=main \--path=. \ --personal
將 podinfo 倉庫添加到 Flux
本示例使用公共倉庫 github.com/stefanprodan/podinfo,podinfo 是一個用 Go 語言編寫的小型 Web 應用程序。
創建一個指向 podinfo 倉庫 master 分支的 GitRepository 清單:
flux create source git podinfo \--url=https://github.com/stefanprodan/podinfo \--branch=master \--interval=1m \--export > ./podinfo-source.yaml
提交并將 podinfo-source.yaml 文件推送到 fluxcd倉庫:
git add -A && git commit -m "Add podinfo GitRepository"
git push origin main
部署 podinfo 應用
配置 Flux 以構建并應用位于 podinfo 倉庫中的 kustomize 目錄。
使用 flux create 命令創建應用 podinfo 部署的 Kustomization。
flux create kustomization podinfo \--target-namespace=default \--source=podinfo \--path="./kustomize" \--prune=true \--wait=true \--interval=30m \--retry-interval=2m \--health-check-timeout=3m \--export > ./podinfo-kustomization.yaml
提交 Kustomization 清單并將其推送到代碼庫:
git add -A && git commit -m "Add podinfo Kustomization"
git push origin main
監控 Flux 同步應用程序
使用 flux get 命令監控 podinfo 應用程序。
使用kubectl get 命令檢查pod service 等信息:
對主分支中 podinfo Kubernetes 清單所做的更改會反映在您的集群中。
當從 podinfo 倉庫中移除 Kubernetes 清單時,Flux 會將其從您的集群中移除。當您從 fluxcd 倉庫中刪除 Kustomization 時,Flux 會移除之前從該 Kustomization 應用的所有 Kubernetes 對象。
當您使用 kubectl edit 修改 podinfo 部署時,更改會還原到與 Git 中描述的狀態一致。
暫停更新
暫停 Kustomization 的更新允許您直接編輯從 Kustomization 應用的對象,而不會根據 Git 中的狀態還原您的更改。
要暫停 Kustomization 的更新,請運行命令 flux suspend kustomization <name>。
要恢復更新,請運行命令 flux resume kustomization <name>。
?
自定義 podinfo 部署
要從您無法控制的倉庫自定義部署,您可以使用 Flux 內聯補丁。以下示例展示了如何使用內聯補丁更改 podinfo 部署。
將以下內容添加到 podinfo-kustomization.yaml 文件的字段規范中:
patches:- patch: |-apiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata:name: podinfospec:minReplicas: 3 target:name: podinfokind: HorizontalPodAutoscaler
提交并推送 podinfo-kustomization.yaml 的更改:
git add -A && git commit -m "Increase podinfo minimum replicas"
git push origin main
同步完成后,運行 kubectl get pods 應該會顯示 3 個 pod。
?
?
總結
對于任何新技術,我們都必須思考的幾個問題之一是它解決了哪些問題。之前的工具遺漏了什么?GitOps 工具帶來了哪些新特性?
在 GitOps 工具出現之前,聲明式期望狀態就已經被使用。正如我們提到的,這是 GitOps 出現之前現代 IaC 工具的標志之一。聲明式期望狀態也應用于 Kubernetes 本身。可以說,GitOps 工具已經很好地采用了這種做法。
在 GitOps 工具出現之前,使用版本控制來存儲期望狀態也是一種常見的范例,但 GitOps 通過強制使用版本控制系統 (VCS) 將這種方法更進一步。其他工具可以從開發人員的機器上應用期望狀態。使用 GitOps 時,必須將更改推送到遠程 Git 存儲庫才能進行部署。
GitOps 為 IaC 生態系統帶來的另一個新特性是從 Git 存儲庫中提取期望狀態,而不是使用 CD 工具進行推送。這帶來了一種新的安全強化方式。
我們可以毫不夸張地說,GitOps 工具帶來的最大改進是持續的漂移檢測和協調。這顯然是真正的游戲規則改變者。通過此功能,我們可以構建不可變的基礎設施并消除人為錯誤。如今,甚至有一些工具將此功能引入了 Terraform 領域。Flux Terraform Provider(實驗性)和 Crossplane Terrajet Providers(在某種程度上,因為它們使用 Terraform Providers 生成 Kubernetes CRD)就是其中兩個。
正如那句名言所說,沒有靈丹妙藥。每種技術都有其優缺點。我們在前面的段落中已經提到了 GitOps 的優點。多年來,憑借圍繞云原生生態系統聚集的龐大社區,GitOps 工具已經解決了許多問題。大多數問題在早期的 GitOps 工具中都存在,但隨著時間的推移,這些問題逐漸演變。現在是采用 GitOps 的好時機。列舉一些目前相對存在的問題,大型云供應商提供的 PaaS 產品并不多(我們可以在這里列舉 Anthos Config Management 和 Azure Arc),我們需要一個 Kubernetes 集群來應用 GitOps(對包括我在內的大多數社區成員來說這不是問題),Git 提供了回滾機制來回滾更改,但 git 有不同的回滾命令,因此必須謹慎處理,GitOps 和水平 Pod 自動伸縮器的協同工作也是另一個需要仔細思考的點。 GitOps 也不支持不同環境之間的傳播,必須使用另一個 CI/CD 工具來處理。
?