前情提要
我想完成什麼 ?
如何用最佳解完成全端應用的開發 ?
- 前端應包含 Web、App(iOS、Android 或簡稱三螢) 與其它
- 後端不限語言、框架(.Net Core、nodejs)
- 測試部署應該自動化(CI/CD)
- 成本應優化
- 應該使用雲原生的技術與 know how
這次我們專注在第 3 點的 CI/CD 上,為了第 1 點,我建置的專案為 flutter
選用的 CI/CD Server 為 Gitlab , 我將會在這裡作較多的著墨,
最終的產出物是 flutter app image, 並推送到 image registry 上 。
如上圖,每個多邊型都應該可以被置換,
- Application 可以被換成 Nodejs/.Net Core/ …
- Gitlab Runner 有三種,本文中會使用 specific runners ,另外有 2 種
- Shared runners(需要信用卡認証身分,每月限制 400 分鐘)
- Group runners (在 Gitlab 上可以)
我將 Gitlab 設定在本機 ( MacBook Pro ) 環境上,下文會講解細節,
也可以置換到雲端的伺服器上,搭配 K8S
ex:- GKE: Google Cloud Platform Kubernetes Engine
- EKS: Amazon Web Services’ Elastic Kubernetes Services
- AKS: Microsoft Azure Kubernetes Service
- Container Registry 這裡我使用最主流的 Docker Hub Registry
以雲原生的三大平台都有對應的功能,如果有機會應該優先選用。
工具準備
首先需要 Gitlab Account ,我們選用 Gitlab 作為 CI/CD Server,
這個階段我們只會作到持續整合,而未部署,相當於只有 CI 的部份。
理論上也可以選用其它的 CI/CD 服務,像是 Azure 或是 GitHub , 這裡就不作過多的展開。
Docker , 簡單說我們的工作只有兩個步驟
- 在 Gitlab 你的專案 > Settings > CI/CD > Runners 註冊 Runner Executors
- 一般來說,我們會選用 docker 或 Kubernetes,本章我會用 docker 為例
- 撰寫 Pipeline 與 Job 腳本,
我們預計執行以下的工作(Pipeline)- Test
- Run Test
- Run Lint
- Build
- Build Application
- Build Image
- Test
開始
註冊 Gitlab Runner
我們要在 docker 建立來執行 gitlab Runner
Create the Docker volume:
1
docker volume create gitlab-runner-config
Start the GitLab Runner container using the volume we just created:
1
2
3
4docker run -d --name gitlab-runner --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v gitlab-runner-config:/etc/gitlab-runner \
gitlab/gitlab-runner:latestRegister Docker Runner
依序輸入 Gitlab URL、gitlab-ci 的 token、runner 說明/名稱、Runner 的 tag、executor、docker image
1
2docker run --rm -it -v gitlab-runner-config:/etc/gitlab-runner \
gitlab/gitlab-runner:latest register- Enter your GitLab instance URL (also known as the gitlab-ci coordinator URL).
- Enter the token you obtained to register the runner.
- Enter a description for the runner. You can change this value later in the GitLab user interface.
- Enter the tags associated with the runner, separated by commas. You can change this value later in the GitLab user interface.
- Provide the runner executor. For most use cases, enter docker.
- If you entered docker as your executor, you’ll be asked for the default image to be used for projects that do not define one in .gitlab-ci.yml.
GitLab instance URL 是 https://gitlab.com/
你可以在專案中的 Settings > CI/CD 找到 token,
description 會顯示在 Runner List 中,可以用易懂的描述,
tags 可以更多的參考這本篇文章設定
executor 選用 docker 記得需要安裝 docker daemon
executor 為 docker 時,需要註明預設的 image,我是選用docker:stable
執行 RUNNER
gitlab-runner run
移除 RUNNER(為了重新安裝)
驗証 runner 狀態是否 alive
gitlab-runner verify –delete
移除 gitlab-runner
gitlab-runner unregister –all-runners
錯誤: 當使用 MacBook M1 當作 RUNNER
在 RUNNER JOB 中執行 flutter pub get 時$ flutter pub get
發生錯誤訊息如下,當我換了一個 intel 晶片的 MacBook 當作 RUNNER 就不會有問題了。
1 | Running "flutter pub get" in rettulf... |
DIND(Docker In Docker)
我們的 Gitlab-Runner 是執行在 Docker 上,
而當我需要 build Docker Images 時,我會在 Container 中建立 docker
這時 Container 所使用的 Image 會是 Docker Image
就被稱為 DIND (Docker In Docker)
在 Gitlab CI 中 Docker Login
參考以下的 .gitlab-ci.yml
1 | before_script: |
異常紀錄與解決方案
$ echo -n $LOGIN_KEY | docker login -u _json_key_base64 –password-stdin https://xxxx-docker.pkg.dev
Error: Cannot perform an interactive login from a non TTY device
主因是讀不到 $LOGIN_KEY
的環境變數,使用 Gitlab-CI 的話要注意 Protect Variable
無法對 docker hub registry
在 RUNNER JOB 中執行 docker push
時
錯誤訊息如下:
dial tcp: lookup docker on x.x.x.x:53: no such host error runner inside docker on armhf
這裡要修改 RUNNER 中的設定檔 config.toml
, 路徑參考如下:
You can find the config.toml file in:
- /etc/gitlab-runner/ on *nix systems when GitLab Runner is executed as root (this is also the path for service configuration)
- ~/.gitlab-runner/ on*nix systems when GitLab Runner is executed as non-root
- ./ on other systems
在 [[runners]] > [runner.docker] 加入 image = docker:stable
或是 privileged = true
這可能不是一個正確的 solution , 可以更多的參考這篇討論
在 DIND 編輯文件
如上題,我們需要在 container 之中編輯文件,
這裡我會使用 vim,
不過安裝前記得先更新 apt-get
不然會出現以下錯誤
E: Unable to locate package vim on Debian jessie simplified Docker container
1 | apt-get update |
GCP Artifact Registry
這裡都以台灣的 region 為範例,
所以都是 ‘asia-east1-docker.pkg.dev‘ 不同的 region 請再參考 GCP 文件
推上去
記得要先登入
docker login -u _json_key_base64 –password-stdin https://asia-east1-docker.pkg.dev
推上去
docker push “asia-east1-docker.pkg.dev/{env_name}/docker/{project_name}:{version_tag}
拉下來
需要先調整 Docker configuration file 取得授權,請參考
gcloud auth configure-docker asia-east1-docker.pkg.dev
再執行
docker pull asia-east1-docker.pkg.dev/{env_name}/docker/{project_name}:{version_tag}
註冊
問題
- gitlab-ci-multi-runner 與 gitlab-runner 的差異為何 ?
- 當 docker gitlab-runner image 的 instance 執行 gitlab-runner run 會產生以下訊息, 這代表什麼意思 ?
Configuration loaded builds=0
listen_address not defined, metrics & debug endpoints disabled builds=0
[session_server].listen_address not defined, session endpoints disabled builds=0
(fin)