上一篇中,我們示範了如何配置并運作一條簡單的流水線,可能有些讀者對于上篇文章中的配置還有些疑問:
- 為何建構任務運作時會有一個slave節點加入
- pipeline的寫法似乎和Jenkins文檔中的例子有點不一樣
今天這篇文章就來解答上面兩個問題,并解釋下建構中的幾個stage跟傳統環境中的差異
哪裡來的slave?
這些slave節點都是
kubernetes-plugin
這個插件動态建立的,實際上是在kubernetes運作的一個pod
大家應該還記得,我們在第一篇文章中,檢查Jenkins安裝結果的時候,檢視了
cloud
的kubernetes配置,這些配置就是給
kubernetes-plugin
用的
這個插件會擴充pipeline的寫法,允許我們自定義執行建構的環境,這也是為什麼我們的pipeline會跟常見的有些差異的原因
slave節點配置
參數 | 作用 |
---|---|
名稱 | kubernetes叢集的辨別,pipeline中以此選擇在哪個叢集中做建構 |
Kubernetes 位址 | kubernetes api入口,如果要連接配接Jenkins master所在的叢集,寫成 https://kubernetes.default 即可 |
憑據 | 連接配接kubernetes api的憑據,如果Jenkins master在叢集内且安裝了rbac權限,可以留白 |
Jenkins 位址 | slave節點連接配接Jenkins master的位址 |
Jenkins 通道 | Jenkins master節點連接配接slave的位址 |
Pod 模闆 | slave節點的定義,可以定義排程規則,包含那些容器,挂載哪些配置等 |
在我們這個環境中,pod模闆的定義放在了pipeline裡,可以提供更好的可回溯性
這裡面還有幾個點要注意:
- Jenkins會在slave pod啟動的時候自動注入一個jnlp container,用來和Jenkins master通信
- 一般來講,pod中的container都會有至少一個stage與其相對應,且stage一般都是串行執行,是以,container的主程序要配置成阻塞在stdin
- container之間一般都會有資料傳遞,預設會給pod上加一個emptydir的volume,mount到每一個container的/home/jenkins/agent目錄,并且這個目錄作為各個container的workspace
容器中的CI/CD
既然slave節點是Jenkins在kubernetes中動态建立的pod,那麼自然我們所有的CI/CD流程都是在容器中進行的,如果說容器中做代碼建構和傳統環境差別還不算大,那麼在後面的docker鏡像建構、釋出到kubernetes等過程就有了比較大的變化了,也是常常會困擾我們的問題,這裡我們要推薦一些新東西出來:
無docker daemon的image build
在容器中做image build并不是新鮮事,常見的有這麼幾種做法:
- dind方式,需要privilege權限
- 挂載/var/run/docker.sock檔案到容器裡,完全操作主機的docker daemon
這兩種方式都對主機有要求,并且在serverless的virtual node上無法使用,我們在示例的pipeline中使用的是kaniko,完全不依賴docker daemon即可完成image build
kubernetes-cli插件
在将應用釋出到kubernetes的時候,需要用到kubectl,這裡有兩種方式:
- 将目标叢集的.kube/config檔案儲存在configmap裡,通過volume的方式挂載到容器裡,在容器内使用kubectl
- 将目标叢集的任意憑證儲存在Jenkins裡,通過kubernetes-cli插件來使用kubectl
在我們的例子中使用的是第二種方式
小結
前面兩篇文章介紹了如果快速搭建Jenkins環境、示範了一條簡單的流水線,本片着重介紹這種建構方式要注意的點以及因這種建構方式而引入的新的工具
後面我們會介紹在這套基于容器的Jenkins環境中的釋出實踐