GitOps 這個概念最早是由Kubernetes 管理公司Weaveworks 公司在2017 年提出的,如今已經過去了5 個年頭,想必大家對這個概念早有耳聞,但你可能並不知道它到底是什麼,它和DevOps 到底是啥關係,本文就來幫大家一一解惑。

基礎設施即代碼

在理解GitOps 之前,我們需要先理解什麼是基礎設施即代碼

基礎設施即代碼(Infrastructure as Code, IaC),顧名思義,表示使用代碼(而非手動流程)來定義基礎設施,研發人員可以像對待應用軟件一樣對待基礎設施,例如:

  • 可以創建包含基礎架構規範的聲明式配置文件,從而便於編輯和分發配置。
  • 可以確保每次配置的環境都完全相同。
  • 可以進行版本控制,所有的變更都會被記錄下來,方便溯源。
  • 可以將基礎設施劃分為若干個模塊化組件,並通過自動化以不同的方式進行組合。

當然,廣義上的IaC 不僅僅只關於基礎設施,還包含了網絡安全配置等等,所以廣義上的IaC 又叫X as Code

比如你想在AWS 中創建服務器,配置網絡,部署Kubernetes 集群以及各種工作負載,你只需要定義好Terraform 或Ansible 的聲明式配置,以及Kubernetes 的配置清單即可,免去一切繁雜的手動操作。

GitOps 是什麼

GitOps = IaC + Git + CI/CD,即基於IaC 的版本化CI/CD。它的核心是使用Git 倉庫來管理基礎設施和應用的配置,並且以Git 倉庫作為基礎設施和應用的單一事實來源,你從其他地方修改配置(比如手動改線上配置)一概不予通過。

Git 倉庫中的聲明式配置描述了目標環境當前所需基礎設施的期望狀態,借助於GitOps,如果集群的實際狀態與Git 倉庫中定義的期望狀態不匹配,Kubernetes reconcilers 會根據期望狀態來調整當前的狀態,最終使實際狀態符合期望狀態。

另一方面,現代應用的開發更多關注的是迭代速度和規模,擁有成熟DevOps 文化的組織每天可以將代碼部署到生成環境中數百次,DevOps 團隊可以通過版本控制、代碼審查以及自動測試和部署的CI/CD 流水線等最佳實踐來實現這一目標,這就是GitOps 幹的事情。

GitOps vs DevOps

從廣義上來看,GitOps 與DevOps 並不衝突,GitOps 是一種技術手段,而DevOps 是一種文化。GitOps 是一種實現持續交付(Continuous Delivery)、持續部署(Continuous Deployment)和基礎設施即代碼(IaC)的工具和框架,它是支持DevOps 文化的。

從狹義上來看,GitOps 與DevOps 有以下幾個區別:

首先,GitOps 是以目標為導向的。它使用Git 來維護期望狀態,並不斷調整實際狀態,最終與期望狀態相匹配。而DevOps 更多關注的是最佳實踐,這些實踐可以普遍應用於企業的每一個流程。

其次,GitOps 採取聲明式的操作方法,而DevOps 同時接受聲明式和命令式的方法,所以DevOps 除了適用於容器環境之外,還適用於虛擬機和裸機環境。

最後,GitOps 重新定義了雲原生場景下的CI/CD,它以Git 作為中心的不可變狀態聲明,以加快持續部署速度。

GitOps 的設計哲學

想要使用GitOps 來管理你的基礎設施和應用,需要踐行以下幾個原則:

1. 聲明式

必須通過聲明式來描述系統的期望狀態。例如Kubernetes,眾多現代云原生工具都是聲明式的,Kubernetes 只是其中的一種。

2. 版本控制/不可變

因為所有的狀態聲明都存儲在Git 倉庫中,並且把Git 倉庫作為單一事實來源,那麼所有的操作都是從Git 倉庫裡驅動的,而且保留了完整的版本歷史,方便回滾。有了Git 優秀的安全保障,也可以使用SSH 密鑰來簽署commits,對代碼的作者和出處實施強有力的安全保障。

3. 自動應用變更

Git 倉庫中聲明的期望狀態發生了任何變更,都可以立即應用到系統中,而且不需要安裝配置額外工具(比如kubectl),也不需要配置Kubernetes 的認證授權。

4. 持續的Reconciliation

Reconciliation 其實最早是Kubernetes 裡的一個概念,表示的是確保系統的實際狀態與期望狀態一致的過程。具體的實現方式是在目標環境中安裝一個agent,一旦實際狀態與期望狀態不匹配,agent 就會進行自動修復。這裡的修復比Kubernetes 的故障自愈更高級,即使是手動修改了集群的編排清單,集群也會被恢復到Git 倉庫中的清單所描述的狀態。

鑑於以上這些設計哲學,我們來看一下GitOps 的工作流:

  • 首先,團隊中的任何一個成員都可以Fork 倉庫對配置進行更改,然後提交Pull Request。
  • 接下來會運行CI 流水線,一般會做這麼幾件事情:驗證配置文件、執行自動化測試、檢測代碼的複雜性、構建OCI 鏡像、將鏡像推送到鏡像倉庫等等。
  • CI 流水線運行完成後,團隊中擁有合併代碼權限的人將會將這個Pull Request 合併到主分支中。一般擁有這個權限的都是研發人員、安全專家或者高級運維工程師。
  • 最後會運行CD 流水線,將變更應用到目標系統中(比如Kubernetes 集群或者AWS) 。

整個過程完全自動化且透明,通過多人協作和自動化測試來保證了基礎設施聲明配置的健壯性。而傳統的模式是其中一個工程師在自己的電腦上操作這一切,其他人不知道發生了什麼,也無法對其操作進行Review。

Push vs Pull

CD 流水線有兩種模式:Push 和Pull。

Push 模式

目前大多數CI/CD 工具都使用基於Push 的部署模式,例如Jenkins、CircleCI 等。這種模式一般都會在CI 流水線運行完成後執行一個命令(比如kubectl)將應用部署到目標環境中。

這種CD 模式的缺陷很明顯:

  • 需要安裝配置額外工具(比如kubectl);
  • 需要Kubernetes 對其進行授權;
  • 需要雲平台授權;
  • 無法感知部署狀態。也就無法感知期望狀態與實際狀態的偏差,需要藉助額外的方案來保障一致性。

Kubernetes 集群或者云平台對CI 系統的授權憑證在集群或云平台的信任域之外,不受集群或云平台的安全策略保護,因此CI 系統很容易被當成非法攻擊的載體。

Pull 模式

Pull 模式會在目標環境中安裝一個Agent,例如在Kubernetes 集群中就靠Operator 來充當這個Agent。Operator 會周期性地監控目標環境的實際狀態,並與Git 倉庫中的期望狀態進行比較,如果實際狀態不符合期望狀態,Operator 就會更新基礎設施的實際狀態以匹配期望狀態。

只有Git 的變更可以作為期望狀態的唯一來源,除此之外,任何人都不可以對集群進行任何更改,即使你修改了,也會被Operator 還原為期望狀態,這也就是傳說中的不可變基礎設施

目前基於Pull 模式的CD 工具有 Argo CD, Flux CD以及 ks-devops

GitOps 的優勢

一般GitOps 首選的都是基於Pull 的部署模式,因為這種模式有很多不可替代的優勢。

更強大的安全保障

上面已經提到了,使用GitOps 不需要任何Kubernetes 或者云平台的憑證來執行部署,Kubernetes 集群內的Argo CD 或者Flux CD 只需要訪問Git 倉庫,並通過Pull 模式來更新即可。

另一方面,Git 由用於跟踪和管理代碼變更的強大密碼學支持,擁有對變更進行簽名以證明作者身份和來源的能力,這是保障集群安全的關鍵。

Git 作為事實的唯一真實來源

因為所有的應用包括基礎設施的聲明式配置都保存在Git 中,並把Git 作為應用系統的唯一事實來源,因此可以利用Git 的強大功能操作所有東西,例如版本控制、歷史記錄、審計和回滾等等,無需使用kubectl 這樣的工具來操作。

提高生產力

Git 也是開發人員非常熟悉的工具,通過Git 不斷迭代,可以提高生產率,加快開發和部署速度,更快地推出新產品,同時提高系統的穩定性和可靠性。

更容易合規的審計

使用GitOps 的基礎設施可以像任何軟件項目一樣使用Git 來管理,所以同樣可以對其進行質量審計。當有人需要對基礎設施進行更改時,會創建一個Pull Request,等相關人員對其進行Code Review 之後,更改才可以應用到系統中。

總結

GitOps 是對現有DevOps 文化的補充,它使用Git 這樣的版本控制系統來自動部署基礎設施,部署過程清晰可見,可以查看和跟踪對系統進行的任何變更,提高了生產力、安全性和合規性。而且GitOps 提供了更優雅的可觀測性,可以實時觀測部署狀態,並採取行動使實際狀態與期望狀態保持一致。

而且在GitOps 中,整個系統都是通過聲明式來描述的,天然適合雲原生環境,因為Kubernetes 也是這麼設計的。

參考資料

By tony

自由軟體愛好者~喜歡不斷的思考各種問題,有新的事物都會想去學習嘗試 做實驗並熱衷研究 沒有所謂頂天的技術 只有謙虛及不斷的學習 精進專業,本站主要以分享系統及網路相關知識、資源而建立。 Github http://stnet253.github.io

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料