安裝GitLab Runner
本教程的安裝環(huán)境為Ubuntu18.04。
- 運(yùn)行以下命令增加GitLab官方倉(cāng)庫(kù):
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
-
安裝最新版本的GitLab Runner,或者選擇特定的版本:
- 安裝最新版本
sudo apt-get install gitlab-runner- 選擇特定的版本
sudo apt-get install gitlab-runner=10.0.0
注冊(cè)GitLab Runner
此處是將你的GitLab Runner注冊(cè)到GitLab page上,讓GitLab page可以和你的Runner通信。
先決條件
在注冊(cè)Runner之前,你首先需要:
- 安裝好Runner的Linux主機(jī)
- 從GitLab page上獲得token
注冊(cè)
- 運(yùn)行如下命令:
sudo gitlab-runner register
- 輸入GitLab URL:
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
https://code.siemens.com/
注意:你可以通過(guò)GitLab page -> Settings -> CI/CD -> Runners來(lái)獲得URL,當(dāng)然前提條件是你有權(quán)限進(jìn)入這些頁(yè)面。
- 輸入你的注冊(cè)token:
Please enter the gitlab-ci token for this runner
xxx
在步驟2中你也可以同時(shí)看到 token信息
- 輸入對(duì)這個(gè)Runner的表述(同時(shí)也是這個(gè)Runner的名字),當(dāng)然,你也可以稍后在GitLab page上修改它:
Please enter the gitlab-ci description for this runner
[hostame] my-runner
- 輸入Runner的tag,稍后你同樣可以在GitLab page上修改它:
Please enter the gitlab-ci tags for this runner (comma separated):
my-tag,another-tag
注意 tag可以有多個(gè),各 tag之間用逗號(hào)隔開(kāi)。如果你使用了多個(gè) tag,那么當(dāng)你想用這個(gè) Runner時(shí),在.gitlab-ci.yml的 tag字段里也必須明確指明這些 tags。
- 輸入Runner的executor:
Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
docker
如果你選擇Docker作為Runner的executor,你還要選擇默認(rèn)的docker image來(lái)運(yùn)行job(當(dāng)然,你也可以在.gitlab-ci.yml里指明你需要用的image):
Please enter the Docker image (eg. ruby:2.1):
alpine:latest
注冊(cè)完成后你可以在/etc/gitlab-runner里發(fā)現(xiàn) config.toml文件,該文件是Runner的配置文件
使用GitLab Runner
-
直接運(yùn)行Runner
sudo gitlab-runner run -
將Runner作為一個(gè)服務(wù)
- 將GitLab Runner安裝為系統(tǒng)服務(wù):
sudo gitlab-runner install -n "<service-name>" -u <user-name>- 啟動(dòng)服務(wù):
sudo gitlab-runner start -n "<service-name>"注意:這些服務(wù)相關(guān)的命令是不推薦的并且將會(huì)在接下來(lái)的版本中刪除。
想要了解更多GitLab Runner相關(guān)的命令,請(qǐng)?jiān)L問(wèn)GitLab Runner Commands.
重要的話(huà)題 —— Executor
Shell Executor
以宿主機(jī)(此處為Ubuntu18.04系統(tǒng))作為Runner的所有jobs的執(zhí)行器。
Runner將會(huì)從遠(yuǎn)程倉(cāng)庫(kù)pull你的工程,工程的目錄為:<working-directory>/builds/<short-token>/<concurrent-id>/<namespace>/<project-name>。
如果你使用了cache,那么cache將會(huì)存在<working-directory>/cache/<namespace>/<project-name>。
想了解更多關(guān)于Shell executor的內(nèi)容,請(qǐng)?jiān)L問(wèn)Shell Executor。
Docker Executor
所有jobs的執(zhí)行環(huán)境為指定的docker image所生成的container,每個(gè)job都會(huì)生成一個(gè)container并且在job結(jié)束后立即銷(xiāo)毀。
-
Docker executor默認(rèn)將所有的builds存儲(chǔ)在
/builds/<namespace>/<project-name>(這里的路徑是container里的路徑,Runner配置文件config.toml里的build_dir字段可以重新指明build的目錄,默認(rèn)對(duì)應(yīng)于宿主機(jī)的目錄是在宿主機(jī)的docker volume下:/var/lib/docker/volumes/<volume-id>/_data/<project-name>),默認(rèn)將所有的caches存儲(chǔ)在container里的/cache目錄(config.toml里的cache_dir字段可以重新指明cache的目錄),注意build_dir和cache_dir指向的均是container里的目錄,要想將container里的數(shù)據(jù)持久化,需要用到volumes字段,這個(gè)字段的使用和docker volume的使用是類(lèi)似的,只需在config.toml的[runner.docker]部分添加volumes = ["/cache", "<host_dir:container_dir>:rw"]即可實(shí)現(xiàn)container里/cache目錄數(shù)據(jù)的永久保存以及將host目錄掛載到相應(yīng)的container目錄并具有讀寫(xiě)的功能。 -
當(dāng)你使用
docker或docker+machineexecutors時(shí),你可以通過(guò)設(shè)置pull_policy來(lái)決定Runner如何pull docker image。pull_policy有三種值:
always—— Runner始終從遠(yuǎn)程pull docker image。
if-not-present—— Runner會(huì)首先檢查本地是否有該image,如果有則用本地的,如果沒(méi)有則從遠(yuǎn)程拉取。
never—— Runner始終使用本地的image。 -
當(dāng)你使用
docker,docker+machine或kubernetes作為executor時(shí),GitLab Runner將會(huì)使用特定的container來(lái)處理Git、artifacts 和cache 操作。通過(guò)在宿主機(jī)中鍵入以下命令:sudo docker images你會(huì)發(fā)現(xiàn)一些特殊的images,如:
REPOSITORY TAG gitlab/gitlab-runner-helper x86_64-3afdaba6 gitlab/gitlab-runner-helper x86_64-cf91d5e1當(dāng)然,你也可以通過(guò)配置
config.toml里的helper_image字段來(lái)讓Runner使用你自己定制化的helper image。
想要了解更多關(guān)于docker executor的信息,請(qǐng)?jiān)L問(wèn)docker executor。
常見(jiàn)問(wèn)題
當(dāng)在Ubuntu18.04上使用docker executor runner時(shí),出現(xiàn)Runner無(wú)法連接網(wǎng)絡(luò)的問(wèn)題
這個(gè)是Ubuntu18.04與Docker的問(wèn)題,是關(guān)于宿主機(jī)與Container的DNS的映射問(wèn)題,詳情可以訪(fǎng)問(wèn)https://github.com/docker/libnetwork/issues/2187。
你的pipeline可能出現(xiàn)如下情況:
fatal: unable to access 'https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@code.siemens.com/zhen.xie/iavgitlabrunnertest.git/': Could not resolve host: code.siemens.com
該問(wèn)題的解決辦法是在Runner的配置文件config.toml里增加dns = ["***.***.***.***"],dns的值你可以通過(guò)在宿主機(jī)上運(yùn)行nmcli dev show來(lái)獲得。
Pipeline出現(xiàn)"JAVA_HOME is not set and no java command could be found in your PATH"
這個(gè)錯(cuò)誤通常出現(xiàn)在你使用Shell executor時(shí),你可以在GitLab page上設(shè)置這個(gè)環(huán)境變量,具體路徑是GitLab page -> Settings -> CI/CD -> Variables。
如何配置GitLab Runner
請(qǐng)參考https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section。
Runner間隔多久去GitLab上檢查是否有job
config.toml文件的check_interval字段會(huì)決定這個(gè)時(shí)間間隔,它的默認(rèn)值是3秒(注意當(dāng)你把它設(shè)為0時(shí)依然采用的是默認(rèn)值3秒,而不是0秒)。要解釋它的意義,首先我們先來(lái)定義worker,在config.toml文件中定義了很多runner,它們可能executor類(lèi)型不同,可能注冊(cè)地址不同,但都是由GitLab Runner這個(gè)服務(wù)來(lái)管理的,為了與GitLab Runner區(qū)分開(kāi),我們將config.toml文件中定義的runner稱(chēng)為worker。對(duì)于不同的worker,worker之間(如worker A ---> worker B)的間隔為check_interval / worker_nums,但是對(duì)于worker A本身來(lái)說(shuō)它下次去檢查是否有job的時(shí)間間隔仍為check_interval。我們?cè)倥e個(gè)簡(jiǎn)單例子:config.toml定義了3個(gè)worker—— worker A, worker B 和 worker C,check_interval采用默認(rèn)值為3秒,第0秒時(shí)worker A會(huì)去檢查是否有屬于自己的job,第1秒時(shí)worker B會(huì)去檢查,第2秒時(shí)worker C去檢查,第3秒時(shí)worker A再檢查……這個(gè)過(guò)程中worker A到worker B的間隔為3 / 3 = 1秒,而對(duì)于worker A下次檢查job時(shí)的時(shí)間間隔為check_interval,即3秒。
官方文檔對(duì)check_interval的解釋?zhuān)?a target="_blank">https://docs.gitlab.com/runner/configuration/advanced-configuration.html#how-check_interval-works。
config.toml里的concurrent字段的意義
concurrent限制了整個(gè)GitLab Runner能并發(fā)處理job的數(shù)量。特別注意concurrent與worker數(shù)量無(wú)任何關(guān)系,所有worker的工作是受GitLab Runner控制的,如果concurrent值為1并且有一個(gè)worker已經(jīng)在工作了,那么即使其他worker達(dá)到了可以工作的條件也只能“pending”。
cache存儲(chǔ)在哪里
請(qǐng)參考https://docs.gitlab.com/ee/ci/caching/#where-the-caches-are-stored
怎樣清除cache
注意cache是沒(méi)有過(guò)期時(shí)間的,而且每一次新的push觸發(fā)的pipeline,都會(huì)重新生成cache,重新生成的cache的名字為“<cache-key>-<num>”,其中num是隨著push數(shù)量遞增的。如果不去清除cache,cache會(huì)永久保留在Runner上,日積月累會(huì)填滿(mǎn)存儲(chǔ)空間的,因此最好隔一段時(shí)間進(jìn)行一次清除,清除方法請(qǐng)參考https://docs.gitlab.com/ee/ci/caching/#clearing-the-cache,或者使用clear_volumes.sh 這個(gè)簡(jiǎn)單腳本來(lái)處理它, 清除cache的原理是將相關(guān)的volume移除,當(dāng)然,docker也有自帶的清除命令,推薦將docker system prune -f --volumes加入到定時(shí)任務(wù)中。
GitLab Runner 變量的優(yōu)先級(jí)
請(qǐng)參考https://docs.gitlab.com/ee/ci/variables/#priority-of-environment-variables
GitLab Runner有哪些預(yù)定義的變量
請(qǐng)參考https://docs.gitlab.com/ee/ci/variables/#predefined-variables-environment-variables
當(dāng)我的Runner采用docker作為executor時(shí),無(wú)法build docker image
這是個(gè)“dind(docker in docker)” 問(wèn)題,一般pipeline會(huì)報(bào)如下錯(cuò)誤:
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
time="2018-12-17T11:12:33Z" level=error msg="failed to dial gRPC: cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: dial unix
你可以將本地的docker socket綁定到container里來(lái)解決這個(gè)問(wèn)題,具體方法是將volumes = ["/var/run/docker.sock:/var/run/docker.sock"]配置到config.toml文件里。
想要了解更多關(guān)于“dind”的信息,請(qǐng)參考https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker-executor。
如何在job所對(duì)應(yīng)的container里使用git clone命令
如果你想在job運(yùn)行期間clone某些代碼(如shell或python的腳本),首先要確保你的宿主機(jī)有權(quán)限clone代碼,然后你就可以將你的secret掛載到container里,例如,你是通過(guò)ssh的方式克隆代碼,并且你的ssh目錄為home/<user>/.ssh,你就可以在config.toml文件里添加如下配置:
volumes = ["/home/x1twbm/.ssh:/root/.ssh:ro"]
然后,這個(gè)job所對(duì)應(yīng)的container就可以拉取指定代碼了。