天天看點

基于 Gitlab CI 和 Kubernetes 的 CI/CD

上節課我們将 Gitlab CI Runner 安裝到了 Kubernetes 叢集中,接下來看看如何結合 Kubernetes 和 Gitlab CI 進行持續內建和持續部署。

首先将本節所用到的代碼庫從 Github 上獲得:cnych/gitlab-ci-k8s-demo,可以在 Gitlab 上建立一個項目導入該倉庫,當然也可以建立一個空白的倉庫,然後将 Github 上面的項目 Clone 到本地後,更改遠端倉庫位址即可:

當我們把倉庫推送到 Gitlab 以後,應該可以看到 Gitlab CI 開始執行建構任務了:

基于 Gitlab CI 和 Kubernetes 的 CI/CD

此時 Runner Pod 所在的 namespace 下面也會出現兩個新的 Pod:

這兩個新的 Pod 就是用來執行具體的 Job 任務的,這裡同時出現兩個證明第一步是并行執行的兩個任務,從上面的 Pipeline 中也可以看到是 test 和 test2 這兩個 Job。我們可以看到在執行 image_build 任務的時候出現了錯誤:

基于 Gitlab CI 和 Kubernetes 的 CI/CD

我們可以點選檢視這個 Job 失敗詳細資訊:

出現上面的錯誤是因為我們并沒有在 Gitlab 中開啟 Container Registry,是以環境變量中并沒有這些值,還記得前面章節中我們安裝的 Harbor嗎?我們這裡使用 Harbor 來作為我們的鏡像倉庫,這裡我們隻需要把 Harbor 相關的配置以參數的形式配置到環境中就可以了。

定位到項目 -> 設定 -> CI/CD,展開 Environmentvariables欄目,配置鏡像倉庫相關的參數值:

基于 Gitlab CI 和 Kubernetes 的 CI/CD

配置上後,我們在上面失敗的 Job 任務上點選“重試”,在重試過後依然可以看到會出現下面的錯誤資訊:

從錯誤資訊可以看出這是因為登入私有鏡像倉庫的時候證書驗證錯誤,因為我們根本就沒有提供任何證書,是以肯定會失敗的,還記得我們之前在介紹 Harbor 的時候的解決方法嗎?第一種是在 Docker 的啟動參數中添加上 insecure-registries,另外一種是在目錄 /etc/docker/certs.d/下面添加上私有倉庫的 CA 證書,同樣,我們隻需要在 dind 中添加 insecure 的參數即可:

然後儲存 .gitlab-ci.yml檔案,重新送出到代碼倉庫,可以看到又觸發了正常的流水線建構了,在最後的階段 deploy_review仍然可以看到失敗了,這是因為在最後的部署階段我們使用 kubectl工具操作叢集的時候并沒有關聯上任何叢集。

我們在 Gitlab CI 中部署階段使用到的鏡像是 cnych/kubectl,該鏡像的 Dockerfile檔案可以在倉庫 cnych/docker-kubectl 中擷取:

我們知道 kubectl在使用的時候預設會讀取目前使用者目錄下面的 ~/.kube/config檔案來連結叢集,當然我們可以把連接配接叢集的資訊直接内置到上面的這個鏡像中去,這樣就可以直接操作叢集了,但是也有一個不好的地方就是不友善操作,假如要切換一個叢集還得重新制作一個鏡像。是以一般我們這裡直接在 Gitlab 上配置內建 Kubernetes 叢集。

在項目頁面點選 AddKubernetesCluster -> Addexisting cluster:

1.Kubernetes cluster name 可以随便填

2.API URL 是你的叢集的 apiserver的位址, 一般可以通過輸入 kubectl cluster-info擷取,Kubernetes master 位址就是需要的

3.CA憑證、Token、項目命名空間

對于我們這個項目準備部署在一個名為 gitlab的 namespace 下面,是以首先我們需要到目标叢集中建立一個 namespace:

由于我們在部署階段需要去建立、删除一些資源對象,是以我們也需要對象的 RBAC 權限,這裡為了簡單,我們直接建立一個 ServiceAccount,綁定上一個 cluster-admin的權限:(gitlab-sa.yaml)

然後建立上面的 ServiceAccount 對象:

可以通過上面建立的 ServiceAccount 擷取 CA 證書和 Token:

填寫上面對應的值添加叢集:

基于 Gitlab CI 和 Kubernetes 的 CI/CD

現在 Gitlab CI 的環境都準備好了,我們可以來看下用于描述 Gitlab CI 的 .gitlab-ci.yml檔案。

一個 Job 在 .gitlab-ci.yml檔案中一般如下定義:

上面這個 Job 會在 test 這個 Stage 階段運作。

為了指定運作的 Stage 階段,可以在 .gitlab-ci.yml檔案中放置任意一個簡單的清單:

你可以指定用于在全局或者每個作業上執行指令的鏡像:

在我們目前的項目中定義了 4 個建構階段:test、build、release、review、deploy,完整的 .gitlab-ci.yml檔案如下:

上面的 .gitlab-ci.yml檔案中還有一些特殊的屬性,如限制運作的的 when和 only參數,例如 only:["tags"]表示隻為建立的标簽運作,更多的資訊,我可以通過檢視 Gitlab CI YAML 檔案檢視:https://docs.gitlab.com/ce/ci/yaml/README.html

由于我們在 .gitlab-ci.yml檔案中将應用的鏡像建構完成後推送到了我們的私有倉庫,而 Kubernetes 資源清單檔案中使用的私有鏡像,是以我們需要配置一個 imagePullSecret,否則在 Kubernetes 叢集中是無法拉取我們的私有鏡像的:(替換下面相關資訊為自己的)

在下面的 Deployment 的資源清單檔案中會使用到建立的 myregistry。

接下來為應用建立 Kubernetes 資源清單檔案,添加到代碼倉庫中。首先建立 Deployment 資源:(deployment.yaml)

這是一個基本的 Deployment 資源清單的描述,像 CI_ENVIRONMENT_SLUG和 VERSION這樣的占位符用于區分不同的環境, CI_ENVIRONMENT_SLUG将由 dev 或 live(環境名稱)和 VERSION替換為鏡像标簽。

為了能夠連接配接到部署的 Pod,還需要 Service。對應的 Service 資源清單如下(service.yaml):

我們的應用程式運作8000端口上,端口名為 http-metrics,如果你還記得前面我們監控的課程中應該還記得我們使用 prometheus-operator為 Prometheus 建立了 自動發現的配置,是以我們在 annotations裡面配置上上面的這幾個注釋後,Prometheus 就可以自動擷取我們應用的監控名額資料了。

現在 Service 建立成功了,但是外部使用者還不能通路到我們的應用,當然我們可以把 Service 設定成 NodePort 類型,另外一個常見的方式當然就是使用 Ingress 了,我們可以通過 Ingress 來将應用暴露給外面使用者使用,對應的資源清單檔案如下:(ingress.yaml)

當然如果想配置 https 通路的話我們可以自己用 CA 證書建立一個 tls 密鑰,也可以使用 cert-manager來自動為我們的應用程式添加 https。

當然要通過上面的域名進行通路,還需要進行 DNS 解析的, CI_ENVIRONMENT_SLUG-gitlab-k8s-demo.qikqiak.com其中 CI_ENVIRONMENT_SLUG值為 live 或 dev,是以需要建立 dev-gitlab-k8s-demo.qikqiak.com 和 live-gitlab-k8s-demo.qikqiak.com 兩個域名的解析。

我們可以使用 DNS 解析服務商的 API 來自動建立域名解析,也可以使用 Kubernetes incubator 孵化的項目 external-dns operator 來進行操作。

所需要的資源清單和 .gitlab-ci.yml檔案已經準備好了,我們可以小小的添加一個檔案去觸發下 Gitlab CI 建構:

現在回到 Gitlab 中可以看到我們的項目觸發了一個新的 Pipeline 的建構:

基于 Gitlab CI 和 Kubernetes 的 CI/CD

可以檢視最後一個階段(stage)是否正确,如果通過了,證明我們已經成功将應用程式部署到 Kubernetes 叢集中了,一個成功的 review階段如下所示:

基于 Gitlab CI 和 Kubernetes 的 CI/CD

整個 Pipeline 建構成功後,我們可以在項目的環境菜單下面看到多了一個環境:

基于 Gitlab CI 和 Kubernetes 的 CI/CD

如果我們點選 終止,就會調用 .gitlab-ci.yml中定義的鈎子 on_stop:stop_review,點選 Viewdeployment就可以看到這次我們的部署結果(前提是DNS解析已經完成):

這就是關于 Gitlab CI 結合 Kubernetes 進行 CI/CD 的過程,具體詳細的建構任務還需要結合我們自己的應用實際情況而定。下節課給大家介紹使用 Jenkins + Gitlab + Harbor + Helm + Kubernetes 來實作一個完整的 CI/CD 流水線作業。

參考連結:https://edenmal.moe/post/2017/Kubernetes-WYNTK-GitLab-CI-Kubernetes-Presentation/

掃描下面的二維碼(或微信搜尋 k8s技術圈)關注我們的微信公衆帳号,在微信公衆帳号中回複 加群 即可加入到我們的 kubernetes 讨論群裡面共同學習

基于 Gitlab CI 和 Kubernetes 的 CI/CD