基於Kubernetes的CI/CD利器 — Prow 入門指南

簡介

Prow 是 Kubernetes 官方使用的 CI/CD 系統,用於管理k8s的issue和pr。若是你常常去 Kubernetes 社區查看 PR 或者提交過一些 PR 後,就會常常看到一個叫k8s-ci-bot的機器人在各個Pr中回覆,而且還能合併pr。在k8s-ci-bot中背後工做的就是Prow。Prow是爲了彌補 GitHub 上一些功能上的缺陷,它也是Jenkins-X的一部分,它具有這些功能:html

  1. 執行各類 Job,包括測試,批處理和製品發佈等,可以基於github webhook配置 Job 執行的時間和內容。
  2. 一個可插拔的機器人功能(Tide),可以接受/foo這種樣式的指令。
  3. 自動合併Pr
  4. 自帶一個網頁,可以查看當前任務的執行狀況以及Pr的情況,也包括一些幫助信息
  5. 基於OWNER文件在同一個repo裏配置模塊的負責人
  6. 可以同時處理不少repo的不少pr
  7. 可以導出Prometheus指標

Prow 擁有本身的CI/CD系統,可是也能與咱們常見的 CI/CD 一塊兒協做,因此若是你已經習慣了 Jenkins 或者travis,均可以使用 Prow。nginx

安裝指南

官方repo提供了一個基於GKE快速安裝指南,本文將基於青雲的Iaas搭建Prow環境。不用擔憂,其中大部分步驟都是平臺無關的,整個安裝過程可以很方便的在其餘平臺上使用。git

1、 準備一個 Kubernetes集羣

有如下多種方式準備一個 Kubernetes 集羣github

  1. 利用kubeadm自建集羣;
  2. 在青雲QingCloud一鍵部署 KubeSphere 集羣,或直接下載安裝 KubeSphere
  3. 將集羣的kubeconfig複製到本地,請確保在本地運行kubectl cluster-info正確無誤。

2、 準備一個 GitHub 機器人帳號

若是沒有機器人帳號,用我的帳號也能夠。機器人帳號便於區分哪些Prow的行爲,因此正式使用時應該用機器人帳號。web

  1. 在想要用prow管理的倉庫中將機器人帳號設置爲管理員。docker

  2. 在帳號設置中添加一個[personal access token][1],此token須要有如下權限:bash

    • 必須public_reporepo:status
    • 可選repo假如須要用於一些私有repo
    • 可選admin_org:hook 若是想要用於一個組織
  3. 將此Token保存在文件中,好比${HOME}/secrets/oauthapp

  4. openssl rand -hex 20生成一個隨機字符串用於驗證webhook。將此字符串保存在本地,好比${HOME}/secrets/h-macide

注意最後兩步建立的token必定須要保存好,除了須要上傳到k8s,後續配置也要用到,用於雙向驗證工具

3、 配置 Kubernetes 集羣

這裏使用的default命名空間配置prow,若是須要配置在其餘命名空間,須要在相關kubectl的命令中配置-n參數,而且在部署的yaml中配置命名空間。 建議將本repo克隆到本地,這個repo帶有不少幫助配置Prow的小工具。

  1. 將上一步中建立token和hmac保存在k8s集羣中
# openssl rand -hex 20 > ${HOME}/secrets/h-mac
kubectl create secret generic hmac-token --from-file=hmac=${HOME}/secrets/h-mac
kubectl create secret generic oauth-token --from-file=oauth=${HOME}/secrets/oauth
複製代碼
  1. 部署Prow。因爲Prow官方yaml中使用了grc.io鏡像,這個鏡像在中國大陸沒法訪問,因此咱們將相應的repo搬到了dockerhub上,並提供了一份替換相關鏡像名稱的yaml,利用下面的命令便可部署Prow(使用的這個repo修改後的yaml)
kubectl apply -f https://raw.githubusercontent.com/magicsong/prow-tutorial/master/prow.yaml
複製代碼
  1. 使用kubectl get pod看到全部Pod都running表示安裝已經完成。以下圖:

  1. 配置外網訪問
  • 若是使用的QKE,那麼集羣默認帶有LoadBalancer Controller。若是隻是一個單獨集羣,那麼只須要按照github.com/yunify/qing…中的安裝便可,安裝很是方便。
  • Prow官方採用的是ingress配置外網訪問,因此咱們須要配置ingress-controller。QKE默認帶有一個ingress-controller,在kubesphere-control-system中。若是集羣中尚未ingress-controller,須要安裝一個。官方文檔中尚未青雲的配置指南,須要安裝下面的指令安裝ingress-controller
  • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
    kubectl apply -f https://raw.githubusercontent.com/magicsong/prow-tutorial/master/manifest/ingress-service.yaml #這個命令QKE須要執行
    複製代碼
    執行上述兩條命令以後,敲 kubectl get svc -n ingress-nginx,等待獲取公網IP便可,以下圖(若是須要手動指定公網IP,參考LB的配置文檔配置ingress-nginx這個service):

注意若是使用的QKE,須要執行上面兩個命令中的第二個命令。第二個命令對應的yaml就是ingrsss,在apply以前須要將其中的namespace修改成kubesphere-control-system

  1. 訪問Prow地址,默認應該爲剛纔的ingress的公網ip+端口8080,應該能在頁面中看到一個Echo Test的任務。訪問效果以下:

恭喜你!你已經擁有了一個prow集羣,這個集羣已經準備工做了,下一步就是要作一些配置工做,以使得Prow能按照咱們的意圖工做。

配置指南

Prow配置較爲複雜,這裏只演示最小配置,能讓咱們的Pr機器人工做起來

工具準備

  1. 安裝bazel。Bazel是google公司用來構建k8s代碼的一個工具,一樣prow也是用bazel構建的。後續的配置都是用bazel動態生成的工具來配置的(相似於go run ./pkg/tool -a -b)。若是你身處非大陸地區,也能夠不用Bazel,直接時候用go get來獲取靜態binay執行命令。
  2. 若是要使用bazel,安裝完成以後須要將整個倉庫github.com/kubernetes/… 整個倉庫clone下來,用於Bazel運行命令的倉庫。clone完成以後cd 進入這個repo的根目錄

配置webhook

Prow是基於webhook工做的,github上的活動會發送給處理

  1. 選擇一個github倉庫配置webhook。執行下面的命令添加一個repo,須要替換掉其中的hmac-pathgithub-token-path,hook的地址是上面的prow地址加一個」/hook「:
# Ideally use https://bazel.build, alternatively try:
# go get -u k8s.io/test-infra/experiment/add-hook && add-hook
bazel run //experiment/add-hook -- \
  --hmac-path=/path/to/hook/secret \
  --github-token-path=/path/to/oauth/secret \
  --hook-url http://an.ip.addr.ess/hook \
  --repo my-org/my-repo \
  --repo my-whole-org \
  --confirm=false  # Remove =false to actually add hook
複製代碼
  1. 若是運行沒問題,那麼須要將最後一行改成--confirm=true。運行成功後,在repo的webhooks配置中,應該能看到一個新的webhook:

配置集羣使用的插件

Prow是以插件機制運行的,相似CoreDNS那種,沒有插件就什麼都不作,可是依然能正常運行。咱們須要配置咱們的repo須要哪些插件

  1. 官方提供了很多插件,在上面的Prow頁面中就能看到一些,如今演示如何使用內置的一些插件。首先建立一個plugins.yaml的文件,以下:
plugins:
  github.com/kubesphere-test/prow-tutorial:
 - size
 - cat 
 - dog
 - pony 
 - yuks 
 - label
 - trigger
 - approve
 - lgtm 
複製代碼
  1. 建立一個空白的config.yaml,這個文件將會在後續配置任務中使用,插件配置部分留空便可。
  2. 若是安裝了bazel,那麼進入test-infra這個目錄,執行下面的命令(記得替換其中的相關文件的路徑),這個命令會檢查config.yamlplugins.yaml的配置是否正確:
bazel run //prow/cmd/checkconfig -- --plugin-config=path/to/plugins.yaml --config-path=path/to/config.yaml
複製代碼
  1. 檢查無誤以後就能夠將plugins.yaml上傳到集羣中(替換其中的路徑):
kubectl create configmap plugins \
  --from-file=plugins.yaml=${PWD}/samples/plugins.yaml --dry-run -o yaml \
  | kubectl replace configmap plugins -f -
複製代碼
  1. 這樣size插件就完成了。能夠提一個PR,效果應該以下圖:

  1. 上述演示中還安裝了不少好玩的插件,能夠參考prow頁面中幫助頁面,學習如何使用這些命令。

配置Tide機器人

tide機器人最主要的功能就是自動合併Pr,當設定的目標達成時,tide機器人就會自動將代碼Merge進主分支。Tide的完整的配置較爲複雜,這裏演示一個基本的配置,無需修改不少就能運行。

  1. 在上述config.yaml中加入下列字段(請修改相應的repo和相應的tide頁面):
tide:
 merge_method:
    kubesphere-test/prow-tutorial: squash

 target_url: http://139.198.121.161:8080/tide
 queries:
 - repos:
 - kubesphere-test/prow-tutorial
 labels:
 - lgtm
 - approved
 missingLabels:
 - do-not-merge
 - do-not-merge/hold
 - do-not-merge/work-in-progress
 - needs-ok-to-test
 - needs-rebase

 context_options:
    # Use branch protection options to define required and optional contexts
 from-branch-protection: true
    # Treat unknown contexts as optional
 skip-unknown-contexts: true
 orgs:
 org:
 required-contexts:
 - "check-required-for-all-repos"
 repos:
 repo:
 required-contexts:
 - "check-required-for-all-branches"
 branches:
 branch:
 from-branch-protection: false
 required-contexts:
 - "required_test"
 optional-contexts:
 - "optional_test"
複製代碼
  1. 執行下面的命令將config.yaml推送到k8s集羣中(替換相應的config.yaml文件位置):
kubectl create configmap config --from-file=config.yaml=${PWD}/samples/config.yaml --dry-run -o yaml | kubectl replace configmap config -f -
複製代碼
  1. 去剛纔的pr上看,應該能夠看到下面的check:

  1. 因爲這是我提的Pr,因此自動會帶上approved標籤,如今只要添加一個lgtm的標籤就能夠。須要找代碼Review的人看過代碼,而後讓他們輸入/lgtm的評論便可,Prow會自動打上lgtm的標籤。(因爲此次演示沒有其餘人打/lgtm,而且本身沒法給本身評論/lgtm,因此本次演示須要手動給這個pr在lables中選擇lgtm的標籤)。效果以下圖:

高級配置

Prow 是一個高效的CI/CD系統,也是一個複雜的系統,本文沒法闡述全部的高級配置,更深刻的配置能夠參考官方文檔。本Repo整理了一些經常使用的腳本,方便後續使用Prow的時候進行配置。使用這些腳本時,請注意替換一些數據。 更多的請參考如下的OWNERS 使用指南。

OWNERS 使用指南

OWNERS是一個配置文件,用於標記代碼的文件夾的所屬。

工做原理

  1. OWNERS文件表示這這個文件所在的目錄的全部者,包括子目錄。因此root目錄裏的OWNERS文件擁有整個集羣的最高權限,稱之爲"root owner",全部的Pr只要root owner贊成了都會被自動合併。
  2. repo下的每一個文件夾均可以設置OWNERS,若是某一個Pr改動了這個文件夾後者其子文件夾的內容,就須要這個文件夾的OWNER 贊成才行,若是改了多個,那就須要多我的都approve。固然也能夠直接找root owner
  3. 能夠在OWNERS文件中設置Label,全部改動了這個文件夾中的Pr都會被打上相應標籤。固然,這個Label不該該出如今root OWNERS中,這樣會給全部的Pr都打上標籤。

基本語法

OWNERS是一個yaml文件,其基本形式(最簡單配置)以下:

approvers:
 - alice
 - bob     # this is a comment
reviewers:
 - alice
 - carol   # this is another comment
 - sig-foo # this is an alias
lables:
 - re/foo
 - re/question
複製代碼
  1. approvers 可以是用/approve命令,這個命令是Pr可以合併的最小條件。能夠沒有lgtm,可是必需要有approved。因此appovers擁有Merge權限,相似於maintainer級別。這裏還有一個注意事項就是approvers提的pr若是知足了工做原理中的第二條規則,就會自動會被打上approved的標籤(出現這種狀況有兩種可能,1. 他是root owner,2. 他是subdir owner,並且他改的代碼都是在這個目錄下的),因此須要在pr merge上添加上另一個標籤的限制(一般是lgtm),來阻止approvers的代碼自動被merge。
  2. reviewer 可以使用/lgtm命令(Looks good to me),用於審閱代碼。通常的repo都會把lgtm這個命令做爲必要條件,任何人提的代碼都不會自動打上lgtm的標籤,必需要手動使用命令才行。主要是約束代碼必須被review過才行。
  3. 若是approvers使用了github的approve功能,也能打上approve的標籤。

高級語法

OWNERS還支持Fliter參數(這個參數不能和上面的這些混合使用),這個參數主要用於對代碼文件進行分類,能夠參考github.com/kubernetes/…瞭解更詳細的用法。

相關文章
相關標籤/搜索