基於 Gogs,以 Golang 為例
阿新 • • 發佈:2019-01-10
實際的 DevOps 專案中,在 pipeline 流水線中包含下載程式碼、測試、構建、釋出、部署、通知等步驟。基本流程如下,當然不同的語言或不同的需求下流程會有所差異:
clone -> test -> build -> publish -> deploy -> notify
包含開發的完整流程為:
- 開發專案程式碼,包括
.drone.yml
檔案和 Dockerfile 檔案 - 上傳程式碼至 Gogs,通過 Gogs 的 webhook 觸發 Drone 的 Pipeline
- Drone 開始 Pipeline 的執行
- clone 程式碼至容器
- 測試
- 編譯程式碼,構建可執行檔案(Java、Golang 等編譯型語言需要,PHP 之類的指令碼語言則不需要)
- 將專案和執行環境打包成映象,釋出到 Registry(當然也可以使用 rsync 將編譯後的檔案(Golang 等)或原始碼(PHP 等)部署到伺服器,此時需要在目標伺服器提前安裝執行環境)
- 部署至生產環境
- 傳送郵件等通知資訊
Drone 的文件挺差勁,不過 Drone 用起來還是挺簡單的,比 Jenkins 簡單到無法描述。
打通 Gogs 和 Drone
建立 Git 專案
登入 Gogs 後,從 Web 頁面建立專案。我的 Gogs 專案地址是 https://gogs.kikakika.com
建立完成後,可以在 Web 頁面新增檔案,但是比較麻煩。這裡把倉庫新增到本地:
git clone https://gogs.kikakika.com/lihongfeng/first.git
然後,在倉庫中建立 .drone.yml
和 hello.go
、hello_test.go
三個檔案。
編寫 .drone.yml
檔案
workspace:
base: /go
path: src/gogs.kikakika.com/lihongfeng/first
pipeline:
build:
image: golang:1.10.2
commands:
- go test
- go build
其中,workspace 定義了可以在構建步驟之間共享的 volume 和工作目錄。建議設定 workspace 以使用所需的 GOPATH。其中:
- base 定義了一個可用於所有 pipeline 步驟的共享的 volume。這可確保原始碼、依賴項和編譯的二進位制檔案在步驟之間持久儲存和共享。
- path 定義了用於構建的工作目錄。程式碼會克隆到這個位置,並且構建過程中每個步驟都會使用這個工作目錄作為預設的工作目錄。path 必須是相對路徑,並且可以與 base 相結合。
編寫 Golang 程式碼
main.go
:
package main
import (
"fmt"
)
func main() {
fmt.Printf("hello world");
}
func hello() string {
return "hello world";
}
main_test.go
:
package main
import "testing"
func TestHello(t *testing.T) {
if hello() != "hello world" {
t.Error("Testing error")
}
}
提交程式碼
$ git add ./
$ git commit -m "try drone with golang demo"
[master f8a6927] try drone with golang demo
3 files changed, 33 insertions(+)
create mode 100644 .drone.yml
create mode 100644 main.go
create mode 100644 main_test.go
$ git push
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 696 bytes | 696.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://gogs.kikakika.com/lihongfeng/first.git
b8c5bdd..f8a6927 master -> master
檢視 Drone 的 web 端是否成功觸發
可以看到成功觸發了 CI。具體頁面截圖如下。
- 專案主頁:
- clone 階段:
+ git init
Initialized empty Git repository in /go/src/gogs.kikakika.com/lihongfeng/first/.git/
+ git remote add origin https://gogs.kikakika.com/lihongfeng/first.git
+ git fetch --no-tags origin +refs/heads/master:
From https://gogs.kikakika.com/lihongfeng/first
* branch master -> FETCH_HEAD
* [new branch] master -> origin/master
+ git reset --hard -q fbcf4d02a0294c943269634edd517c977ea03cfb
+ git submodule update --init --recursive
- build 階段:
+ go test
PASS
ok gogs.kikakika.com/lihongfeng/first 0.002s
+ go build
實現 CI/CD
上面的例子只是構建專案及執行測試,並沒有構建映象及將映象釋出到 Registry,更沒有操作生產環境伺服器更新映象。
通過更新上面的 .drone.yml
檔案實現這幾個步驟:
workspace:
base: /go
path: src/gogs.kikakika.com/lihongfeng/first
pipeline:
test:
image: golang:1.10.2
commands:
- go test
build:
image: golang:1.10.2
commands:
- go build
publish:
image: plugins/docker
repo: kikajack/first
dockerfile: ./Dockerfile
tags: latest
# registry: https://harbor.kikakika.com # 如果使用自建的映象倉庫,例如 Harbor,這裡可以通過 registry 指定
secrets: [ docker_username, docker_password ] # 這裡的使用者名稱和密碼在 web 介面指定
# 如果需要自動部署容器到伺服器,可以開啟下面這部分程式碼
# deploy:
# image: appleboy/drone-ssh # 用於連線伺服器
# host:
# - your_host
# username: your_name
# password: your_pass
# port: 22
# command_timeout: 300 # ssh命令列執行超時時間,300秒
# script:
# - docker pull repo_url:latest
# - docker rm -f docker-demo || true # 這裡這樣是因為如果不存在docker-demo,rm會報錯
# - docker run -d -p 8065:8065 --name docker-demo repo_url
其中 secrets: [ docker_username, docker_password ]
中指定的使用者名稱密碼,需要在 Drone 的 Web 頁面設定。這樣可以避免在配置檔案中出現密碼,安全。
Dockerfile 檔案
需要在專案根目錄中建立 Dockerfile 檔案,用於構建映象。可以參考 通過 Docker 部署 Go 伺服器,這裡有完整的示例。這個檔案支援兩種方式構建映象:容器外編譯後複製二進位制檔案到容器,或複製原始碼到容器後在容器中編譯得到二進位制檔案。
複製原始碼到容器後在容器內編譯:
# 官方的 Golang 映象基於 Debian,且 workspace(GOPATH)配置為 /go
FROM golang:1.10.2
# 將本地的 Go 檔案複製到容器中的 workspace
ADD . /go/src/gogs.kikakika.com/lihongfeng/first
# 在容器內編譯構建應用。可以在這裡獲取或管理依賴關係,可以手動或使用諸如“godep”之類的工具
RUN go install gogs.kikakika.com/lihongfeng/first
# 容器啟動時,預設執行 first 應用
ENTRYPOINT /go/bin/first
# 監聽 8080 埠
EXPOSE 8080
容器外編譯後複製二進位制檔案到容器
可以參考 這個例子。
Dockerfile
檔案:
FROM plugins/base:multiarch
LABEL maintainer="Bo-Yi Wu <[email protected]>" \
org.label-schema.name="Drone Workshop" \
org.label-schema.vendor="Bo-Yi Wu" \
org.label-schema.schema-version="1.0"
ADD release/linux/amd64/helloworld /bin/
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 CMD [ "/bin/helloworld", "-ping" ]
ENTRYPOINT ["/bin/helloworld"]
.drone.yml
檔案:
workspace:
base: /go
path: src/github.com/go-training/drone-golang-example
clone:
git:
image: plugins/git
depth: 50
tags: true
pipeline:
testing:
image: golang:1.10.0
commands:
- go test -v .
- go vet
build_linux_amd64:
image: golang:1.10.0
group: build
commands:
- make build_linux_amd64
build_linux_i386:
image: golang:1.10.0
group: build
commands:
- make build_linux_i386
publish_linux_amd64:
image: plugins/docker:17.05
pull: true
secrets: [ docker_username, docker_password ]
group: release
repo: appleboy/test
auto_tag: true
dockerfile: Dockerfile
when:
event: [ push, tag ]
local: false
publish_alpine:
image: plugins/docker
group: release
pull: true
dockerfile: Dockerfile.alpine
secrets: [ docker_username, docker_password ]
default_tags: true
default_suffix: alpine
repo: appleboy/test
when:
event: [ push, tag ]
local: false
驗證映象是否上傳成功
- 登入官方映象倉庫
https://hub.docker.com/r/kikajack/first
,可以看到映象上傳成功了。
- 執行一下,會成功的輸出“hello world”:
[root@VM_139_74_centos ~]# docker run kikajack/first
Unable to find image 'kikajack/first:latest' locally
latest: Pulling from kikajack/first
cc1a78bfd46b: Already exists
6861473222a6: Already exists
7e0b9c3b5ae0: Already exists
3ec98735f56f: Already exists
32ecd1fcfe1a: Already exists
9889d58a42e5: Already exists
337bad6698be: Already exists
831eeb459358: Pull complete
d4438c00f9db: Pull complete
Digest: sha256:9caf567d796deead445606f56892f843f8869aef92d27bb8ff20985cd8a82169
Status: Downloaded newer image for kikajack/first:latest
hello world[root@VM_139_74_centos ~]#