本文首發於:Jenkins 中文社群
作者:翟志軍,審校:王冬輝,linuxsuren
Jenkins master 的高可用是個老大難的問題。和很多人一樣,筆者也想過兩個 Jenkins master 共享同一個 JENKINS_HOME 的方案。瞭解 Jenkins 原理的人,都會覺得這個方案不可行。但是真的不可行嗎?
由於工作原因,筆者需要親自驗證以上猜想。
JENKINS_HOME 介紹
Jenkins 所有狀態資料都存放檔案系統的目錄中,這個目錄被稱為 JENKINS_HOME 目錄。
實驗環境介紹
筆者通過 Docker compose 啟動兩個獨立的 Jenkins master,分別為 jenkins-a 和 jenkins-b。它們共用同一個 JENKINS_HOME 目錄。相應的程式碼倉庫的連結放在文章底部。
將程式碼克隆到本地後,進入倉庫,執行 docker-compose up -d
即可啟動實驗環境。啟動完成,在瀏覽器中輸入 http://localhost:7088 可訪問 jenkins-a,jenkins-b 的地址是 http://localhost:7089 。但是你會發現它們啟動後的介面顯示是不一樣的。
jenkins-b 的介面如下圖所示:
而 jenkins-a 的介面如下圖所示:
這時,將 jenkins-a 日誌中的解鎖密碼(Unlock password)輸入到 jenkins-b 的頁面中,會得到報錯資訊:
ERROR: The password entered is incorrect, please check the file for the correct password
複製程式碼
這時,再次 jenkins-b 日誌中的解鎖密碼(Unlock password)輸入到表單中即可進入下一步。接下來就是按照提示一步步完成了。在 jenkins-b 安裝步驟的最後一步,我們設定了管理員的使用者名稱密碼:admin/admin。然後就算完成任務了。
然後我們再在 jenkins-a 使用 admin/admin 進行登入,登入是報錯的:使用者密碼不正確。
接下來,執行 docker-compose restart jenkins-a
命令重啟 jenkins-a。再次使用 admin/admin 就可以登入成功了。
當兩個 Jenkins 啟動完成後,接下來開始做實驗。
實驗1:建立任務
在 jenkins-a 建立任務 x,重新整理 jenkins-b 的頁面,jenkins-b 上會不會顯示出任務 x ?
結果:jenkins-b 不會出現任務 x。重啟 jenkins-b 後,任務 x 出現在任務列表中。
實驗2:任務結果可見性
jenkins-a 上任務執行,jenkins-b 上能否看到任務執行結果?
jenkins-a 執行任務 x,並且執行成功。重新整理 jenkins-b 看不到任何執行記錄。重啟 jenkins-b 後,可看到執行記錄。
實驗3:兩 master 同時執行同一任務
分別在兩個 Jenkins master 上(幾乎)開始同一個任務 x。其中一個任務的 build number 會更新,但是另一個不會。
其中 jenkins-a 任務 x 的 build number 會升到 2,而 jenkins-b 保持的是 1。這時,單獨執行 jenkins-b 的任務 x,日誌會出現錯誤:
jenkins-b_1 | WARNING: A new build could not be created in job x
jenkins-b_1 | java.lang.IllegalStateException: JENKINS-23152: /var/jenkins_home/jobs/x/builds/2 already existed; will not overwrite with x #2
複製程式碼
實驗4:編輯任務
jenkins-a 上設定任務 x 定時執行,重新整理 jenkins-b 頁面,任務 x 中並沒有定時執行的設定。重啟 jenkins-b 後,任務 x 更新。
實驗5:定時任務的結果是什麼?
如果 jenkins-a 和 jenkins-b 兩個任務均為定時任務,而且都生效了。它們執行結果是什麼的呢?
看到的現象是,兩個任務都會按時執行,但是隻有一個任務能將執行結果寫入到磁碟中。介面如下圖:
另,從日誌中,可以確認 jenkins-a 和 jenkins-b 確實按時執行了。如下圖日誌中,看出 jenkins-a 定時執行 #6 次構建時報錯,因為 jenkins-b 已經執行過 #6 次構建了:
小結
可以確認的是,當兩個 Jenkins 程式共用同一個 JENKINS_HOME 目錄時,其中一個 Jenkins 程式更新了 JENKINS_HOME 的內容,另一個是不會實時更新的。所以,同時啟動兩個 Jenkins master 共用同一個 JENKINS_HOME 的方案是不可行的。我們不能在 jenkins-a 掛了後,直接將流量切到 jenkins-b。因為 jenkins-b 必須重啟。
最後結論:多個 Jenkins master 共享同一個 JENKINS_HOME 的方案是無法使用 Jenkins master 的高可用。
附錄
- Jenkins standby 實驗環境:github.com/zacker330/j…