Pages - Menu

2023年3月27日 星期一

[Drone]Drone plugin-Drone-docker 修改原始檔

碎碎念

之前發現一個後端執行drone會發生的問題,
偶爾發生,但一段時間總會發生一次。
多個step同時build,會造成image錯亂。
好麻煩阿…

正文

先來看幾張圖,應該就能瞭解我再說什麼了。






首先看到第一張圖,他在執行docker build的時候,會用git commit的值,當作image的tag名稱。

然後看第二張圖,直到build完image後,才會再根據你的tag去將image改成你要的tags

所以我們來想一個情境,當A、B同時執行時,他們的git commit都一樣,
A已經build完了,正要執行最後一個步驟,將git commit tag改成正常的image tag 。
此時B也剛build完,所以他也產生了一個一模一樣的 commit tag的image,那A執行最後一個步驟時,他改得到底是誰的image?

如果一個接一個step跑的話,時間大概需要 4分半,
但同步的話,只要1分半,時間快了三倍。

所以還是要想辦法解掉,本來有想幾個解法,

  1. 一次把程式都build一遍,放在同一個image內,
    執行時,再根據參數看要執行哪個檔案。

但是他們有一種情境是只要更新其中一個功能就好,那此時全部build就不太適合。

  1. 在drone step時,塞tag進去,但他只會在最後一個步驟,才會改image的tag ,這招也不行

  2. 改plugin/gcr 了,在第一步驟時就把image的tag改掉,不要使用git commit,那就解掉這個問題了。

動手

首先找到這個image的原始碼 drone-plugins/drone-docker,然後開始改吧。

各環境main.go的package import docker 要先改掉,不改掉我不確定他會不會抓本機的package,我golang初學沒多久。

修改前

import (
    "os"
    "runtime"

    "github.com/joho/godotenv"
    "github.com/sirupsen/logrus"
    "github.com/urfave/cli"

    docker "github.com/drone-plugins/drone-docker"
)

修改後

import (
    "os"
    "runtime"

    "github.com/joho/godotenv"
    "github.com/sirupsen/logrus"
    "github.com/urfave/cli"

    docker "drone-docker"
)

然後我在docker.go上面直接加了兩行,指定了tag,這不適合所有人,
因為你們的使用情境可能跟我不太一樣,我這邊是只要push到git後,drone會自動產生tag,所以如果不指定的話,我還是有tag的值可以取得。

tag := build.Repo + ":" + build.Tags[0]

args := []string{
"build",
"--rm=true",
"-f", build.Dockerfile,
"-t", build.Name,
"-t", tag,
}

另外,如果要知道plugin/gcr裡面有什麼環境變數可以拿來用的話,
可以在drone的step上面,執行export -p

- name: publish-dev
  image: plugins/gcr
  pull: if-not-exists
  volumes:
    - name: docker
      path: /var/run/docker.sock   
  commands: 
    - export -p

執行結果:


改完後,執行下面的指令先產生go 的程式。
這個go的指令,我是從.drone.yaml抄出來的。
執行前記得先設定環境變數

export GOOS=linux
export GOARCH=amd64
export CGO_ENABLED=0
export GO111MODULE=on

Go build

go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-docker ./cmd/drone-docker
go build -v -ldflags "-X main.version=${DRONE_COMMIT_SHA:0:8}" -a -tags netgo -o release/linux/amd64/drone-gcr ./cmd/drone-gcr

Docker build

將go的執行檔打包進去docker image內,
先打包到本機的docker:linux-amd64,
因為docker-gcr的dockerfile會去抓docker:linux-amd64 當作image的基底再產生檔案

docker build \
  --label org.label-schema.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  --label org.label-schema.vcs-ref=$(git rev-parse --short HEAD) \
  --file docker/docker/Dockerfile.linux.amd64 --tag plugins/docker:linux-amd64 .
docker build \
  --label org.label-schema.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
  --label org.label-schema.vcs-ref=$(git rev-parse --short HEAD) \
  --file docker/gcr/Dockerfile.linux.amd64 --tag asia-east1-docker.pkg.dev/rouge-sms/docker-public/gcr:0.0.13 .

完成



上圖可以看到,在docker build時,會同時下兩個tag,
一個還是維持git commit的值,但另一個就是拿repository加版本號當作tag。

ref.

沒有留言:

張貼留言