1. 程式人生 > >gitlab-ci配置疑難備忘

gitlab-ci配置疑難備忘

運行 備忘 不同 ava isp 多平臺 -1 目前 命令行

最近在自搭的gitlab服務器上加上了ci,大部份操作都比較順利,但是也碰到一些問題抓狂,記錄如下。

1、關於一個project配多個runner:在gitlab-ci裏是支持的,但是含義確有點反常,

我之前認為是每個runner都會獨立運行所有job,這樣一來可以在不同的os上添加runner,以達到多平臺測試的目的。

然而gitlab-ci實則對多runner的處理是當成一個資源池,由空閑runner來挑選job,那麽build和test兩個job可能會在不同的runner上運行,導致依賴錯誤。

如果只是為了多平臺測試目的,可以把每個job復制多份,每份給一個不同的tag(os名),然後各os上的runner也有相應的tag,那麽在分配時就會各取所需。

但是這樣仍然有問題:

一是復制出來的那麽多job已經在那裏了,每輪pipeline必須都執行完,但一旦有一個runner不在線(比如說臨時掛了或取消了),對應os的job就沒人執行,整個pipeline就無法完成。

二是沒有辦法手動挑選部份os測試,可能某次提交只改了linux平臺上相關代碼,但是也要把所有平臺測試runner跑一遍,非常費事,現在在cm msg裏可以用[ci skip]來跳過整輪pipeline,但卻沒有其它指令來選擇(或只跳過)部份jobs。

這一系列問題在gitlab官網上已經很多人提了issue及相關建議,希望在之後版本能改進吧。

https://gitlab.com/gitlab-org/gitlab-ce/issues/18041

https://gitlab.com/gitlab-org/gitlab-ce/issues/24610

2、如何讓runner在本機啟動一個長進程(不關閉的),比如說deploy job,就在本機部署運行?

問題在於,runner每收到一個job,運行相應的命令,必須要等到該命令完成,以向上匯報運行結果,如果命令裏啟動了其它進程,也就必須等那些進程結束,一個長運行進程,自然就會卡住整個pipeline了。對於一些常用分離子進程的招數,如前面加nohup,後面加&,都不管用,其原因在於,runner監視自己啟動的進程是用進程組的方式,即使脫離父子關系,組仍然存在:

技術分享

圖中java進程是在運行的測試程序,它和上面啟動它的各級bash的pgid是一樣的。(https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/2231)

解決這個問題的簡單辦法,就是讓目標進程以service方式啟動,這樣就徹底脫離了runner的進程組。(當然還有其它方案,最後再說,先把最難的一路回顧完)

然而跟著這一思路走下去,繼續遇到各種問題:

a、首先做一個service用來啟動目標進程,這是最基本的一步了。在ubuntu上,把控制腳本放到/etc/init.d裏,用update-rc.d來註冊服務。

b、要啟停service,必須有sudo權限,然而runner在後臺運行並沒有終端用來輸密碼,怎麽辦?原來/etc/sudoers裏面還可以配置NOPASSWD選項,可以讓sudo不輸密碼,長姿勢了。

c、用service來運行進程,用戶是root,實際上又以-u方式切換成gitlab-runner這個專用賬號,然而它是沒有桌面的,因為登錄桌面用的是自己的開發人員賬號,要運行的是一個java awt程序,沒有桌面的話會報錯運行不起來,怎麽辦?原來可以通過共享.Xauthority文件的方式,讓其它賬號連接自己的桌面,具體則是要在運行java awt之前先導出DISPLAY和XAUTHORITY兩個環境變量:

技術分享

又長姿勢了。

3、程序運行起來了,但是依賴的一些外部文件(不在git倉庫)怎麽辦?

這些外部文件,可能還會變化,不能每次都手動去拷,需要自動同步過來。

目前辦法是利用堅果雲,開發者在自己電腦上,把需要的依賴文件都放在堅果雲同步文件夾裏,這樣每當有更新,就會自動上傳到堅果雲服務器。

在ci機器上裝一個堅果雲客戶端當然是最簡單,但是也可以用掛載一個davfs的方式來通過webdav協議從堅果雲服務器拉數據,更便於命令行操作。

gitlab-ci配置疑難備忘