CentOS Stream 是穩定的

Stef Walter發表於2022-08-23

紅帽在宣佈將工作重心從 CentOS 切換到 CentOS Stream 後,CentOS 的定位發生了變化。按照 CentOS 官方的說法,它從原來的 RHEL 下游專案變成了一個 Linux 開發平臺,社群開發者可以與紅帽的開發人員一起為 RHEL 做貢獻。如果單純的從字面上的意思來看,很容易讓人理解為 CentOS Stream 就是紅帽的開發測試版本,既然是開發和測試的版本,所以不穩定就是必然的

那麼實際情況是什麼?

把一個大家可以免費使用的發行版變成了不穩定的開發版本,紅帽真的這麼不厚道麼?我一直想寫點東西來以正視聽,直到我看到了 Stef Walter(他是紅帽僱員,高階總監,軟體工程(全球)。負責 RHEL 和 Satellite 的大部分工作:服務、應用堆疊、安裝、升級、映象構建等等)的博文《CentOS Stream 是持續交付的》,我知道我不需要寫任何東西了,只需將它翻譯成中文就已足夠。為了方便大家理解,在原文譯文的基礎上,我加了很多註釋。

透過這篇譯文,我們可以找到下面問題的答案:

  • 紅帽為什麼要做這個轉變?
  • 紅帽的開發模式發生了哪些變化?
  • Stream和RHEL的異同在哪裡?
  • Stream穩定麼?

持續交付 101:持續做苦難的事情,它們就會變得容易!

從外界看來,我們構建 RHEL(包括 CentOS Linux)的方式十多年來似乎沒有什麼變化。但在幕後,我們正在進行一場巨大的改革,即如何在不影響客戶的情況下開發 RHEL。

我在很多的會議上講述過這個故事,但有關 CentOS Linux 8 和 CentOS Stream 的公告推動了我在這裡講述這個故事。

三年前(原文釋出於 2020 年,因此這裡是 2017 年),我們幾個在 RHEL 工程部工作的人有了一個想法:如果我們將現代化的開發實踐應用到 RHEL 上,比如:持續整合、持續交付、可預測的版本釋出節奏……,再加上開源開放實踐,比如:早釋出、勤釋出、拉取請求、分支和程式碼審查,會怎樣?

很明顯,不是嗎?……不。

Linux 發行版是持續整合和交付的巨大挑戰

吸引我進入開源領域的一直是這種整合挑戰,有無數不協調的專案,這真的是一個進化的驚人的例子。眯起你的雙眼,你幾乎可以看到奇怪的生物體,突變、微觀世界和自然選擇都發生在你的面前。

在過去的 20 年裡,我為 100 多個不同的開源專案做了貢獻。我的貢獻集中在讓各個專案無縫地在一起執行,這樣使用者就可以有一個連貫的使用體驗。

Cockpit 專案 就是最明顯的例子。我們將大約 95 個獨立開發的 Linux API 和元件整合在一起,在 10 多個不同的發行版中以不同的時間表釋出,在六年內每隔一週釋出一次穩定的版本。

如果說 Linux 是持續整合和交付的巨大挑戰,那麼我認為 RHEL 絕對是挑戰之最:包含上萬個未經協調的專案、數千名貢獻者、新增額外的架構(比如 kABI)和額外的保障(諸如 10+3 的週期),不斷地整合它們,每天交付一個穩定的版本。

我們用夢幻般的(嗯,水汪汪的)眼睛,稱這種努力為“隨時就緒的 RHEL”。

這項工作開始艱苦地將數千個軟體包整合到持續整合中。讓很多人震驚的是,在 2017 年的時候我們並沒有針對所有的 RHEL 元件進行持續整合。如果這很容易的話,就應該更早做到。

目前,任何進入到 RHEL 中的更新都必須先透過 “持續整合閘門Continuous Integration Gating[註釋 1],然後才能進入我們的每夜組合Nightly Compose,它會為這些元件執行自動測試。在每夜構建Nightly Builds之前,每一個變更都需要經過 RHEL 質量(主要由紅帽的 QE 團隊)的明確驗證。

“隨時就緒的 RHEL”的工作現在持續進行並持續交付,你現在可以把它稱為 CentOS Stream:RHEL 每夜組合已經在 CentOS Stream 中交付。持續交付的全部目的是為了每一次版本的釋出都像之前一樣穩定。我們每天都在交付。

我們結束了麼?……並沒有。

註釋 1

這裡需要簡單介紹一下紅帽 RHEL 的開發過程的變化,在 CentOS Stream 之前,RHEL 用的還是傳統的瀑布式開發模式,當一個合併請求Merge Request進來,稽核透過以後,需要把這個補丁提交到發行版的程式碼倉庫,進入到組合階段再進行測試,如果失敗需要重新進行測試和驗證,如下圖所示。

CentOS Stream 是穩定的

在以前這個週期會很長,原因在於 Linux 作業系統會包含數千個軟體包,傳統模式下,都是每隔固定的時間,將積累下來多次提交的程式碼集中進行組合。如果順利透過還好,如果失敗就需要將失敗的部分返工,而其他的相關的元件需要等失敗的元件提交新的補丁以後重新再次進行組合。

因此,其他測試透過的專案的開發者有可能會在很長一段時間後,為了配合測試失敗的專案的程式碼更改,不得不從正在進行的其他工作中抽身出來,重新返工修改自己那部分的程式碼,開發人員通常都需要並行處理很多工作,打斷正在進行的工作是效率非常低下的行為;此外,為了配合測試,有可能還需要重新搭建測試環境;並且,作業系統最終釋出之前,多個專案之間也需要相互等待,彼此之間的協調性很差。所有這些都會對發行版的釋出進度造成延誤,在過去這樣一個測試周期往往需要耗時 2~3 個月。

縮短這個週期最好的辦法就是在補丁進入發行版程式碼庫之前就完成補丁的測試工作,測試透過以後再提交到發行版程式碼倉庫,完成發行版整體的組合工作和確認。在這種模式下,測試範圍縮小到具體的某個軟體包,也只會涉及到與之有關的開發人員,這就大大的提升了工作效率。

在對作業系統進行持續整合的關鍵在於,需要有一種控制機制,能夠鑑別每個專案提交的程式碼在執行了 CI 系統的測試以後,能夠根據測試結果判斷這些程式碼是否可以進入到最終的發行版程式碼樹中。這就是閘門的作用,當測試失敗的時候,CI 系統可以防止這個中斷影響到其他的包。它就像是機場或者火車站的驗票口一樣,只有持有有效票據的人才可以透過,對於程式碼來說,透過閘門的唯一途徑就是拿到透過 CI 測試的結果。之後,就可以入庫並進入到映象打包的階段。

CentOS Stream 是穩定的

基於測試結果,閘門可以根據開發者事先的定義,引導透過測試的程式碼進入到不同的程式碼倉庫,比如測試版程式碼倉庫或者是穩定版程式碼倉庫。

CentOS Stream 是穩定的

以 RHEL 8 為例,已經實現了大部分作業系統的構建打包過程的 CI/CD。如下圖所示,在圖中實線是還需要人手工參與的部分,而虛線是已經實現了自動化的部分。因此以 CI/CD 的方式開發作業系統是“隨時就緒的 RHEL”的基礎。

CentOS Stream 是穩定的

對多數人來說,CentOS Stream 已經和 RHEL 一樣穩定!

但是這裡的挑戰是空前的,RHEL 的工程師們已經意識到了這一點。不同團隊在整合 RHEL 的工作方式上與上游社群本身一樣多樣化,然而因為有這麼多人在一起迭代來實現這個目標的不同方面,我相信我們是可以實現持續交付的。

圖片由 CC-SA 授權

這是版本 8 和 9 的交付流程:可以看到左側是 Fedora 的釋出。這張圖說明了 CentOS Stream 是如何等同於 RHEL X.Y 版本的[註釋 2]。從技術上來講,CentOS Stream 和 RHEL 的更新是編譯自同一套原始碼的兩套二進位制軟體包。因此,當且僅當一個更新被髮布到 RHEL 的每夜構建時,該更新才會被髮布到 CentOS Stream 中。因此,RHEL 的每夜構建也是你獲得的 CentOS Stream 的更新。一旦我們從 Fedora 構建了分支,我們的開發就會按照 RHEL 的產品開發節奏來進行,即:每一個變更都會經歷完整的 RHEL 質量保證的測試流程,每一次變更都要在之前的變更基礎之上疊加。當且僅當更新被髮布到未釋出的 RHEL 的小版本更新中以後,這個更新才會推送到 CentOS Stream 中。這些更新就是紅帽客戶在未來看到的 RHEL 的勘誤更新。

這些變更中的每一個,無論是 Bug 修復還是新增的功能特性,在 CentOS Stream 中落地之前,都會透過自動化測試進行測試,並透過 QE 流程進行驗證。

CentOS Stream 中唯一不能直接和立即看到的是我們在已經發布的 RHEL 的小版本擴充套件升級(EUS)[註釋 3]中做的工作(即上圖中顯示的 “RHEL X.Y Errata”)。這項工作通常是在 NDA 下完成的,是禁止公開的[註釋 4],或者是已經在 CentOS Stream 中被向後移植的程式碼工作[註釋 5]

註釋 2

下圖是 CentOS Stream 和 RHEL 的開發流程,兩個發行版的原始碼都是來自同一個原始碼庫。當有拉取請求進來,被專案負責人批准以後,會分別進到 CentOS Stream 和 RHEL 的發行版程式碼庫;觸發構建操作,根據不同的版本打上不同的標籤,CentOS Stream 會被打上 koji 標籤,而 RHEL 會打上 brew 標籤;同樣的程式碼只有同時透過了 CentOS Stream 和 RHEL 的測試流程,閘門才會開啟並讓程式碼進入到下一個候選環節;在候選環節會做程式碼的驗證,同樣的,CentOS Stream 和 RHEL 中的程式碼都必須透過驗證,才可以進入到發行版的組合階段。

CentOS Stream 是穩定的

因此,從開發流程上看 CentOS Stream 和 RHEL,雖然可能在測試用例和規則上不同,但是考核的標準是“與”的關係,因此穩定性是一致的。

註釋 3

在 RHEL 的每一個大版本中會有很多小的升級版本,比如 RHEL 7、RHEL 8 是大版本,而對應的像 RHEL 7.6、RHEL 8.4 這樣的是 7 系列和 8 系列裡對應的小版本。紅帽內部稱這種小版本為 RHEL X.Y。

在預設情況下,如果我們透過紅帽官網線上升級以後,永遠只能是獲得大版本里最新的版本。比如,你現在有臺系統的版本是 RHEL 8.2,而假設現在 8 系列最新的版本是 8.5,那麼透過 dnf update 升級以後,你被升級的系統版本將是 8.5。這通常不會有什麼問題,然而對於一些有特殊要求的客戶,比如有版本基線管理要求的,或者是出於特殊的相容性穩定性考慮的客戶,是不希望看到作業系統版本因為打補丁發生變化的。

針對這種需求,紅帽有 EUS Addon 服務(即文中提到的 RHEL X.Y Errata,在紅帽也被稱為 RHEL X.Y.Z),如果有了 EUS  訂閱,就可以把系統註冊到某個小的升級版本,比如 RHEL8.2,因為 EUS 的生命週期是小版本釋出之後維持 2 年,從下圖可以看到,在 2022 年年中以前,RHEL 8.2 EUS 的生命週期結束之前,系統透過網路線上升級是可以一直停留在 RHEL8.2 這個版本的,之後你可以選擇跳躍到下一個 EUS 版本,比如 8.6。

CentOS Stream 是穩定的

針對 EUS,紅帽會向後移植主線版本中的紅帽定義的級別為關鍵Critical重要Important的安全勘誤公告(RHSA),以及紅帽選擇的優先順序為“緊急Urgent”的程式漏洞修復公告(RHBA)。其他勘誤公告可根據具體情況釋出。

因為 CentOS Stream 只有一個主線版本,沒有小的升級版本,也沒有 EUS 的服務,因此作者在其博文中說:“Stream 中唯一不能直接和立即看到的是我們在已經發布的 RHEL 的小版本擴充套件升級(EUS)中做的工作(即上圖中顯示 RHEL X.Y Errata)”。

註釋 4

關於上文中提到的“不能被立即檢視需要簽署 NDA 以及禁止公開”的原因在於:修復安全相關等問題時,如果這些漏洞是社群未知的漏洞,出於對終端使用者的保護,在修復補丁正式釋出之前,紅帽不會公開相關資訊,以避免被別有用心的人利用。這些資訊在紅帽正式釋出補丁之前,只能在和紅帽簽署了 NDA 的合作伙伴內部共享,在補丁釋出之後紅帽會公開補丁的詳細內容。

註釋 5

對於 RHEL 的小版本,在下一個小的升級版本釋出之前會作為主線與 CentOS Stream 保持一致,但是當新的小版本釋出以後,如果上一個小版本屬於有 EUS 服務支援的,那麼從這個時間點開始,上一個小版本將進入到 EUS 程式碼分支中。

以 RHEL 8.2 為例,它在 2020 年年底進入到 EUS 階段。假設 2021 年在 CentOS Stream 8 和 RHEL 8 中向後移植了一個上游社群的一個重要更新,紅帽也會將這個更新向後移植到 8.2,但是 8.2 的這個向後移植的操作在 CentOS Stream 中就體現不出來了,或者說從 CI 角度來看,這個向後移植操作與 CentOS Stream 的 CI 沒有直接關係。

CentOS Stream 旨在和 RHEL 一樣穩定,這是持續交付的基礎!

但是,即使是 RHEL 釋出的產品也不是完全穩定的。早在 2020 年 7 月,RHEL(和 CentOS)修復了“boot hole”漏洞,這個修復的結果比這個 CVE 本身 糟糕的多:它導致了許多系統無法啟動。

因此,我們不僅在再加工上游元件上投入了時間,還調整了流程(譯者注:即指 CI/CD 流程),以確保這種情況不會再次發生。並不斷梳理,迭代。

雖然我沒有參與結束 CentOS Linux 8 生命週期結束的決定,但我致力於努力推動 CentOS Stream 的發展。更重要的是,它使得 RHEL 開發過程開放給公眾:在這裡,我們可以與整個生態系統一起應對這一令人興奮的持續整合和交付的挑戰。

將一個產品開源是很難的,但是我們取得了驚人的進步。截止目前為止,我們已經將 RHEL 的開發過程與 Fedora 保持一致,將 RHEL 的所有實際的原始碼放在一個 可讀取的位置,讓貢獻者能夠針對 RHEL 的任何部分開啟一個 拉取請求,並且可以“早釋出”和“勤釋出”。

這只是個開始,數以百計的人都在為 CentOS Stream 的改變而努力,同時不遺餘力的交付您所期待的 RHEL 版本。

CentOS Stream 是 RHEL 穩定可靠的持續交付產品。

相關文章