最小化DevOps自動化流程(Golang)
-
Why?
為什麼要做自動化流程?
在開發過程中,我們在本地機器上做開發,完成一次功能迭代之後,如何釋出到遠端產品伺服器一直是個很頭疼的問題。最通常的做法就是使用(S)FTP把程式碼(或者程式碼壓縮包)覆蓋到伺服器上。這樣的做法雖然“直截了當”,但是容易出錯,而且全程需要人為干預。(筆者親歷過其他專案部門的負責人過來求助,說釋出時拷貝程式碼到伺服器的過程中,伺服器突然宕機沒有反應。)所以我們需要一種方式幫助我們完成程式碼釋出的整個過程。有非常多的第三方工具幫助我們實現流程自動化的目的。
我們要完成的目標是:1,無人干預;2,縮短髮布時間,減少釋出時期存在的風險;3,增加專案迭代效率。
-
What?
用什麼工具來做自動化流程?
git, github(gitlab)
-
When?
在什麼時機下建立自動化流程?
理論上是在第一次釋出專案到伺服器之前就需要做自動化流程。但是根據迭代開發的思想,我們在建立專案的時候就應該開始著手建立自動化流程。
-
How?
如何建立一個最小化的自動化流程?
我們通過三部實現開發部署流程自動化。
-
建立版本倉庫

new gitlab repo
接著clone 遠端倉庫到本地開發機器.
如果你還沒有建立任何專案程式碼檔案。此時可以使用命令:
git clone [email protected]:EdisonLeung/devops.git cd devops touch README.md git add README.md git commit -m "add README" git push -u origin master
如果您已經開始了本地機器上的編碼工作,此時可以在專案目錄下使用命令:
git init git remote add origin [email protected]:EdisonLeung/devops.git git add . git commit -m "Initial commit" git push -u origin master
如果您不光在本地開始了編碼工作,同時在本地已經建立了git倉庫.此時可以在專案目錄下使用命令:
git remote rename origin old-origin git remote add origin [email protected]:EdisonLeung/devops.git git push -u origin --all git push -u origin --tags
最後在伺服器clone我們的版本倉庫(記得新增伺服器SSH Key到Gitlab):
cd ~/www git clone [email protected]:EdisonLeung/devops.git
clone完成:
root@aliyun:~/www# git clone [email protected]:EdisonLeung/devops.git Cloning into 'devops'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0) Receiving objects: 100% (3/3), done.
目前我們從專案開發到專案部署有三個動作要手動做:
a) 本地機器git push到遠端倉庫
b) 遠端伺服器git pull拉去遠端倉庫版本
c) 重啟webserver服務
第二步我們就要將這三個動作自動化。
-
建立自動化部署指令碼
建立deploy目錄,並建立兩個檔案,main.go和deploy.sh:

目錄結構
deploy.go
package main import ( "io" "log" "net/http" "os/exec" ) func relaunching() { cmd := exec.Command("sh", "./deploy.sh") err := cmd.Start() if err != nil { log.Fatal(err) } err = cmd.Wait() } func restart(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "<h1>deploy server: restarting webserver...</h1>") relaunching() io.WriteString(w, "<h1>deploy server: webserver restarted!</h1>") } func main() { http.HandleFunc("/", restart) http.ListenAndServe(":5000", nil) }
當伺服器5000埠被訪問時,http.HandleFunc會建立路由呼叫restart函式relaunching函式,呼叫過程中在瀏覽器輸出啟動過程.
最終relaunching函式呼叫命令列deploy.sh來重啟webserver.
deploy.sh指令碼內容如下:
#! /bin/sh kill -9 $(pgrep webserver) cd ~/www/devops git pull [email protected]:EdisonLeung/devops.git ./webserver &
再建立一個main.go來啟動一個最小web頁面:

webserver main.go
程式碼示例如下:
package main import ( "io" "net/http" ) func index(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "<h1>This is Index Page!</h1>") } func main() { http.HandleFunc("/", index) http.ListenAndServe(":8080", nil) }
注意:這裡的http監聽埠號要與deploy.go內的埠號區別開,不能是相同埠號,不然會有埠衝突造成服務不能啟動!
這時的程式碼架構就完成了,下面我們來編譯釋出程式碼:
因為我們在本地機器環境編譯程式碼,所以對於異構系統來說,go語言為我們提供了相應的引數來針對不同的作業系統和架構進行程式碼的編譯:
因為伺服器所採用的是linux amd64的系統,所以編譯命令的環境變數如下:
main.go編譯生成webserver
env GOOS=linux GOARCH=amd64 go build -o webserver
進入deploy目錄編譯生成deploy
env GOOS=linux GOARCH=amd64 go build
輸出的檔案如圖:

編輯結果
下面我們提交專案:
進入DevOps根目錄
git add . git commit -m "basic automatic publishing feature." git push origin master
提交結果:
Counting objects: 8, done. Delta compression using up to 4 threads. Compressing objects: 100% (8/8), done. Writing objects: 100% (8/8), 5.03 MiB | 1.21 MiB/s, done. Total 8 (delta 1), reused 0 (delta 0) To gitlab.com:EdisonLeung/devops.git 91e5396..c9c087fmaster -> master
接下來就要進入伺服器拉去最新版本程式碼併發布。
登入遠端伺服器拉取程式碼:
root@aliyun:~/www/devops# git pull remote: Enumerating objects: 9, done. remote: Counting objects: 100% (9/9), done. remote: Compressing objects: 100% (8/8), done. remote: Total 8 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (8/8), done. From gitlab.com:EdisonLeung/devops 91e5396..c9c087fmaster-> origin/master Updating 91e5396..c9c087f Fast-forward deploy/deploy| Bin 0 -> 6594124 bytes deploy/deploy.go |28 ++++++++++++++++++++++++++++ deploy/deploy.sh |6 ++++++ main.go|15 +++++++++++++++ webserver| Bin 0 -> 6498848 bytes 5 files changed, 49 insertions(+) create mode 100755 deploy/deploy create mode 100644 deploy/deploy.go create mode 100644 deploy/deploy.sh create mode 100644 main.go create mode 100755 webserver
將deploy目錄拷貝至使用者根目錄:
cp -r ~/www/devops/deploy/* ~/
啟動webserver和deploy service:
cd ~ ./www/devops/webserver & ./deploy &
開啟瀏覽器檢視結果顯示:

webserver result

deploy service result
兩個服務均啟動成功了!
注意 1.兩個服務啟動前,先用以下命令檢視是否有相同服務正在執行,如果有,先將其kill掉:
$ps aux | grep webserver
$kill [pid]
注意 2.使用chmod命令給服務程式和指令碼提權:
chmod a+x webserver
-
自動獲取版本推送事件webhook
我們將部署觸發的地址新增到遠端版本倉庫的webhook中,如圖:

webhook
webhook新增完成:

webhook
下面我們驗證一下這個簡單的自動化流程的效果。
我們把顯示的文字改為"This is the Index Page2".

change code
然後編譯提交

編譯提交
檢視結果:

釋出迭代成功