GitOps | 一種實現雲原生的持續交付模型

GitOps | 一種實現雲原生的持續交付模型

來自專欄 IT大咖說5 人贊了文章

你可能已經聽說過「GitOps」,但並不知道它到底是什麼,除了GitOps,你可能還聽說過DevOps,或者AIOps、GOps等,是的,現在是「Ops」盛行的時代。

GitOps是一種實現持續交付的模型,它的核心思想是將應用系統的聲明性基礎架構和應用程序存放在Git的版本控制庫中。Choerodon豬齒魚在構建持續交付流水線時參考了GitOps,並進行了實踐,俗話說「兵馬未動,理論先行」,在本文中,將重點闡述GitOps工作流程的原理和模式,以及將它們應用在生產和大規模運行Kubernetes中的一些實踐經驗

GitOps,90%的最佳實踐,10%有意思的新東西需要我們去構建。 —— 《?GitOps - Operations by Pull Request》來自:https://www.weave.works

這篇文章是根據Weave Cloud的幾篇關於GitOps的文章翻譯整理而來:

GitOps

GitOps: Operations by Pull Request

The GitOps Pipeline - Part 2

GitOps - Part 3: Observability

GitOps - Part 4: Application Delivery Compliance and Secure CICD

主要內容:

  • 什麼是GitOps?
  • GitOps的主要優點
  • GitOps的應用場景——適合雲原生的持續交付
  • GitOps的基本原則
  • 最佳實踐
  • 拉式流水線——Pull Request操作
  • GitOps工作流
  • 可視化
  • 應用交付的合規性和安全的CI/CD
  • GitOps帶來的價值

什麼是GitOps?

GitOps是一種持續交付的方式。它的核心思想是將應用系統的聲明性基礎架構和應用程序存放在Git版本庫中。

將Git作為交付流水線的核心,每個開發人員都可以提交拉取請求(Pull Request)並使用Gi??t來加速和簡化Kubernetes的應用程序部署和運維任務。通過使用像Git這樣的簡單工具,開發人員可以更高效地將注意力集中在創建新功能而不是運維相關任務上(例如,應用系統安裝、配置、遷移等)。

GitOps: versioned CI/CD on top of declarative infrastructure. Stop scripting and start shipping. t.co/SgUlHgNrnY — Kelsey Hightower (@kelseyhightower) January 17, 2018

GitOps的主要優點

通過GitOps,當使用Git提交基礎架構代碼更改時,自動化的交付流水線會將這些更改應用到應用程序的實際基礎架構上。但是GitOps的想法遠不止於此——它還會使用工具將整個應用程序的實際生產狀態與基礎架構源代碼進行比較,然後它會告訴集群哪些基礎架構源代碼與實際環境不匹配。

通過應用GitOps最佳實踐,應用系統的基礎架構和應用程序代碼都有「真實來源」——其實是將基礎架構和應用程序代碼都存放在gitlab、或者github等版本控制系統上。這使開發團隊可以提高開發和部署速度並提高應用系統可靠性。

將GitOps理論方法應用在持續交付流水線上,有諸多優勢和特點:

  • 安全的雲原生CI/CD管道模型
  • 更快的平均部署時間和平均恢復時間
  • 穩定且可重現的回滾(例如,根據Git恢復/回滾/ fork)
  • 與監控和可視化工具相結合,對已經部署的應用進行全方位的監控

GitOps應用場景——滿足雲原生環境下的持續交付

作為CI / CD流水線的方案,GitOps被描述為軟體開發過程的「聖杯」。 由於沒有單一工具可以完成流水線中所需的所有工作,因此可以自由地為流水線的不同部分選擇最佳工具。可以從開源生態系統中選擇一組工具,也可以從封閉源中選擇一組工具,或者根據使用情況,甚至可以將它們組合在一起,其實,創建流水線最困難的部分是將所有部件粘合在一起

不管如何選擇構造自己的交付流水線,將基於Git(或者其他版本控制工具)的GitOps最佳實踐應用在交付流水線中都是一個不二選擇,這將使構建持續交付流水線,以及後續的推廣變得更加容易,這不僅從技術角度而且從文化角度來看都是如此。

當然,GitOps也不是萬能的,它也有相應的應用場景。

不可變基礎設施

應用都需要運行在多台機器上,它們被組織成不同的環境,例如開發環境、測試環境和生產環境等等。需要將相同的應用部署到不同的機器上。通常需要系統管理員確保所有的機器都處於相同的狀態。接著所有的修改、補丁、升級需要在所有的機器中進行。隨著時間的推移,很難再確保所有的機器處於相同的狀態,同時越來越容易出錯。這就是傳統的可變架構中經常出現的問題。這時我們有了不可變架構,它將整個機器環境打包成一個單一的不可變單元,而不是傳統方式僅僅打包應用。這個單元包含了之前所說的整個環境棧和應用所有的修改、補丁和升級,這就解決了前面的問題。 —— 摘自InfoQ的《關於不可變架構以及為什麼需要不可變架構》作者 百占輝

「不可變基礎設施」這一概念不是剛剛冒出來的,它也不是必須需要容器技術。然而,通過容器,它變得更易於理解,更加實用,並引起了業內廣泛注意。「不可變基礎設施」讓我們以全新的方式理解和面對應用系統,尤其是使以微服務為代表的分散式系統在部署、運營等方面變得不那麼複雜,而有很好的可控性。

那麼,如何比較方便地在實際的生產過程中應用「不可變基礎設施」,這給業界也提出了另外一個問題。

GitOps是在具體Kubernetes的應用實踐中出現的,GitOps需要依託於「不可變基礎架構」才能發揮其作用。在一定程度上說,「不可變基礎架構」為GitOps的出現創造了必要的條件,反過來GitOps應用Kubernetes的容器編排能力,能夠迅速的使用鏡像搭建出應用系統所需的組件。

聲明性容器編排

Kubermetes作為一個雲原生的工具,可以把它的「聲明性」看作是「代碼」,聲明意味著配置由一組事實而不是一組指令組成,例如,「有十個redis伺服器」,而不是「啟動十個redis伺服器,告訴我它是否有效」。

藉助Kubermetes的聲明性特點,應用系統的整個配置文件集可以在Git庫中進行版本控制。通過使用Git庫,應用程序更容易部署到Kubernetes中,以及進行版本回滾。更重要的是,當災難發生時,群集的基礎架構可以從Git庫中可靠且快速地恢復。

Kubernetes等雲原生工具的聲明性體現在可以對實例、容器、網路、存儲、CPU等配置通過一組代碼方便的表達出來,Kubernetes等雲原生工具可以利用這些配置代碼運行出來一套基於容器的應用系統,例如YMAL,

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

name: nginx-deployment

spec:

replicas: 1

template:

metadata:

labels:

app: nginx

spec:

containers:

- name: nginx

image: registry.choerodon.com.cn

ports:

- containerPort: 80

GitOps充分利用了不可變基礎設施和聲明性容器編排,通過GitOps可以輕鬆地管理多個部署。為了最大限度地降低部署後的變更風險,無論是有意還是偶然的「配置偏差」,GitOps構建了一個可重複且可靠的部署過程,在整個應用系統宕機或者損壞情況下,為快速且完全恢復提供了所需條件。

GitOps的基本原則

以下是在雲原生環境中GitOps的原則:

  • 任何能夠被描述的內容都必須存儲在Git庫中

通過使用Git作為存儲聲明性基礎架構和應用程序代碼的存儲倉庫,可以方便地監控集群,以及檢查比較實際環境的狀態與代碼庫上的狀態是否一致。所以,我們的目標是描述系統相關的所有內容:策略,代碼,配置,甚至監控事件和版本控制等,並且將這些內容全部存儲在版本庫中,在通過版本庫中的內容構建系統的基礎架構或者應用程序的時候,如果沒有成功,則可以迅速的回滾,並且重新來過。

  • 不應直接使用Kubectl

作為一般規則,不提倡在命令行中直接使用kubectl命令操作執行部署基礎架構或應用程序到集群中。還有一些開發者使用CI工具驅動應用程序的部署,但如果這樣做,可能會給生產環境帶來潛在不可預測的風險。

  • 調用Kubernetes 的API的介面或者控制器應該遵循 Operator 模式

調用Kubernetes 的API的介面或者控制器應該遵循 Operator 模式(什麼是Operator 模式?),集群的狀態和Git庫中的配置文件等要保持一致,並且查看分析它們之間的狀態差異。

最佳實踐

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

Git是每個開發人員工具包的一部分。學習起來感覺自然而且不那麼令人生畏,而且工具本身也非常簡單。 通過使用Git作為應用系統的事實來源,幾乎可以操作所有東西。例如,版本控制,歷史記錄,評審和回滾都是通過Git進行的,而無需使用像kubectl這樣的工具。

所以,Git是GitOps形成的最基礎的內容,就像第一條原則「任何能夠被描述的內容都必須存儲在Git庫中 」描述的那樣:通過使用Git作為存儲聲明性基礎架構和應用程序代碼的存儲倉庫,可以方便地監控集群,以及檢查比較實際環境的狀態與代碼庫上的狀態是否一致。所以,我們的目標是描述系統相關的所有內容:策略,代碼,配置,甚至監控事件和版本控制等,並且將這些內容全部存儲在版本庫中,在通過版本庫中的內容構建系統的基礎架構或者應用程序的時候,如果沒有成功,則可以迅速的回滾,並且重新來過。

拉式流水線——Pull Request操作

推送流水線

目前大多數CI / CD工具都使用基於推送的模型。基於推送的流水線意味著代碼從CI系統開始,通過一系列構建測試等最終生成鏡像,最後手動使用「kubectl」將任何更改推送到Kubernetes集群。

很多開發人員不願意在CI中啟動CD部署流程,或者使用命令行工具操作啟動CD部署流程的原因可能是這樣做會將集群的用戶和密碼等公布出去。雖然可以有措施保護CI / CD 腳本和命令行,但是這些操作畢竟還是在集群外部非可信區工作的。所以,類似做法是不可取的,會給系統安全帶來潛在的風險。

具有集群外讀/寫(R/W)許可權的典型推送流水線:

  • CI運行測試,輸出傳遞到容器映像存儲庫。
  • CD系統自動部署容器(或根據請求,即手動)。

拉式流水線

在GitOps中,鏡像被拉出並且憑證保留在集群中:

Git庫是拉式流水線模式的核心,它存儲應用程序和配置文件集。開發人員將更新的代碼推送到Git代碼庫; CI工具獲取更改並最終構建Docker鏡像。GitOps檢測到有鏡像,從存儲庫中提取新鏡像,然後在Git配置倉庫中更新其YAML。然後,GitOps會檢測到群集已過期,並從配置庫中提取已更改的清單,並將新鏡像部署到群集。

GitOps的流水線

在上節中介紹了GitOps採用拉式模式構建交付流水線,本節將詳細地介紹在構建GitOps流水時需要注意哪些事情,有哪些最佳實踐。

GitOps流水線

這是一個新圖,顯示部署上游的所有內容都圍繞Git庫工作的。在「拉式流水線」中講過,開發人員將更新的代碼推送到Git代碼庫,CI工具獲取更改並最終構建Docker鏡像。GitOps的Config Update檢測到有鏡像,從存儲庫中提取新鏡像,然後在Git配置倉庫中更新其YAML。然後,GitOps的Deploy Operator會檢測到群集已過期,並從配置庫中提取已更改的清單,並將新鏡像部署到群集。

使用群集內部的Deploy Operator,群集憑據不會在生產環境之外公開。一旦將Deploy Operator安裝到集群與Git倉庫建立連接,線上環境中的任何更改都將通過具有完全回滾的Git pull請求以及Git提供的方便審計日誌完成。

自動git→集群同步

由於沒有單一工具可以完成流水線中所需的所有工作,可以從開源生態系統中選擇一組工具,也可以從封閉源中選擇一組工具,或者根據使用情況,甚至可以將它們組合在一起,其實,創建流水線最困難的部分是將所有部件粘合在一起。要實現GitOps,必須要開發出新的組件,用於粘合這些工具,實現拉式交付流水線。

部署和發布自動化是應用落實GitOps,並使交付流水線工作的基礎。GitOps不僅要保證,當開發人員通過Git更新配置文件集的時候,GitOps流水線要自動根據最新的配置文件狀態更新線上環境,而且GitOps還要能夠實時比對Git庫中配置文件集最新的狀態與線上環境最新的狀態保持一致。

在上節中提到了兩個名詞:Config UpdateDeploy Operator,根據GitOps的實踐,Config Update 和 Deploy Operator是需要進行設計開發的,它們是實現GitOps流水線必須的關鍵組件。GitOps賦予了它們神奇的魔法,它們既是自動化容器升級和發布到線上環境的工具,可能也要負責服務、部署、網路策略甚至路由規則等任務。因此,Config UpdateDeploy Operator是映射代碼,服務和運行集群之間所有關係的「粘合劑」。

當然,您可以根據具體的設計,賦予各種其他的功能,但是自動同步是一定需要的,確保如果對存儲庫進行任何更改,這些更改將自動部署到線上環境中

僅部署容器和配置

GitOps建議不直接將應用程序部署到線上環境中,而是將應用程序和相關配置打包成鏡像,並存儲到鏡像庫中,最後,通過鏡像的方式生成容器,並部署到線上環境中。

容器為什麼如此重要?在GitOps模型中,我們使用不可變基礎架構模式。一旦代碼在Git中提交,GitOps就不希望任何其他內容發生變化,這樣可以最大限度地降低系統潛在不確定性、不一致性風險。例如,需要將相同的應用部署到不同的機器上。通常需要系統管理員確保所有的機器都處於相同的狀態。接著所有的修改、補丁、升級需要在所有的機器中進行。隨著時間的推移,很難再確保所有的機器處於相同的狀態,同時越來越容易出錯。然而,容器是比較完美地解決了這個問題,當然,使用虛擬機是可以的,顯然使用容器更加方便。

GitOps的可觀察性

「可觀察性就像生產中的驅動測試一樣。如果你不知道如何確定它是否正常工作,請勿接受 pull request。@mipsytipsy 「 - Adriano Bastos

在GitOps中,使用Git庫來存儲應用系統的配置文集和應用程序,它確保開發人員將所有對於應用系統的配置和程序的新增、修改等都通過Git庫進行版本控制,使Git成為配置和程序的唯一真實來源。而GitOps的可觀察性則是確保線上環境的真實狀態與Git庫中的保持一致性。本章節將給大家介紹GitOps的可觀察性。

可觀察性是另一個真理來源

在GitOps中,我們使用Git作為系統所需狀態的真實來源。例如,如果應用系統宕機,GitOps可以回滾到之前正確狀態。而可觀察性是系統實際運行狀態的真實來源,系統開發人員或者運維人員可以監控系統的狀態。這是一張顯示流程的圖片。

通過觀察需尋找問題的答案

如果大家使用Kubernetes作為雲原生環境和容器編排工具,相信大家會有這樣的感觸,雖然Kubernetes是一個非常棒的編排容器平台,但是隨之而來的缺乏友好的可視化管理界面給開發人員或者運維人員帶來諸多不便。例如:

  • 我的部署成功了嗎?我的系統現在處於工作的狀態,我現在可以回家嗎?
  • 我的系統與以前有什麼不同?我可以使用Git或我們的系統歷史記錄來檢查嗎?
  • 我的改變是否改善了整體用戶體驗?(與系統正確性相對)
  • 我在信息中心找不到我的新服務(例如RED指標)
  • 這個故障是否與我上次的服務更新事件有關,還是和其他操作有關係?

大家可能會想到通過監控伺服器的CPU、內存、網路等,以及應用的日誌,甚至微服務的調用鏈等來解決問題。是的,這個沒有錯,能夠得到一些反饋信息,但是使用過類似監控的開發人員或者運維人員也會感覺,這些監控儀錶盤給我們大量冗繁的信息,需要認真地甄別,而且有很多信息在這些儀錶盤中是獲得不到的。這意味著需要創建新的儀錶盤,用於監控新的指標和內容。

GitOps的可觀察性

可觀察性可被視為Kubernetes 持續交付周期的主要驅動因素之一,因為它描述了在任何給定時間系統的實際運行狀態。觀察運行系統以便理解和控制它。新功能和修復程序被推送到git並觸發部署管道,當準備好發布時,可以實時查看正在運行的集群。此時,開發人員可以根據此反饋返回到管道的開頭,或者將映像部署並釋放到生產集群。

在這裡GitOps引入一個新的工具:Diffs,用來監控對比系統狀態。即:

  • 驗證當前線上系統的狀態是否和Git庫中描述的狀態一致,例如,我上一次發布是否符合期望?
  • 提醒開發人員不一致狀態,以及相應的明細信息。

在文章前面講過,在Git庫中存儲的實際上是「聲明性基礎設施」,例如Kubernetes的YAML文件,用以構建應用系統所需的各種組件、域名、網路等配置信息。Diffs需要讀取Git庫中配置信息,同時,通過API等讀取集群的相應信息,並進行比對。

例如,Kubernetes集群:所需的Kubernetes狀態可能是「有4個redis伺服器」。Diffs定期檢查群集,並在數量從4變化時發出警報。一般而言,Diffs將YAML文件轉換為運行狀態查詢。

GitOps是面向發布的操作模型,請參見下圖。交付速度取決於團隊在此周期中繞過各個階段的速度。

應用交付合規性和安全性

由於以安全的方式跟蹤和記錄更改,因此合規性和審計變得微不足道。使用Diffs等比較工具還可以將Git庫中定義的集群狀態與實際運行的集群進行比較,從而確保更改與實際情況相符。

在Git中記錄所有的操作日誌

通過上面文章的敘述,開發人員或者運維人員通過Git操作系統配置和應用程序的新建和更新等。通過Git客戶端git commit /git merge的所有操作都會Git庫記錄下來,審計員可以查看Git,看看誰做了任何更改,何時以及為何以及如何影響正在運行的系統部署。當然,可以根據自身的需求定製不同的交付合規性。相較於直接進入伺服器操作或者通過Kubctl操作集群,Git記錄了每一個操作步驟,這些可以為合規性和審計提供完整的操作日誌。

角色和許可權控制

幾乎所有的Git庫都提供角色和許可權控制,與開發和運維無關的人員沒有許可權操作Git庫。而不是直接把伺服器或者集群的操作許可權散發出去,這樣特別容易引起安全泄露。

GitOps帶來的好處

更加快速地開發

藉助GitOps的最佳實踐,開發人員可以使用熟悉的Git工具,便捷地將應用程序和其對應的配置文件集持續部署到Kubernetes等雲原生環境,提高業務的敏捷度,快速地相應用戶的需求,有助於增加企業市場的競爭力。

更好地進行運維

藉助GitOps,可以實現一個完整的端到端的交付流水線。不僅可以實現拉式的持續集成流水線和持續部署流水線,而且系統的運維操作可以通過Git來完成。

更強大的安全保證

幾乎所有的Git庫都提供角色和許可權控制,與開發和運維無關的人員沒有許可權操作Git庫。而不是直接把伺服器或者集群的操作許可權散發出去,這樣特別容易引起安全泄露。

更容易合規的審計

由於以安全的方式跟蹤和記錄更改,因此合規性和審計變得微不足道。使用Diffs等比較工具還可以將集群狀態的可信定義與實際運行的集群進行比較,從而確保跟蹤和可審計的更改與實際情況相符。

關於Choerodon豬齒魚

Choerodon豬齒魚是一個開源企業服務平台,是基於Kubernetes的容器編排和管理能力,整合DevOps工具鏈、微服務和移動應用框架,來幫助企業實現敏捷化的應用交付和自動化的運營管理的開源平台,同時提供IoT、支付、數據、智能洞察、企業應用市場等業務組件,致力幫助企業聚焦於業務,加速數字化轉型。

  • choerodon官方網站
  • 論壇
  • Github
  • 文檔
  • 微信公眾號:Choerodon豬齒魚
  • 微博公眾號:Choerodon豬齒魚

推薦閱讀:

航司數字化轉型的重點投放及IT要素 (1)
容器編排之戰-Container Orchestration Wars
航司數字化轉型的重點投放及IT要素 (2)
六、自動化交付平台-標準化建設
2017DevOps採用和趨勢現狀-信息圖

TAG:Kubernetes | DevOps | 敏捷開發 |