如何優雅的使用 GitOps 實現運維自動化
什么是 GitOps 呢?
- GitOps 是一套使用 Git 來管理基礎架構和應用配置的實踐,而 Git 指的是一個開源版控制系統。GitOps 在運行過程中以 Git 為聲明性基礎架構和應用的單一事實來源。
- GitOps 使用 Git 拉取請求來自動管理基礎架構的配置和部署。Git 存儲庫包含系統的全部狀態,因此系統狀態的修改痕跡既可查看也可審計。
- GitOps 圍繞開發者經驗而構建,可幫助團隊使用與軟件開發相同的工具和流程來管理基礎架構。除了 Git 以外,GitOps 還支持您按照自己的需求選擇工具。
1. GitOps 到底是個什么呢
GitOps = 基礎設施即代碼(IaC) + 合并請求(MR) + 持續集成/持續交付(CI/CD)
GitOps 是一種運維框架,它采用了 DevOps 在應用程序開發階段的最佳實踐(例如版本控制、協作、合規性和CI/CD工具),并將其應用于基礎設施自動化。
與 GitOps 相比,傳統的 DevOps 盡管在軟件開發生命周期已實現自動化,但基礎架構大體上仍然是一個需要專業團隊進行手動操作的過程。隨著對基礎架構需求的不斷增長,實現基礎設施自動化變得越來越重要。現代化的基礎設施需要彈性機制(速度和規模),以便能有效地管理持續部署所需的云資源。
GitOps體系學習和理解
GitOps 用于對基礎設施置備的過程進行自動化,采用以 配置文件 存儲為代碼(基礎設施即代碼),配置文件在每次部署時都會生成相同的基礎設施環境,來保證環境的一致性,完成整個運維流程的自動化。
- 三叉戟 - 基礎設施即代碼(IaC) - Terraform
- GitOps 使用 Git 倉庫作為基礎設施定義的單一可信來源,將所有基礎設施以配置文件的方式存儲起來,達到配置和管理應用服務的問題。
- 三叉戟 - 合并請求(MR)
- GitOps 使用合并請求作為所有基礎設施更新的變更機制,合并請求是團隊通過評審和評論進行協作的地方,合并會被提交到您的主干分支并可作為審計日志。
- 三叉戟 - 持續集成/持續交付(CI/CD)
- GitOps 使用具有持續集成和持續交付的 Git 工作流來自動化執行基礎架構的更新,在新代碼合并后,CI/CD 流水線將執行環境中的更改,從而避免手動配置的錯誤等問題。
對于任何需要協作的工作,改變都是很棘手的,GitOps 也不例外。GitOps 需要所有參與者遵守紀律,它是一種采用全新的方式來工作的承諾。對于團隊來說,把所有的事情都記錄下來至關重要。
2. GitOps 的核心在于協助
可以覆蓋應用程序從構思到代碼再到部署全流程的協作
從核心上來說,GitOps 指的是將 Git 存儲庫作為構建基礎設施和部署應用程序所有代碼的唯一可信數據源,然后將代碼自動化部署到不同的云環境上面(可以借助Terraform完成資源編排)。
每個人都能夠在同一個系統中工作,并了解事情的進展情況。無論你是在基礎架構中還是在應用程序開發中,所有的更改都遵循同樣的流程,即定義工作主體,將其分配給個人,團隊協作,然后部署這些代碼,并將 Git 存儲庫作為唯一可信數據源使用。
- GitOps 與代碼和協作都有緊密聯系
- 使用版本控制系統可以確保一切都被記錄且可見,審計跟蹤使團隊保持合規性。
- 針對于不同的項目和團隊,新建 issue 來描述添加的目標和任務(多云平臺)。
- 在 issue 中,記錄列出的任務列表的執行程度和進展(通過ME合并請求)。
GitOps體系學習和理解
3. GitOps 的使用優秀實踐
良好的運維體系擁有一個無縫鏈接且完美的體驗,能夠增進基礎設施、運營和開發團隊之間的協作,在提高軟件環境的穩定性、可靠性和安全性的同時,實現更快速部署,這能夠增強團隊的信心。比如:
GitOps體系學習和理解
- [1] 版本控制
- 核心 - 配置文件 - 聲明式系統
- Git 倉庫作為所有基礎設施和應用部署代碼的單一事實來源
- 通過受保護分支的獨特權限,限制可以部署到生產的用戶和團隊
- [2] 代碼審查
- 團隊 - 方便后續追溯問題原因
- 提高代碼質量,傳播最佳實踐,防止問題的出現
- [3] 持續集成/持續交付
- 部署 - 無縫體驗 - 與 Terraform 緊密集成
- 將其與敏捷管理和源代碼管理建立在同一個應用程序中
- 支持從物理機、虛擬機、容器到云原生平臺的多種基礎環境的部署
4. GitOps 的大致運行流程
伴隨著 DevOps 在近些年的火爆,圍繞 xOps 產生了很多概念,諸如 DevSecOps,AIOps,MLOps,ChatOps 等等,當然還有的主角 GitOps。而GitOps 這個詞出現于 2017 年,是由 Weaveworks 公司根據多年云計算基礎設施和應用程序管理經驗而提出的一個概念。
GitOps體系學習和理解 - 亂七八糟的xOps造詞運動
一般情況下,可以使用下面的持續交付系統(示意圖),來完成云原生應用程序的部署與交付。這種 從左到右走到底 的 Push 模式,雖然很容易實現一鍵式部署,但也存在一些問題。
GitOps體系學習和理解 - 完成云原生應用程序的部署與交付
簡而言之,就是沒有辦法保證兩側的服務是一致的,這可能會導致 配置漂移 的發生和安全合規問題的出現,而使用聲明式是解決這個問題的關鍵點。
- [1] 很難保證
- 倉庫里清單文件的內容是否和 k8s 集群的實際情況是否一致
- [2] 不夠靈活
- 鏡像有更新時不能夠自動同步至集群,除非每次從頭到尾走一遍部署流程
- [3] 安全合規
- 有可能需要操作人員通過 kubectl 命令做一些集群操作
聲明式系統有個特點,其能夠幫我們自動完成應用程序或基礎設施系統的描述狀態和實際狀態的自動同步,保證兩者能保持一致。比如,應用部署清單里面應用程序是一個副本(replicas=1),那么集群側應用程序就會是一個 pod。
GitOps體系學習和理解 - 關于聲明式的理解以及解題思路
而 GitOps 以聲明式系統為基座,以 Git 為單一可信源,即一切皆代碼,從而我們可以將上述構建流程改為下面這樣的 pull 模式。pull 模式的關鍵就是,單一可信源與 k8s 集群的集成,當可信源側的文件清單發生變更的時候,集群側能夠及時捕捉到此變更,從而完成變更清單的部署。
- 這就需要使用的 Git 工具支持與 k8s 打交道的能力。
- 可以將 Git 工具與 Terraform 集成,來完成云基礎設施的自動化管理。
GitOps體系學習和理解 - 關于聲明式的理解以及解題思路。
GitOps體系學習和理解 - 關于聲明式的理解以及解題思路
- # ------- 0.0 -------
- # GitOps的倉庫代碼結構
- # -------------------
- # 多云環境
- ➜ tree -a GitOps
- GitOps
- └── gitops
- ├── .gitlab-ci.yaml # CI/CD
- └── environments
- ├── aliyun
- │ ├── kubeconfig.yaml # k8s集群配置
- │ ├── main.tf # 基礎設置配置
- │ └── yaml
- │ └── app.yaml # 集群服務配置
- └── k3s
- └── yaml
- ├── app.yaml # 集群服務配置
- └── kubeconfig.yaml # k8s集群配置
以 Git 為單一可信源,所有與軟件開發相關流程中的代碼(包括基礎設施代碼、應用程序源碼、配置等)都會存儲在 Git 倉庫中。所有管理過程都是通過合并請求(MR)來完成的,當需要對基礎設施作某些變更時,只需要修改代碼,并提交 MR,在所有的修改都被審查和批準后,代碼可以被合并到主分支上。一旦代碼變化被合并,所有的變化將被部署到生產中。
- GitOps 的優點
- 快速進行變更 - 更新和回滾
- 人員工作體驗的提升 - 部署流程完美
- 安全性提高 - 倉庫進行權限分配
- 合規審計容易做 - 所見即所得
- GitOps 的缺點
- 協作文化的建立 - 逐步培養
- Git Workflow的建立 - 混合云保證服務可用
- 敏感信息的處理 - 敏感信息(與Vault結合解決) - GitSecOps
5. GitOps 集成 ArgoCD 實踐
ArgoCD 只是一個持續交付工具,但其實核心功能點!
ArgoCD 是一款開源且主要針對 Kubernetes 來做 GitOps 的持續交付工具。現在是 CNCF 的孵化項目。其整體架構圖如下:
GitOps體系學習和理解 - 集成ArgoCD實踐
ArgoCD 是以 Kubernetes Controller 的形式來實現的,它會對運行在 Kubernetes 集群上的應用程序進行監聽,并將實際運行狀態和期望狀態(在部署清單文件中指定,且存儲在版本控制系統中)進行對比,當兩者狀態不一致的時候,則提示 OutOfSync,此時可以通過自動或者手動的方式來完成同步操作,以讓兩者狀態再次保持一致。存儲在 Git 倉庫中的任何變更都會被自動同步至集群側。
這其實就是實現 GitOps 的核心原理。所有對于應用程序或者基礎設施的變更僅僅需對 Git 倉庫做一些 MR 或者 Push 操作即可實現,變更會自動部署。所以,雖然 GitOps 的核心不是 Git,但是卻與 Git 息息相關。
Git 將作為存儲部署清單文件的版本控制系統,與 ArgoCD 做集成,實現 GitOps workflow。整體示意圖如下所示:
- 一個 Git 實例
- 一個 ArgoCD 運行實例
GitOps體系學習和理解 - 集成ArgoCD實踐
- [1] 安裝和啟動 ArgoCD 服務
- # 安裝ArgoCD服務(官方)
- # 使用Kustomize來完成對部署清單文件的編排
- # 同時用sops來處理敏感信息在Git上的存儲問題
- $ kubectl create namespace argocd
- $ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
- # 暴露argocd的服務端口
- $ kubectl -n argocd port-forward pods/argocd-server-6db46c865b-qqnbl 8080:8080
- # 獲取登陸密碼
- $ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
- RDMpJRKRfsmkcgbP
- # 訪問ArgoCD服務
- http://localhost:8080
- admin/RDMpJRKRfsmkcgbP
- [2] 介紹 sops 的使用
- # 這sops是一款開源的加密文件的編輯器(以GPG為例演示)
- # 支持YAML、JSON、ENV、INI和BINARY格式,且支持多種加密方式
- # 安裝
- $ brew install gnupg
- $ brew install sops
- # 生成一對key
- $ gpg --full-generate-key
- # sops和gpg的結合 - 創建sops配置文件
- # encrypted_regex: 加密規則;規定需要對哪些字段的值進行加密
- # gpg: 加密所需要的fingerprint值
- $ cat >> .sops.yaml << EOF
- creation_rules:
- - encrypted_regex: '^(username|title|)$'
- pgp: 'ED2A6947C44F9228B39E65B705A11CD02E66FF4B'
- EOF
- # sops和gpg的結合 - 創建敏感信息的文件
- $ cat >> secret.yaml << EOF
- apiVersion: v1
- data:
- username: eGlhb21hZ2UK=
- company: SmlIdShHaXRMYWIp=
- kind: Secret
- metadata:
- labels:
- app: demo
- name: sops-demo
- namespace: jihu-gitlab
- type: Opaque
- EOF
- # sops和gpg的結合 - 敏感信息的文件加密
- $ sops -e secret.yaml
- [3] 配置 ArgoCD 的服務
GitOps體系學習和理解 - 配置ArgoCD的服務
- [4] 使用 ArgoCD 的服務
- # 在ArgoCD的Project下面添加application來讓GitOps飛起來
- # 至此ArgoCD配置完成,且此ArgoCD實例已經在監聽配置的Git的倉庫
- # 如果該倉庫的配置文件發生了變化,則變化會被自動同步至Kubernetes集群側
- # 查看運行的應用程序
- $ kubectl -n gitops-argocd get pods
- NAME READY STATUS RESTARTS AGE
- deploy-766c4cbbfc-m8dz6 1/1 Running 0 53m
- # 查看此應用程序的輸出 - 映射端口出來
- $ kubectl -n gitops-argocd port-forward pods/deploy-766c4cbbfc-m8dz6 9999:9999
- $ curl localhost:9999/jihu
- Hello JiHu GitLab,this is xiaomage,version is v6.1.0