欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

gitlab?ci?cd?命令的使用不完全指南

 更新時間:2023年04月16日 08:48:14   作者:eleven26  
這篇文章主要為大家介紹了gitlab中ci和cd命令使用的不完全指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

gitlab 可能大家很常用,CI、CD 也應(yīng)該早有耳聞,但是可能還沒有去真正地了解過,這篇文章就是我對 gitlab CI、CD 的一些理解,以及踩過的一些坑,希望能幫助到大家。

什么是 CI、CD

CI(Continuous Integration)持續(xù)集成,CD(Continuous Deployment)持續(xù)部署(也包含了持續(xù)交付的意思)。

CI 指的是一種開發(fā)過程的的自動化流程,在我們提交代碼的時候,一般會做以下操作:

  • lint 檢查,檢查代碼是否符合規(guī)范
  • 自動運行測試,檢查代碼是否能通過測試

這個過程我們可以稱之為 CI,也就是持續(xù)集成,這個過程是自動化的,也就是說我們不需要手動去執(zhí)行這些操作,只需要提交代碼,這些操作就會自動執(zhí)行。

CD 指的是在我們 CI 流程通過之后,將代碼自動發(fā)布到服務(wù)器的過程,這個過程也是自動化的。 在有了前面 CI 的一些操作之后,說明我們的代碼是可以安全發(fā)布到服務(wù)器的,所以就可以進(jìn)行發(fā)布的操作。

為什么要使用 CI、CD

實際上,就算沒有 CI、CD 的這些花里胡哨的概念,對于一些重復(fù)的操作,我們也會盡量想辦法會讓它們可以自動化實現(xiàn)的,只不過可能效率上沒有這么高,但是也是可以的。

CI、CD 相比其他方式的優(yōu)勢在于:

  • 一次配置,多次使用:我們需要做的所有操作都通過配置固定下來了,每次提交代碼我們都可以執(zhí)行相同的操作。
  • 可觀測性:我們可以通過 CI、CD 的日志來查看每次操作的執(zhí)行情況,而且每一次的 CI、CD 執(zhí)行的日志都會保留下來,這樣我們就可以很方便地查看每一次操作的執(zhí)行情況。
  • 自動化:我們不需要手動去執(zhí)行 CI、CD 的操作,只需要提交代碼,CI、CD 就會自動執(zhí)行。
  • 少量配置:一般的代碼托管平臺都會提供 CI、CD 的功能,我們只需要簡單的配置一下就可以使用了。同時其實不同平臺的 CI、CD 配置也是有很多相似之處的,所以我們只需要學(xué)習(xí)一種配置方式,就可以在不同平臺上使用了。

gitlab CI、CD

在開始之前,我們可以通過下圖來了解一下 CI、CD 的整體流程:

  • 在開發(fā)人員提交代碼之后,會觸發(fā) gitlab 的 CI 流水線。也就是上圖的 CI PIPELINE,也就是中間的部分。
  • 在 CI 流水線中,我們可以配置多個任務(wù)。比如上圖的 build、unit test、integration tests 等,也就是構(gòu)建、單元測試、集成測試等。
  • 在 CI 流水線都通過之后,會觸發(fā) CD 流水線。也就是上圖的 CD PIPELINE,也就是右邊的部分。
  • 在 CD 流水線中,我們可以配置多個任務(wù)。比如上圖的 staging、production 等,也就是部署到測試環(huán)境、部署到生產(chǎn)環(huán)境等。

在 CD 流程結(jié)束之后,我們就可以在服務(wù)器上看到我們的代碼了。

gitlab CI、CD 中的一些基本概念

在開始之前,我們先來了解一下 gitlab CI、CD 中的一些基本概念:

  • pipeline:流水線,也就是 CI、CD 的整個流程,包含了多個 stage,每個 stage 又包含了多個 job。
  • stage: 一個階段,一個階段中可以包含多個任務(wù)(job),這些任務(wù)會并行執(zhí)行,但是下一個 stagejob 只有在上一個 stagejob 執(zhí)行通過之后才會執(zhí)行。
  • job:一個任務(wù),這是 CI、CD 中最基本的概念,也是最小的執(zhí)行單元。一個 stage 中可以包含多個 job,同時這些 job 會并行執(zhí)行。
  • runner:執(zhí)行器,也就是執(zhí)行 job 的機器,runner 跟 gitlab 是分離的,runner 需要我們自己去安裝,然后注冊到 gitlab 上(不需要跟 gitlab 在同一個服務(wù)器上,這樣有個好處就是可以很方便實現(xiàn)多個機器來同時處理 gitlab 的 CI、CD 的任務(wù))。
  • tag: runnerjob 都需要指定標(biāo)簽,job 可以指定一個或多個標(biāo)簽(必須指定,否則 job 不會被執(zhí)行),這樣 job 就只會在指定標(biāo)簽的 runner 上執(zhí)行。
  • cache: 緩存,可以緩存一些文件,這樣下次流水線執(zhí)行的時候就不需要重新下載了,可以提高執(zhí)行效率。
  • artifacts: 這代表這構(gòu)建過程中所產(chǎn)生的一些文件,比如打包好的文件,這些文件可以在下一個 stage 中使用,也可以在 pipeline 執(zhí)行結(jié)束之后下載下來。
  • variables:變量,可以在 pipeline 中定義一些變量,這些變量可以在 pipeline 的所有 stagejob 中使用。
  • services:服務(wù),可以在 pipeline 中啟動一些服務(wù),比如 mysql、redis 等,這樣我們就可以在 pipeline 中使用這些服務(wù)了(常常用在測試的時候模擬一個服務(wù))。
  • script: 腳本,可以在 job 中定義一些腳本,這些腳本會在 job 執(zhí)行的時候執(zhí)行。

CI、CD 的工作模型

我們以下面的配置為例子,簡單說明一下 pipelinestage、job 的工作模型,以及 cacheartifacts 的作用:

ci 配置文件(也就是一個 pipeline 的所有任務(wù)):

# 定義一個 `pipeline` 的所有階段,一個 `pipeline` 可以包含多個 `stage`,每個 `stage` 又包含多個 `job`。
# stage 的順序是按照數(shù)組的順序來執(zhí)行的,也就是說 stage1 會先執(zhí)行,然后才會執(zhí)行 stage2。
stages:
  - stage1 # stage 的名稱
  - stage2
# 定義一個 `job`,一個 `job` 就是一個任務(wù),也是最小的執(zhí)行單元。
job1:
  stage: stage1 # 指定這個 `job` 所屬的 `stage`,這個 `job` 只會在 `stage1` 執(zhí)行。
  script: # 指定這個 `job` 的腳本,這個腳本會在 `job` 執(zhí)行的時候執(zhí)行。
    - echo "hello world" > "test.txt"
  tags: # 指定這個 `job` 所屬的 `runner` 的標(biāo)簽,這個 `job` 只會在標(biāo)簽為 `tag1` 的 `runner` 上執(zhí)行。
    - tag1
  # cache 可以在當(dāng)前 `pipeline` 后續(xù)的 `job` 中使用,也可以在后續(xù)的 `pipeline` 中使用。
  cache: # 指定這個 `job` 的緩存,這個緩存會在 `job` 執(zhí)行結(jié)束之后保存起來,下次執(zhí)行的時候會先從緩存中讀取,如果沒有緩存,就會重新下載。
    key: $CI_COMMIT_REF_SLUG # 緩存的 key
    paths: # 緩存的路徑
      - node_modules/
  artifacts: # 指定這個 `job` 的構(gòu)建產(chǎn)物,這個構(gòu)建產(chǎn)物會在 `job` 執(zhí)行結(jié)束之后保存起來??梢栽谙乱粋€ stage 中使用,也可以在 pipeline 執(zhí)行結(jié)束之后下載下來。
    paths:
      - test.txt
job2:
  stage: stage1
  script:
    - cat test.txt
  tags:
    - tag1
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/
    # 指定這個 `job` 的緩存策略,只會讀取緩存,不會寫入緩存。默認(rèn)是既讀取又寫入,在 job 開始的時候讀取,在 job 結(jié)束的時候?qū)懭搿?
    # 但是實際上,只有在安裝依賴的時候是需要寫入緩存的,其他 job 都使用 pull 即可。
    policy: pull
# job3 和 job4 都屬于 stage2,所以 job3 和 job4 會并行執(zhí)行。
# job3 和 job4 都指定了 tag2 標(biāo)簽,所以 job3 和 job4 只會在標(biāo)簽為 tag2 的 runner 上執(zhí)行。
# 同時,在 job1 中,我們指定了 test.txt 作為構(gòu)建產(chǎn)物,所以 job3 和 job4 都可以使用 test.txt 這個文件。
job3:
  stage: stage2
  script:
    - cat test.txt
  tags:
    - tag1
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/
    policy: pull
job4:
  stage: stage2
  script:
    - cat test.txt
  tags:
    - tag1
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/
    policy: pull

上面的配置文件的 pipeline 執(zhí)行過程可以用下面的圖來表示:

說明:

  • 上面的圖有兩個 pipeline 被執(zhí)行了,但是 pipeline2 沒有全部畫出來
  • 其中,在 pipeline 1 中,stage1 中的 job 會先被執(zhí)行,然后才會執(zhí)行 stage2 中的 job。
  • stage1 中的 job1job2 是可以并行執(zhí)行的,這也就是 stage 的本質(zhì)上的含義,表示了一個階段中不同的任務(wù),比如我們做測試的時候,可以同時對不同模塊做測試。
  • job1job2 都指定了 tag1 標(biāo)簽,所以 job1job2 只會在標(biāo)簽為 tag1runner 上執(zhí)行。
  • job1 中,我們創(chuàng)建了一個 test.txt 文件,這個文件會作為 stage1 的構(gòu)建產(chǎn)物,它可以在 stage2 中被使用,也就是 job3job4 都可以讀取到這個文件。一種實際的場景是,前端部署的時候,build 之后會生成可以部署的靜態(tài)文件,這些靜態(tài)文件就會被保留到部署相關(guān)的 stage 中。需要注意的是,artifacts 只會在當(dāng)前 pipeline 后續(xù)的 stage 中共享,不會在 pipeline 之間共享。
  • 同時,在 job1 中,我們也指定了 cache,這個 cache 會在 job1 執(zhí)行結(jié)束之后保存起來,不同于 artifacts,cache 是可以在不同的 pipeline 之間共享的。一種很常見的使用場景就是我們代碼的依賴,比如 node_modules 文件夾,它可以加快后續(xù) pipeline 的執(zhí)行流程,因為避免了重復(fù)的依賴安裝。

需要特別注意的是:cache 是跨流水線共享的,而 artifacts 只會在當(dāng)前流水線的后續(xù) stage 共享。

其他一些在個人實踐中的一些經(jīng)驗

gitlab 的 CI、CD 是一個很龐大的話題,同時很多內(nèi)容可能比較少用,所以本文只是介紹個人在實踐中用到的一些內(nèi)容,其他的東西如果有需要,可以自行查閱官方文檔。

指定特定分支才會執(zhí)行的 job

這個算是基本操作了,我們可以通過 only 來指定特定分支才會執(zhí)行的 job,也有其他方法可以實現(xiàn),比如 rules,具體請參考官方文檔。

deploy-job:
  stage: deploy
  # 當(dāng)前的這個 job 只會在 master 分支代碼更新的時候會執(zhí)行
  only:
    - "master"

不同 job 之間的依賴

這個也是基本操作,我們可以通過 needs 來指定不同 job 之間的依賴關(guān)系,比如 job1 依賴 job2,那么 job1 就會在 job2 執(zhí)行完畢之后才會執(zhí)行。

job1:
  stage: deploy
  needs:
    - job2

指定執(zhí)行 job 的 runner

我們可以通過 tags 來指定 job 執(zhí)行的 runner,比如我們可以指定 job 只能在 api 標(biāo)簽的 runner 上執(zhí)行。

build-job:
  stage: build
  tags:
    - api

如果我們沒有標(biāo)簽為 apirunner,那么這個 job 就會一直不會被執(zhí)行,所以需要確保我們配置的 tag 有對應(yīng)的 runner。

指定 job 的 docker image

注意:這個只在我們的 runnerexecutordocker 的時候才會生效。也就是我們的 runner 是一個 docker 容器。

有時候,我們需要執(zhí)行一些特定命令,但是我們?nèi)值?docker 鏡像里面沒有,可能只需要一個特定的 docker 鏡像,這個時候我們可以通過 image 來指定 jobdocker 鏡像。

deploy-job:
  stage: deploy
  tags:
    - api
  # 指定 runner 的 docker image
  image: eleven26/rsync:1.3.0
  script:
    # 下面這個命令只在上面指定的 docker 鏡像中存在
    - rsync . root@example.com:/home/www/foo

為我們的集成測試指定一個 service

在我們的 CI 流程中,可能會有一些集成測試需要使用到一些服務(wù),比如我們的 mysql,這個時候我們可以通過 services 來指定我們需要的服務(wù)。

test_rabbitmq:
  # 這會啟動一個 rabbitmq 3.8 的 docker 容器,我們的 job 就可以使用這個容器了。
  # 我們的 job 可以連接到一個 rabbitmq 的服務(wù),然后進(jìn)行測試。
  # 需要注意的是,這個容器只會在當(dāng)前 job 執(zhí)行的時候存在,執(zhí)行完畢之后就會被刪除。所以產(chǎn)生的數(shù)據(jù)不會被保留。
  services:
    - rabbitmq:3.8
  stage: test
  only:
    - master
  tags:
    - go
  script:
    # 下面的測試命令會連接到上面啟動的 rabbitmq 服務(wù)
    - "go test -v -cover ./pkg/rabbitmq"

復(fù)用 yaml 配置片段

yaml 中,有一種機制可以讓我們復(fù)用 yaml 配置片段,比如:

# 發(fā)布代碼的 job
.deploy-job: &release-job
  tags:
    - api
  image: eleven26/rsync:1.3.0
  script:
    - rsync . root@example.com:/home/www/foo
deploy-release:
  <<: *release-job
  stage: deploy
  only:
    - "release"
deploy-master:
  <<: *release-job
  stage: deploy
  only:
    - "master"

上面的代碼中,我們定義了一個 release-job 的配置片段,然后在 deploy-releasedeploy-master 中,我們都引用了這個配置片段,這樣我們就可以復(fù)用這個配置片段了。 等同于下面的代碼:

# 發(fā)布代碼的 job
.deploy-job: &release-job
  tags:
    - api
  image: eleven26/rsync:1.3.0
  script:
    - rsync . root@example.com:/home/www/foo
deploy-release:
  tags:
    - api
  image: eleven26/rsync:1.3.0
  script:
    - rsync . root@example.com:/home/www/foo
  stage: deploy
  only:
    - "release"
deploy-master:
  tags:
    - api
  image: eleven26/rsync:1.3.0
  script:
    - rsync . root@example.com:/home/www/foo
  stage: deploy
  only:
    - "master"

yaml 的術(shù)語中,這一種機制叫做 anchor。

cache vs artifacts

初次使用的人,可能會對這個東西有點迷惑,因為它們好像都是緩存,但是實際上,它們的用途是不一樣的。

  • cache 是用來緩存依賴的,比如 node_modules 文件夾,它可以加快后續(xù) pipeline 的執(zhí)行流程,因為避免了重復(fù)的依賴安裝。
  • artifacts 是用來緩存構(gòu)建產(chǎn)物的,比如 build 之后生成的靜態(tài)文件,它可以在后續(xù)的 stage 中使用。表示的是單個 pipeline 中的不同 stage 之間的共享。

指定 artifacts 的過期時間

我們可以通過 expire_in 來指定 artifacts 的過期時間,比如:

job1:
  stage: build
  only:
    - "release"
  image: eleven26/apidoc:1.0.0
  tags:
    - api
  artifacts:
    paths:
      - public
    expire_in: 1 hour

因為我們的 artifacts 有時候只是生成一些需要部署到服務(wù)器的東西,然后在下一個 stage 使用,所以是不需要長期保留的。所以我們可以通過 expire_in 來指定一個比較短的 artifacts 的過期時間。

cache 只 pull 不 push

gitlab CI 的 cache 有一個 policy 屬性,它的值默認(rèn)是 pull-push,也就是在 job 開始執(zhí)行的時候會拉取緩存,在 job 執(zhí)行結(jié)束的時候會將緩存指定文件夾的內(nèi)容上傳到 gitlab 中。

但是在實際使用中,我們其實只需要在安裝依賴的時候上傳這些緩存,其他時候都只是讀取緩存的。所以我們在安裝依賴的 job 中使用默認(rèn)的 policy,而在后續(xù)的 job 中,我們可以通過 policy: pull 來指定只拉取緩存,不上傳緩存。

job:
  tags:
    - api
  image: eleven26/rsync:1.3.0
  cache:
    key:
      files:
        - composer.json
        - composer.lock
    paths:
      - "vendor/"
    policy: pull  # 只拉取 vendor,在 job 執(zhí)行完畢之后不上傳 vendor

cache 的 key 使用文件

這一個特性是非常有用的,在現(xiàn)代軟件工程的實踐中,往往通過 *.lock 文件來記錄我們使用的額依賴的具體版本,以保證在不同環(huán)境中使用的時候保持一致的行為。

所以,相應(yīng)的,我們的緩存也可以在 *.lock 這類文件發(fā)生變化的時候,重新生成緩存。上面的例子就使用了這種機制。

script 中使用多行命令

script 中,我們可以使用多行命令,比如:

job:
  script:
    # 我們可以通過下面這種方式來寫多行的 shell 命令,也就是以一個豎線開始,然后換行
    - |
      if [ "$release_host" != "" ]; then
        host=$release_host
      fi

CD - 如何同步代碼到服務(wù)器

如果我們的項目需要部署到服務(wù)器上,那么我們還需要做一些額外的操作,比如同步代碼到服務(wù)器上。 如果我們的 gitlab 是通過容器執(zhí)行的,或者我們的 runner 的 executor 是 docker,那么有一種比較常見的方法是通過 ssh 私鑰來進(jìn)行部署。

我們可以通過以下流程來實現(xiàn):

  • 新建一對 ssh key,比如 id_rsaid_rsa.pub。
  • id_rsa.pub 的內(nèi)容添加到服務(wù)器的 authorized_keys 文件中。
  • id_rsa 上傳到 gitlab 中(在項目的 CI/CD 配置中,配置一個變量,變量名為 PRIVATE_KEY,內(nèi)容為 id_rsa 的內(nèi)容,類型為 file)。
  • 在我們的 ci 配置文件中,添加如下配置即可:
before_script:
  - chmod 600 $PRIVATE_KEY
deploy:
  stage: deploy
  image: eleven26/rsync:1.3.0
  script:
    # $user 是 ssh 的用戶
    # $host 是 ssh 的主機
    # $port 是 ssh 的端口
    # $PRIVATE_KEY 是我們在 gitlab 中配置的私鑰
    - rsync -az -e "ssh -o StrictHostKeyChecking=no -p $port -i $PRIVATE_KEY" --delete --exclude='.git' . $user@$host:/home/www

這里的 rsync 命令中,我們使用了 -o StrictHostKeyChecking=no 參數(shù),這是為了避免每次都需要手動輸入 yes 來確認(rèn)服務(wù)器的指紋。

安全最佳實踐:

  • 為每一個 project 配置 ssh key 變量,如果是全局變量的話,其他 project 可以在未授權(quán)的情況下,訪問到這個私鑰,這是非常危險的。
  • 使用單獨的倉庫來保存 ci 配置文件,防止其他人未經(jīng)授權(quán)就修改 ci 配置文件,這也是非常危險的。

必須嚴(yán)格遵循以上兩步,否則會造成嚴(yán)重的安全問題。

總結(jié)

最后,總結(jié)一下本文中一些比較關(guān)鍵的內(nèi)容:

  • gitlab 中的一些基本概念:
    • pipeline:代表了一次 CI 的執(zhí)行過程,它包含了多個 stage。
    • stage:代表了一組 job 的集合,stage 會按照順序執(zhí)行。
    • job:代表了一個具體的任務(wù),比如 build、test、deploy 等。
  • 一個 stage 中的多個 job 是可以并行執(zhí)行的。但是下一個 stagejob 必須要等到上一個 stage 的所有 job 都執(zhí)行完畢之后才會執(zhí)行。
  • cacheartifacts 的區(qū)別:
    • cache 是用來緩存依賴的,比如 node_modules 文件夾,它可以加快后續(xù) pipeline 的執(zhí)行流程,因為避免了重復(fù)的依賴安裝。
    • artifacts 是用來緩存構(gòu)建產(chǎn)物的,比如 build 之后生成的靜態(tài)文件,它可以在后續(xù)的 stage 中使用。表示的是單個 pipeline 中的不同 stage 之間的共享。
  • cache 在安裝依賴的 job 中才需要使用默認(rèn)的 policy,也就是 pull-push,在其他不需要安裝依賴的 job 中使用 pull 就可以了,不需要上傳緩存。
  • cachekey 可以指定多個文件,這樣在指定的文件變動的時候,緩存會失效,這往往用在依賴相關(guān)的文件中。
  • 可以使用 services 關(guān)鍵字來指定需要啟動的服務(wù),比如 mysqlredis 等,在 job 中可以連接到這些 services,從而方便進(jìn)行測試。
  • 可以使用 yamlanchor 機制來復(fù)用一些配置片段,可以少寫很多重復(fù)的配置。
  • 一個 job 必須運行在某個 runner 上,jobrunner 的關(guān)聯(lián)是通過 tag 來指定的。

以上就是gitlab ci cd 不完全指南的詳細(xì)內(nèi)容,更多關(guān)于gitlab ci cd 的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論