iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
DevOps

DevOps 好想學!新手也能打造雲端 Study Lab系列 第 18

Day18 - GitLab CI 自動建置 Docker Image

前言

上回說到 CI/CD 的第一步會是 Build ,今天就來實際了解如何建置 Build Stage。

Build 相關配置

要如何使用專案裡的 Dockerfile 自動建置 Image,需要先了解 GitLab CI 裡的 Job 是如何運行的,在.gitlab-ci.yml中定義 Job 的格式如下

job-name:
  stage: stage-name
  script:
    - echo "script"

對流水線中每一個 Job ,GitLab Runner 會透過 Docker 啟動 Container 做為此 Job 的環境,而容器要使用什麼 Image 可以在 .gitlab-ci.yml 上定義,會根據要下達的指令定義所需 Image 。

https://ithelp.ithome.com.tw/upload/images/20210918/20139235D6ambEPOZ9.png

像是Script 中若有 python xxx.py 的指令,可以選擇使用 python 的 Image 做為 Job 的容器。

而現在的目標是希望在 Job 中能夠建置 Image ,也就是說,會需要在 script 裡會下達如 docker build 的指令,所以要使用的 Image 就會是 Docker 本身,在 Docker 裡建置 Docker 容器,這種作法稱為 Docker-in-Docker ,在.gitlab-ci.yml可以這樣配置

image: docker

services:
  - docker:dind

在 GitLab 文檔中的 Use Docker to build Docker imagesDocker-in-Docker 方法的詳細介紹。

這樣就可以 Build Docker Image 了,但緊接著會遇到下一個問題,每一次 Job 運行完成後 GitLab Runner 會將容器刪除,所以 Build 好的 Image 需要先 Push 到可以保存的地方,而 GitLab 很好心的提供了 GitLab Container Registry ,讓我們可以儲存在 CI/CD 運行時建置出的 Image。

準備工作差不多完成,可以開始撰寫 .gitlab-ci.yml 了,一開始會將重複使用的值定義為 variabes,如 CI_IMAGE 就是保存在 GitLab Registry 的 Image 名稱。為了區別每次流水線建置出的 Image , Tag 會打上本次 Commit 產生的 SHA 來保證名稱唯一性,在 Predefined variables reference 有參數可以直接代入。

variables:
  IMAGE_NAME: node-project
  CI_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

$CI_REGISTRY_IMAGE 為此專案 GitLab Container Registry 的位置,而 $CI_COMMIT_SHORT_SHA 是 SHA 的前八碼。

接著在 Build Job 中,透過 docker build 以及 docker push 建置 Image 並上傳到 Registry ,因為需要有上傳權限,所以會先使用 docker login 登入取得 Push 權限。

build:
  stage: build
  only:
    - dev
    - master
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $CI_IMAGE .
    - docker push $CI_IMAGE

有了 Image 後,接下來的 Job 就能使用 docker pull 將 Image 下載下來進行其他操作,像是在 Test Job 就可以使用 docker run <image> <command> 運行測試腳本。

test:
  stage: test
  only:
    - dev
    - master
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker pull $CI_IMAGE
    - docker run $CI_IMAGE echo "run test script here"

基本概念大致介紹完成,就來實際建立 Build Stage 吧!

建立 Build Stage

  1. 進入 Cloud Shell 網站

  2. 點擊左上 Explorer -> Open Folder -> 選擇 project 資料夾 -> Open

  1. 點擊 .gitlab-ci.yml 檔案並用以下內容取代

https://ithelp.ithome.com.tw/upload/images/20210918/201392356Z65TgVsn7.png

  • .gitlab-ci.yml
image: docker

services:
  - docker:dind
 
variables:
  IMAGE_NAME: node-project
  CI_IMAGE: $CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA

stages:
  - build
  - test
  - publish
  - stg-deploy
  - prod-deploy

build:
  stage: build
  only:
    - dev
    - master
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $CI_IMAGE .
    - docker push $CI_IMAGE

test:
  stage: test
  only:
    - dev
    - master
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker pull $CI_IMAGE
    - docker run $CI_IMAGE echo "run test script here"

publish:
  stage: publish
  only:
    - master
  script:
    - echo "publish job"

stg-deploy:
  stage: stg-deploy
  only:
    - master
  script:
    - echo "Staging deploy job"

prod-deploy:
  stage: prod-deploy
  only:
    - master
  script:
    - echo "Production deploy job"
  when: manual
  1. 點擊終端機輸入指令,建立 Commit 並 Push 到 GitLab 上
cd ~/project
git add .
git commit -m "add build and test stages"
git push origin master
  1. 輸入 GitLab 帳號密碼後按Enter
Username for 'https://gitlab.com': 
Password for 'https://user@gitlab.com':
  1. GitLab 網站,點擊之前建立的 web app 的 Repository

  2. 進入到 Repository 後,點擊 CI/CD -> Pipelines

會看到新的 CI/CD Pipeline ,等待一段時間直到運行成功。

https://ithelp.ithome.com.tw/upload/images/20210918/20139235hYjGAlDjzY.png

  1. 接著檢查 Image 是否儲存成功,點擊 Packages & Registries -> Container Registry

https://ithelp.ithome.com.tw/upload/images/20210918/20139235utmrYsGzNO.png

可以發現有 webapp 專案的 Image。

https://ithelp.ithome.com.tw/upload/images/20210918/20139235yu4KeMcWvQ.png

點擊進去就能查看 Tag 名稱。

https://ithelp.ithome.com.tw/upload/images/20210918/20139235LDpsOpeSU0.png

這裡的 Tag 名稱會跟本次 Commit 的前八碼 SHA 吻合。

結論

今天完成了 Build Stage , 也簡單說明 Test Stage 的方式,明天會學習如何將 Image 上傳至 Google Container Registry 。


上一篇
Day17 - GitLab CI 流水線建置
下一篇
Day19 - GitLab CI 上傳 Image 到 Google Container Registry
系列文
DevOps 好想學!新手也能打造雲端 Study Lab30

尚未有邦友留言

立即登入留言