iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 19
1
DevOps

就是「懶」才更需要重視DevOps系列 第 19

Day19 實際演練 - 自動 Build Image

首先我們要先準備一份 code(以 golang 示範) 跟一份 Dockerfile 檔案,稍後將由 Drone 自動將程式 buildImage

  • 專案結構(HelloWorld):
    .
    ├── vendor (管理 golang pkg 專用)
    ├── Dockerfile
    ├── .drone.yml
    └── main.go
// main.go
package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {

		c.String(http.StatusOK, "Hello World")
	})

	r.Run() // listen and serve on 0.0.0.0:8080
}

## Dockerfile
# 第一層基底
FROM golang:1.11.2-alpine AS build

# 複製原始碼
COPY . /go/src/Project
WORKDIR /go/src/Project

# 進行編譯(名稱為:project)
RUN go build -o project

# 最終運行golang 的基底
FROM alpine

COPY --from=build /go/src/Project/project /app/project
WORKDIR /app

ENTRYPOINT [ "./project" ]

首先準備好以上範例,接著我們準備來執行昨天的四個步驟:

  1. clone project (drone default action)
  2. 編譯程式碼
  3. 讀取 Dockerfilebuild 成映像檔
  4. 推至 Harbor 私有庫

Step1: clone project (請先自行於 Drone 啟動專案)

完成以下 yaml 後,執行 git push 將會觸發 drone 執行 clone 事件

## Drone 1.0 版本寫法
kind: pipeline
type: docker      # 在 Docker 內部執行管道命令
name: clone       # 可自行定義的名稱

Step2: 編譯程式碼

golang 來說,若不將程式內有用到的 pkg 一併上傳至 gitlab 等平台,那麼每次在 build images 之前,就必須要先將使用到的 pkg 重新對外在拉一次,因此這部份也可以交給 drone 自動完成。

## Drone 1.0 版本寫法
kind: pipeline
type: docker      # 在 Docker 內部執行管道命令
name: clone       # 可自行定義的名稱

steps:
  - name: build-golang                   # 事件一:可自行定義的名稱
    image: neil605164/plugin-govendor    # 使用 neil605164/plugin-govendor  容器
    commands:                            # 需執行的指令
      - mkdir -p /usr/local/go/src/${DRONE_REPO_NAME}                 # 於 goroot 建立專案名稱的空資料夾
      - ls -al vendor                                                 # 查看當前 vendor 資料夾(尚未編譯完成的 code)
      - rsync -r  /drone/src/* /usr/local/go/src/${DRONE_REPO_NAME}   # 將 clone 的專案複製到 goroot 底下
      - cd /usr/local/go/src/${DRONE_REPO_NAME}                       # 移動至 goroot 專案底下
      - govendor sync                                                 # 編譯 golang 程式碼
      - rsync -r /usr/local/go/src/${DRONE_REPO_NAME}/* /drone/src    # 將編譯後的程式在複製回 drone 預設 path
      - ls -al vendor                                                 # 查看當前 vendor 資料夾(已經編譯完成的 code)

Drone 編譯程式碼時,會自動至外部 clone 有用到的 pkg,當編譯完成後,所有有用到的 pkg 都會被放置 vendor 資料夾底下,如下圖所示:

備註:
步驟二當中使用到的 neil605164/plugin-govendor 就是我是先封裝好的 drone plugin, 以下是 neil605164/plugin-govendorDockerfile

# 基底
FROM golang:1.11.2-alpine

# 安裝 git + rsync
RUN apk add git rsync

# 安裝 govendor
RUN go get -u github.com/kardianos/govendor

Step3: 讀取 Dockerfilebuild 成映像檔 + 推至 Harbor 私有庫

當程式編譯完成後,當然就是要推到私有庫上啦,在這邊直接採用官方 plugins/docker ,這一個現成的 plugin 就已經夠方便啦,不僅自動 build image 還可以自動推到指定的私有庫,若真的不適合的話也可以透過原本作者寫的在往上疊加自己要的功能上去就好。

## Drone 1.0 版本寫法
kind: pipeline
type: docker      # 在 Docker 內部執行管道命令
name: clone       # 可自行定義的名稱

steps:
  - name: build-golang                                                # 事件一:可自行定義的名稱
    image: neil605164/plugin-govendor                                 # 使用 neil605164/plugin-govendor  容器
    commands:                                                         # 需執行的指令
      - mkdir -p /usr/local/go/src/${DRONE_REPO_NAME}                 # 於 goroot 建立專案名稱的空資料夾
      - ls -al vendor                                                 # 查看當前 vendor 資料夾(尚未編譯完成的 code)
      - rsync -r  /drone/src/* /usr/local/go/src/${DRONE_REPO_NAME}   # 將 clone 的專案複製到 goroot 底下
      - cd /usr/local/go/src/${DRONE_REPO_NAME}                       # 移動至 goroot 專案底下
      - govendor sync                                                 # 編譯 golang 程式碼
      - rsync -r /usr/local/go/src/${DRONE_REPO_NAME}/* /drone/src    # 將編譯後的程式在複製回 drone 預設 path
      - ls -al vendor                                                 # 查看當前 vendor 資料夾(已經編譯完成的 code)
  - name: build-image-push-harbor                   # 事件二:可自行定義的名稱
    image: plugins/docker                           # 使用 plugins/docker  容器
    settings:
      username:                                     # harbor 私有庫帳號
        from_secret: docker_username
      password:                                     # harbor 私有庫密碼
        from_secret: docker_password
      repo: <harbor url> /library/golang-hello      # harbor 私有庫存放位置
      tags: latest                                   # harbor image tag( 也可以利用 ${DRONE_TAG} 自動取得 push 到 gitlab 的版號)
      registry: <harbor url>                        # harbor 私有庫網址

今天就是範到這邊啦,以上步驟就完成了透過 drone 自動「編譯程式碼」、「build image」、「push image」三個動做,這樣是不是只需要寫一次發布腳本,接下來的流程每次都由 drone 自動完成。


上一篇
Day18 該如何實現自動化
下一篇
Day20 Let's Kubernetes
系列文
就是「懶」才更需要重視DevOps30

尚未有邦友留言

立即登入留言