DevOps 教學:利用 GitLab、GKE 五步驟達成 CI/CD

DevOps 教學:利用 GitLab、GKE 五步驟達成 CI/CD

DevOps 是什麼? Google 實做 DevOps 的 SRE 方法介紹》中我們提到 DevOps 核心概念是解決開發與維運,甚至是測試部門間的衝突,以提高組織交付應用程式和服務的能力。而本次的 DevOps 教學將介紹如何使用 GitLab 部署 Google Kubernetes Engine(GKE),5 步驟達成 CI/CD!

DevOps 教學前言:CI/CD 是什麼?導入須知

CI/CD 是軟體敏捷式開發中「持續改善」理念的具體作法。其中 CI 指的是持續整合(Continuous Integration),將新版的程式碼自動建置和測試,確保程式碼沒有問題。而 CD 可視團隊狀況定義為持續交付(Continuous Delivery),將程式變更推送到測試環境,確保它是一個隨時可以部署到正式環境的狀態,或持續部署(Continuous Deployment),讓它完全自動部署到正式環境,不用手動部署。此次示範的 CI/CD 導入流程如下。

GitLab CICD deploy DotNetCore to GKE
  1. 建立GitLab Server
  2. 設定環境
  3. 建立一個Gitlab Project
  4. 使用範例 .Net Core 程式碼 Commit 到GitLab
  5. 觸發 CI/CD 流程來建立 Docker Image,存放在 GCR 並且部署到 GKE

本文流程較長,使用工具很多,需要您先有的知識如下:

  1. 對 GCP 有初步了解,會建VM並操作SSH
  2. 對GitLab和Git有初步了解,會Commit程式碼
  3. 對 Kubernetes 了解一點點即可

為什麼要提這麼多呢?因為本實作有非常多坑在裡面,每個坑掉進去要花好幾個小時才能爬出來,我盡可能把陷阱都提示給您了,但實在太多太瑣碎所以不會 step-by-step來詳細說明,希望您不會踩到!

Gitlab 安裝方式可以參考這篇文章:https://docs.gitlab.com/ee/install/google_cloud_platform/

DevOps 教學步驟一:建立 GitLab Server

首先建立一台機器,如果只是測試不用開太大:

建立一台機器 GCP VM

指定作業系統為 Ubuntu 18.04 LTS,Disk 大小建議最少30GB以上,下圖10GB是自己當初沒想到,給自己埋的雷……(你看到後面就知道了)

使用Ubuntu 18.04做為GitLab VM

防火牆看您有沒有憑證,如果沒有只要開放HTTP就好:

防火牆開放 HTTP(s)

等機器建好會拿到一個IP,強烈建議您使用固定IP,本人不在知情的狀況下使用臨時IP,埋了第二個雷……

DevOps 教學步驟二:安裝 GitLab

現在我們直接從GCP的SSH按鈕連進去這台主機,直接看這文件安裝就對了: https://about.gitlab.com/install/#ubuntu

先裝一些相依性的東西:

sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates tzdata

接下來裝 postfix

sudo apt-get install -y postfix

它會引導到另一個畫面,詢問郵件設定的問題:

我選擇 Internet Site。

設定GitLab的Postfix

這裡是確認主機名稱,如果您是在GCP建的,它應該會自己帶資料出來,按OK即可。

確認VM的主機名稱

終於要開始裝GitLab了。用以下指令下載 Gitlab:

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash

下載 GitLab安裝檔

接下來文件上是這樣寫的,記得你要改成你的domain或是IP位址:

sudo EXTERNAL_URL=”https://gitlab.example.com” apt-get install gitlab-ee

像我就是輸入這樣:

sudo EXTERNAL_URL=”http://35.185.135.182” apt-get install gitlab-ee

不用想入侵我的主機,該IP已不存在~嘿嘿~

接下來看它表演,我是說它會開始執行安裝流程:

安裝 GitLab

大概5分鐘之後會看到歡迎畫面:

GitLab安裝成功

接著點擊 VM 的 IP, 用 HTTP 就好。

有耶,開心!!

看到 GitLab 歡迎畫面

相關環境設定,照一般流程註冊自己的帳號:

註冊GitLab帳號

因為GitLab 會Build 一個 Docker Image,存在 Cloud Storage,之後也要拉 Image出來,並且部署到 Google Kubernetes Engine,需要兩個權限:

  1. Storage Admin
  2. Kubernetes Enginer Developer

所以我們必需要建立一個Service Account:

建立 Service Account for GitLab

賦予權限:

授權 Service Account 讓 GitLab 存取 GCR 並部署 GKE

不需要增加其他權限,直接按 Done:

不需授予其他權限

另外也要給它一個 key

下載 service account key

把key用Json格式下載下來:

下載 service account key 用來跑 CI/CD

檔名取為:

重新命名 service account key

接下來要設定 CI/CD 環境變數,我們先回到GitLab主畫面,建立第一個 GitLab 專案:

建立第一個 GitLab 專案

命名,並且把專案設定為 Private,按下Create Project:
(後面我的Project Name有更改,因為反覆練了很多次)

GitLab 專案命名

它會說你現在不能 Push 程式碼,因為你還沒有 SSH Key

你現在不能 Push 程式碼,因為你還沒有 SSH Key

那我們就回到本機 (等等寫程式要Push Code的那台電腦),像我是Mac電腦的話,就輸入以下指令:

cd .ssh #去放有 ssh key的.ssh目錄 (在這裡我假設你已經有了)
cat id_rsa.pub #查看ssh key 的內容

查看ssh key 的內容

然後複製從 “ssh-rsa”一直到你的 “email@xxx.com” 為止,貼到GitLab專案的 User Setting => SSH Keys

複製從 ssh key 貼到GitLab

接下來回到首頁,可以看到第一次push code的教學:

首頁可以看到第一次push code的教學

在本機照著做看看,設定使用者:

在本機設定GitLab使用者

把專案拉下來

把專案從GitLab拉下來

這裡要補充一下,為了安全,我有設GCP的防火牆只允許公司的IP去連,所以就不能直接點 GCP Console 的SSH,而是要從我本機電腦去SSH,所以我要把SSH Key放在VM上。

把本機電腦的SSH Key放在VM上

接下來就用基本指令來 push 看看:

Push 成功

確認 code push上去之後,回到GitLab頁面重新整理,看到 README.md 出現了。

確認 Push GitLab 結果

太棒了,到此 GitLab的環境設定完成。

DevOps 教學步驟三:CI/CD 環境設定

接下來就是重頭戲了,CI/CD環境設定,我們先到 Project 的Setting=>CI/CD頁面,新增一些環境變數,因為我們要做自動化,所以為了讓它真正做到全自動,就必須把環境變數設定好,不要嫌麻煩,這是一次工,之後就很輕鬆了。

設定CI/CD環境

首先是 GCP_SERVICE_KEY,相關的選項照以下的方式設定:

注意:Protect variable 要取消,不要打勾!!後面有洞!

Protect variable 要取消,不要打勾

GCP_PROJECT

GCP_PROJECT

GCP_ZONE

GCP_ZONE

GCP_CLUSTER_NAME

GCP_CLUSTER_NAME

我們先把 GKE Cluster的名字預先想好,設為環境變數。當然你要先建也沒問題。

gcloud container clusters create cluster-1 –num-nodes 2 –machine-type n1-standard-1 –zone asia-east1-a

建立GKE Cluster

如果您只是要測試,就不用先急著先建 Cluster,怕你浪費錢~

GCP_GCR

GCP_GCR

最後是這樣

設定5個環境變數

做 docker build的設定檔 .gitlab-ci.yml (注意這是第一版)

做 docker build的設定檔 .gitlab-ci.yml

注意:環境變數還要要補上這兩行,以免 Runner 出錯 (坑出現了,後面會解釋)

環境變數還要要補上這兩行,以免 Runner 出錯

另外您的 service account key 要放在家目錄,您的Mac電腦本身的家目錄

而且要改名為 service_account.json

接下來把 asp.Net的範例程式碼抓下來,來源網址為:https://github.com/dotnet/dotnet-docker/tree/main/samples/aspnetapp

因為等等要 Push Code之後會觸發 CI/CD 流程,就先做到這裡,我們還有另一個重要的東西要做。

DevOps 教學步驟四:註冊 GitLab Runner

在GitLab的說明上會教你如何安裝並註冊Runner,我後來依照指引到這個網址來安裝 Ubuntu 的 Runner:

https://docs.gitlab.com/runner/install/linux-repository.html

我先登入到 GitLab 這台 VM,使用以下指令:

https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash

下載Runner

下載完執行安裝指令:

sudo apt-get install gitlab-runner

GitLab Runner 安裝之後,還需要向 GitLab Server 完成註冊,才算是真正的架設完畢。註冊的方式即是執行下面的 Command:

sudo gitlab-runner register

接下來回有一連串的問答

註冊GitLab Runner

接下來是 Enter the registration token ,這個 token 會在 GitLab project的 setting => CI/CD頁面會看得到。

然後名字就任意輸入即可:

輸入 Runner 描述

過程中我有碰到網路問題讓我註冊失敗,後來發現是GitLab要允許它自己的IP連線,所以我後來去改了防火牆規則:

更改防火牆規則讓Runner註冊成功

整個註冊過程如下,還包括一些額外的問題:

回答Runner註冊相關問題

注意:如果你中間有重開機的話,Token 會重新產生,所以要用新的Token重新註冊一次喔!(坑又來了)

Runner註冊完成

整個註冊過程也可以用指令一口氣先寫好如下(後面註解要拿掉喔):

sudo gitlab-runner register -n \ 
  –url http://你的VM的IP或網址/ \
  –registration-token “FR7pk-GQwBavt7zysFYs” \ 注意token重開機會換掉,要重新註冊
  –executor docker \
  –description “you can write anything” \
  –docker-image “docker:19.03.12” \ 用這個版本比較好
  –docker-privilege true 有指定這個,就不用改 config.toml 的 value 為 true (後面再說明)

DevOps 教學步驟五:Push Code 以觸發 CI/CD 流程

環境已經設定得「差不多了」,真的是差不多而已,開始Run會發現還差很多。

一跑馬上錯,它說沒有 Runner ,但我明明剛剛才註冊好怎麼可能沒有?

GitLab 說沒有 Runner

後來發現是沒有裝 Docker,原來最基本的Docker都還沒裝~

可參考這個網址,回到GitLab的SSH,一直複製貼上就對了:

https://docs.docker.com/engine/install/ubuntu/

接下來就再跑一次,然後又看到另一個錯誤~

它連到我舊的IP (已經釋放掉了),所以一直出錯:

GitLab 因為連到舊的IP而出錯

為什麼會這樣呢?因為我當初建VM的時候,使用的是 Ephermeral (臨時) 的IP,每次重開機它都會換一個新的IP,而我在做初始化設定時,GitLab會記錄那個IP到它的設定檔裡面,但我每次重開機換新IP的時候,GitLab並不知道,這算是一個大坑啊!!

好家在,後來找到這篇文章可以解決:

https://docs.bitnami.com/aws/apps/gitlab/configuration/change-default-address/

要去 vim /etc/gitlab/gitlab.rb

找到 external_url “https://gitlab.example.com”

改成

更改gitlab.rb的IP

然後輸入 sudo gitlab-ctl reconfigure 讓它重新跑一次設定:

輸入 sudo gitlab-ctl reconfigure 重新設定GitLab IP

大概跑了2分鐘

GitLab IP更新完成

GitLab網頁會出錯,不用擔心,它需要整個重啟,等它開好:

等待 GitLab 重啟完成

等它重啟完成,我們再按一次 Retry 的按鈕:

Retry GitLab Job

又看到另一個錯誤:

GitLab Job 因為版本問題產生的Error

這個前面有提過,它是和Docker版本的問題有關,要回去改 .gitlab-ci.yaml

加這2行:

.gitlab-ci.yaml 修改內容

然後再push上去

Push .gitlab-ci.yaml 到GitLab

另外還有一個地方,

/etc/gitlab-runner/config.toml 要把 runner 的 privileged 改成 true

你也可以在註冊 runner 時指定   –docker-privilege true (前面有提過)

還有環境變數要取消 Protect Variable 的勾勾,不然還是會出錯喔!

環境變數要取消 Protect Variable 的勾勾

後來再 retry ,有看到錯誤,但它的狀態還是在 running,此時不要緊張,等它全部跑完……

GitLab的狀態還是在 running,此時不要緊張,等它全部跑完

因為目前VM只有1core,大概等了半個小時

有上GCR耶??好感動

GitLab成功建完Docker Image放上GCR

但我的cluster其實還沒建,所以它只做好 build 好image,還沒deploy到GKE,這是正常的。

GitLab只做好 build 好image,還沒deploy到GKE

你想想看,前面錯誤一堆,都花時間在troubleshooting,根本都用不到GKE,如果當時就開好Cluster,看看現在帳單多少錢??(這叫做錢坑)

現在可以建Cluster了。

gcloud container clusters create cluster-1 –machine-type n1-standard-1 –num-nodes 2 –zone asia-east1-b

然後啊……

GitLab因為Disk空間不足所產生的Error

所以我才說VM在建的時候,Disk調大一點,後來我改成30GB。

你可以在不關機器的情況下加大喔!

你可以在不關機器的情況下加大Disk

但你還是要在機器裡面做 resize才算(其實步驟很多),參考這個: https://cloud.google.com/compute/docs/disks/add-persistent-disk#resize_partitions

我順便把GitLabe調成 n1-standard2 (2core 7.5GB),不然每次跑好久最後才看到錯誤,太浪費時間了!對了,重開機要再重新註冊Runner喔!

好了,再retry一次吧!

它的頁面refresh很慢,不要急。

重新Retry CD流程

看到這個,好感動!!

CD流程部署GKE成功

真的部署好了,太感動了!(看我多激動)

GKE部署成功,看到 .Net Core歡迎畫面

這裡我總結一下五大巨坑:

  • 建GitLab要用固定IP,否則每次重開機又換新IP。
  • 每次建新GitLab專案要重新設定環境變數和Runner。
  • 每次重開機都要重新註冊Runner,參數要跟著調整。
  • 要確保Disk夠大,避免事後調整浪費時間。
  • GKE Cluster等到 Image 部署到GCR再建就好,不用晾在那邊累積帳單。

詳細的設定檔可以來這裡:

https://gitlab.com/kevin354/gitlab-iis-k8s-deploy-sample

發佈留言