
在現在的雲原生世界裡面 GitOps 不斷的被提及,這種持續傳遞的模式越來越受到了大家的青睐,我們前面也有文章詳細講解了 GitOps 的相關概念,在網上也可以找到很多關于它的資源,但是關于 GitOps 相關的工作流實踐的示例卻并不多見,我們這裡就将詳細介紹一個使用示例,希望對大家實踐 GitOps 有所幫助。
GitOps Workflow
上圖是目前示例中的 GitOps 工作流程。GitLab 和 Argo CD 是兩個主要的核心元件:
Argo CD 是一個聲明式、GitOps 持續傳遞的 Kubernetes 工具,它的配置和使用非常簡單,并且自帶一個簡單易用的 Dashboard 頁面,更重要的是 Argo CD 支援 kustomzie、helm、ksonnet 等多種工具。應用程式可以通過 Argo CD 提供的 CRD 資源對象進行配置,可以在指定的目标環境中自動部署所需的應用程式。關于 Argo CD 更多的資訊可以檢視官方文檔了解更多。
GitLab CI 是 GitLab 的持續內建和持續傳遞的工具,也是非常流行的 CI/CD 工具,相比 Jenkins 更加輕量級,更重要的是和 GitLab 天然內建在一起的,是以非常友善。
目前前提條件是有一個可用的 Kubernetes 叢集,通過 kubectl 可以正常通路叢集,為了通路 Argo CD 的 Dashboard 頁面,我們可以通過 Ingress 來暴露服務,為此需要在 Kubernetes 中安裝一個 Ingress Controller,我這裡已經提前安裝了 ingress-nginx,接下來我們将 Helm3 來安裝 Argo CD,關于 Helm 以及 ingress-nginx 的使用我們前面的文章中已經多次提到,這裡就不再詳細介紹他們的使用了。
首先建立一個 argocd 的命名空間:
然後添加 argocd 的 chart 倉庫位址:
接下來我們就可以使用 Helm 安裝 Argo CD 了:
其中 values.yaml 檔案如下所示,用來定制安裝的 Argo CD:
執行上面的安裝指令後,Argo CD 就會被安裝在 argocd 命名空間之下,可以在本地 /etc/hosts 中添加一個映射,将 argocd.k8s.local 映射到 ingress-nginx 所在的節點即可:
當所有 Pod 變成 Running 狀态後,我們就可以通過浏覽器通路 Argo CD 的 Dashboard 頁面了:
預設的使用者名為 admin,密碼為 server Pod 的名稱,可以通過如下所示的指令來擷取:
用上面的使用者名和密碼即可登入成功,接下來我們在 GitLab 中來建立示例項目。
我們這裡使用的示例項目是一個 Golang 程式,在頁面上顯示一個文本資訊和 Pod 名稱,代碼位址:https://github.com/cnych/gitops-webapp-demo。我們可以将該項目代碼上傳到我們自己的 GitLab 上面去,我這裡的 GitLab 安裝在 Kubernetes 之上,通過配置域名 git.k8s.local 進行通路,調整過後我們本地的代碼倉庫位址為:http://git.k8s.local/course/gitops-webapp 。
接下來需要添加一些在 GitLab CI 流水線中用到的環境變量(Settings → CI/CD → Variables):
CI_REGISTRY - 鏡像倉庫位址,值為:https://index.docker.io/v1/
CI_REGISTRY_IMAGE - 鏡像名稱,值為:cnych/gitops-webapp
CI_REGISTRY_USER - Docker Hub 倉庫使用者名,值為 cnych
CI_REGISTRY_PASSWORD - Docker Hub 倉庫密碼
CI_PASSWORD - Git 倉庫通路密碼
CI_USERNAME - Git 倉庫通路使用者名
現在我們可以開始使用 GitOps 來配置我們的 Kubernetes 中的應用了。Argo CD 自帶了一套 CRD 對象,可以用來進行聲明式配置,這當然也是推薦的方式,把我們的基礎設施作為代碼來進行托管,下面是我們為開發和生産兩套環境配置的資源清單:
上面定義的 Application 這個資源,就是 Argo CD 用于描述應用的 CRD 對象:
name:Argo CD 應用程式的名稱
project:應用程式将被配置的項目名稱,這是在 Argo CD 中應用程式的一種組織方式
repoURL:源代碼的倉庫位址
targetRevision:想要使用的 git 分支
path:Kubernetes 資源清單在倉庫中的路徑
destination:Kubernetes 叢集中的目标
然後同樣使用 kubectl 工具直接部署上面的資源對象即可,将會建立兩個 Application 類型的對象:
此時我們再去 Argo CD 的 Dashboard 首頁同樣将會看到兩個 Application 的資訊:
點選其中一個就可以看到關于應用的詳細資訊,我們可以在 gitops-webapp 代碼倉庫的 deployment/<env> 目錄裡面找到資源對象。我們可以看到,在每個檔案夾下面都有一個 kustomization.yaml 檔案,Argo CD 可以識别它,不需要任何其他的設定就可以使用。
由于我們這裡的代碼倉庫是私有的 GitLab,是以我們還需要配置對應的倉庫位址,在頁面上 Settings → Repositories,點選 Connect Repo using HTTPS 按鈕:
添加我們的代碼倉庫認證資訊:
需要注意的是這裡預設使用的是 HTTPS,是以我們需要勾選下方的 Skip server verification,然後點選上方的 CONNECT 按鈕添加即可。然後重新同步上面的兩個 Application,就可以看到正常的狀态了。
接下來我們需要為應用程式建立流水線,自動建構我們的應用程式,推送到鏡像倉庫,然後更新 Kubernetes 的資源清單檔案。
下面的示例并不是一個多麼完美的流水線,但是基本上可以展示整個 GitOps 的工作流。開發人員在自己的分支上開發代碼,他們分支的每一次送出都會觸發一個階段性的建構,當他們将自己的修改和主分支合并時,完整的流水線就被觸發。将建構應用程式,打包成 Docker 鏡像,将鏡推送到 Docker 倉庫,并自動更新 Kubernetes 資源清單,此外,一般情況下将應用部署到生産環境需要手動操作。
GitLab CI 中的流水線預設定義在代碼倉庫根目錄下的 .gitlab-ci.yml 檔案中,在該檔案的最上面定義了一些建構階段和環境變量、鏡像以及一些前置腳本:
接下來是階段的定義和所需的任務聲明。我們這裡的建構過程比較簡單,隻需要在一個 golang 鏡像中執行一個建構指令即可,然後将編譯好的二進制檔案儲存到下一個階段處理,這一個階段适合分支的任何變更:
然後就是建構鏡像并推送到鏡像倉庫,這裡我們使用 Kaniko,當然也可以使用 DinD 模式進行建構,隻是安全性不高,這裡我們可以使用 GIT 送出的 commit 哈希值作為鏡像 tag,關于 Docker 鏡像倉庫的認證和鏡像位址資訊可以通過項目的參數來進行傳遞,不過這個階段隻在主分支發生變化時才會觸發:
下一個階段就是将應用程式部署到開發環境中,在 GitOps 中就意味着需要更新 Kubernetes 的資源清單,這樣 Argo CD 就可以拉取更新的版本來部署應用。這裡我們使用了為項目定義的環境變量,包括使用者名和 TOKEN,此外在送出消息裡面增加 [skip ci] 這樣的關鍵字,這樣流水線就不會被觸發:
最後添加一個部署到 prod 環境的階段,和前面非常類似,隻是添加了一個手動操作的流程:
這樣我們就完成了整個流水線的定義。
接下來我們來看看它們是如何一起工作的。我們将開發和線上兩個環境的應用分别部署在了 dev 和 prod 命名空間之下,通過 Ingress 暴露服務,同樣需要将兩個應用的域名 http://webapp.dev.k8s.local/ 與 http://webapp.prod.k8s.local/ 在本地 /etc/hosts 中添加映射。
如果一切正常的話現在我們可以在浏覽器中來檢視我們部署的 web 應用程式了。
Dev web app
然後我們來嘗試修改下代碼,編輯 main.go 檔案,将變量 welcome 中的 GITOPS 修改為 GITOPS-K8S:
然後送出代碼到 master 分支,然後進入 GitLab 項目 -> CI/CD -> Pipelines,就可以看到一個新的流水線開始建構了。
等待一會兒,正常情況下會執行到 dev 的部署階段,然後變成 skipped 的狀态,此時流水線已經将代碼中的 dev 下的資源清單檔案已經更新了。
GitLab CI/CD Pipeline
然後 Argo CD 在自動同步模式下在一分鐘内變會更新 Kubernetes 的資源對象,我們也可以在 Argo CD 的頁面中看到進度。當 Argo CD 中同步完成後我們再去檢視 DEV 環境的應用,就可以看到頁面上面的資訊已經變成了 GITOPS-K8S 了。
Update Dev Web APP
最後如果需要部署到 prod 環境,我們隻需要在 GitLab 的流水線中手動觸發即可,之後,prod 中的鏡像也會被更新。
GitLab CI/CD Prod deployment
下面是同步時 Argo CD 更新的頁面狀态變化圖。
Argo CD Sync Workflow
到這裡,我們就使用 GitOps 成功的将我們的應用部署到了開發和生産環境之中了。
https://www.weave.works/technologies/gitops/
https://argoproj.github.io/argo-cd/
https://docs.gitlab.com/ee/ci/yaml/
https://medium.com/@andrew.kaczynski/gitops-in-kubernetes-argo-cd-and-gitlab-ci-cd-5828c8eb34d6
https://github.com/cnych/gitops-webapp-demo