在現代雲端環境中,伺服器映像檔已成為基礎設施即程式碼的核心元件。相較於即時複製現有伺服器或使用快照,從精心管理的伺服器映像檔建立的執行個體更為乾淨與一致。本文將探討如何有效地建立、管理和佈署伺服器映像檔,以實作真正的基礎設施即程式碼。
伺服器映像檔建置方法的選擇
建立伺服器映像檔主要有兩種方法:線上建置和離線建置。每種方法各有優缺點,適用於不同的場景。
線上映像檔建置:直觀但較慢
線上建置是最常見與直觀的方法,流程包括:
- 建立並設定新的伺服器執行個體
- 將設定完成的執行個體轉換為映像檔
這種方法的優點是實作簡單,但缺點是速度較慢,通常需要數分鐘到數十分鐘才能完成整個過程。
離線映像檔建置:快速但較複雜
離線建置則是:
- 掛載磁碟區
- 複製必要檔案到磁碟區
- 將磁碟區轉換為可開機映像檔
離線建置通常更快,但需要更多技術工作和專業知識。
兩種方法的選擇主要取決於團隊對速度和簡易性的需求平衡。在深入討論實作細節前,讓我們先了解一些建置伺服器映像檔的工具。
伺服器映像檔建置工具概覽
伺服器映像檔建置工具通常透過協調以下流程工作:
- 建立伺服器執行個體或磁碟區
- 執行伺服器設定工具或指令碼進行客製化
- 使用基礎設施平台API將伺服器執行個體轉換為映像檔
主流映像檔建置工具
目前市場上有幾種主要的映像檔建置工具:
HashiCorp Packer:目前最受歡迎的映像檔建置工具,支援多種作業系統和基礎設施平台。
Netflix Aminator:Netflix開放原始碼的工具,專為AWS EC2上的CentOS和Red Hat映像檔設計。
雲端平台原生服務:如AWS Image Builder和Azure Image Builder等。
這些工具都能將映像檔建置過程定義為程式碼,符合基礎設施即程式碼的理念。接下來,讓我們探討線上建置映像檔的流程。
線上映像檔建置流程詳解
線上建置伺服器映像檔的流程包括啟動新的伺服器執行個體、設定它,然後將其轉換為映像檔格式。
從原始映像檔啟動
線上建置的第一步是從原始映像檔啟動新的伺服器執行個體。以下是一個簡化的映像檔建置程式碼範例:
image:
name: shopspinner-linux-image
platform: fictional-cloud-service
origin: fci-12345678
region: europe
instance_size: small
這段程式碼定義了一個名為shopspinner-linux-image
的映像檔建置任務。它使用ID為fci-12345678
的現有映像檔作為起點,這通常是雲端供應商提供的標準Linux發行版。程式碼還指定了建置執行個體的區域和大小。如果沒有指定任何設定動作,結果映像檔將基本上是原始映像檔的複製品。
建置執行個體的基礎設施資源
為映像檔建置執行個體提供適當的基礎設施資源非常重要。以下是一個擴充套件的範例:
image:
name: shopspinner-linux-image
origin: fci-12345678
region: europe
size: small
subnet: ${IMAGE_BUILDER_SUBNET_ID}
ssh_key: ${IMAGE_BUILDER_SSH_KEY}
這個範例增加了子網路ID和SSH金鑰引數,這些值可以動態生成並傳遞給映像檔建置工具。理想的做法是為映像檔建置建立一次性的基礎設施,並在建置完成後銷毀它,以確保安全性。
建置執行個體應該只有最低限度的資源和存取許可權:
- 只允許伺服器佈建工具的入站存取
- 只允許下載套件和設定所需的出站存取
設定建置執行個體
一旦伺服器執行個體執行,就可以應用伺服器設定。大多數映像檔建置工具支援執行常見的伺服器設定工具。以下是使用假設的Servermaker工具設定執行個體的範例:
image:
name: shopspinner-linux-image
origin: fci-12345678
region: europe
instance_size: small
subnet: ${IMAGE_BUILDER_SUBNET_ID}
configure:
tool: servermaker
code_repo: servermaker.shopspinner.xyz
server_role: appserver
這段程式碼應用了一個伺服器角色appserver
,可能會安裝應用伺服器和相關元素。這種方法與伺服器角色的概念相結合,使團隊能夠標準化不同型別的伺服器設定。
使用簡單指令碼建置映像檔
對於那些偏好更完整烘焙映像檔的團隊,完整的伺服器設定工具可能過於複雜。由於每次建置映像檔時通常都是從已知、一致的原始來源開始,因此更簡單的指令碼語言可能更合適,例如Bash、批次指令碼或PowerShell。
以下是使用shell指令碼建置映像檔的範例:
image:
name: shopspinner-linux-image
origin: fci-12345678
configure:
commands:
- 10-install-monitoring-agent.sh
- 20-install-jdk.sh
- 30-install-tomcat.sh
這個範例使用簡單的shell指令碼來設定映像檔。指令碼以數字字首命名,清楚表明執行順序。每個指令碼專注於單一任務,而不是使用條件迴圈的大型複雜指令碼,這種方法更易於維護和理解。
離線映像檔建置流程詳解
線上建置映像檔的過程可能很慢。離線建置提供了一種更快的替代方案。
離線建置的工作原理
離線建置流程如下:
- 將可掛載的映像檔作為磁碟區掛載
- 設定磁碟區上的檔案
- 解除安裝磁碟區並將其轉換為映像檔格式
這種方法通常比線上建置快得多,但需要更多的技術工作。
離線建置的技術挑戰
離線建置面臨的主要挑戰是如何正確設定磁碟區。伺服器設定工具通常應用於它們正在執行的伺服器執行個體。即使是簡單的shell指令碼,也經常執行套件安裝程式,預設情況下會在執行伺服器的檔案系統中安裝檔案。
有兩種主要方法可以解決這個問題:
使用安裝路徑選項:許多工具有命令列或設定選項,可以設定為將檔案安裝到不同的路徑。例如:
yum install --prefix /mnt/image_builder/ java
使用chroot命令:chroot命令可以使用不同的檔案系統根目錄執行命令:
chroot /mnt/image_builder/ yum install java
chroot方法的優勢在於它適用於任何工具或命令。流行的映像檔建置工具如Packer內建支援chroot功能。
伺服器映像檔的原始內容
建置伺服器映像檔時,有幾個元素需要考慮:
映像檔建置程式碼:定義映像檔的程式碼,如Packer範本檔案。
原始來源映像檔:可能是平台格式的來源映像檔(如AMI)、作業系統安裝映像檔(如ISO映像檔)或從頭開始建置。
伺服器設定程式碼:用於自訂映像檔的伺服器設定工具或指令碼。
其他伺服器元素:可能包括來自公共或內部儲存函式庫的套件。
從現成伺服器映像檔建置
基礎設施平台供應商、作業系統供應商和開放原始碼專案通常會建置伺服器映像檔並提供給使用者。這些現成映像檔通常是建置自己映像檔的良好起點。
然而,許多現成映像檔都過度佈建,安裝了各種工具和套件。為了安全性和效能,應該最小化自訂伺服器映像檔上安裝的內容。
有兩種方法可以解決這個問題:
- 在伺服器映像檔設定過程中移除不需要的內容
- 尋找更小的原始映像檔,如JEOS(Just Enough Operating System)映像檔
從頭開始建置伺服器映像檔
如果使用內部雲端或虛擬化平台,可能沒有現成的映像檔可用。或者,團隊可能不想使用現成映像檔。替代方案是從頭開始建置自訂伺服器映像檔。
作業系統安裝映像檔提供了一個乾淨、一致的起點。映像檔建置過程從作業系統映像檔啟動伺服器執行個體並執行指令碼化安裝過程開始。
伺服器映像檔及其內容的來源
使用第三方映像檔時,需要考慮其來源和安全性。一些需要考慮的問題:
- 映像檔和套件是否包含已知漏洞?
- 供應商採取哪些步驟來掃描程式碼潛在問題?
- 如何確保包含的軟體或工具不會以違反組織政策或當地法律的方式收集資料?
- 供應商使用什麼流程來檢測和防止非法篡改?
不應完全信任來自供應商或第三方的內容,應該實施自己的檢查。在映像檔的管道中建立檢查是一個好方法。
伺服器映像檔的更新與管理
隨著時間推移,伺服器映像檔會變得過時,因為會發布更新的套件和設定。雖然可以在每次建立新伺服器時應用修補程式和更新,但這個過程會隨著時間的推移而變得更長,降低了使用伺服器映像檔的好處。定期更新映像檔可以保持一切順暢執行。
重新加熱或重新烘焙映像檔
當需要建置伺服器映像檔的新版本時(例如,更新最新的作業系統修補程式),可以使用與建置第一個版本相同的工具和流程。
有兩種主要方法:
重新加熱映像檔:使用先前版本的映像檔作為原始來源映像檔。這確保新版本與先前版本一致,因為唯一的變更是在應用伺服器設定時明確進行的變更。
重新烘焙映像檔:從原始來源重新建置新版本的映像檔。這種方法可能更乾淨,更可靠地可重現,因為它不包含先前建置可能留下的任何內容。
例如,如果伺服器設定安裝了一個後來決定移除的套件,如果重新加熱映像檔,該套件仍會存在於較新的伺服器映像檔中,需要增加程式碼來明確移除它。如果每次都重新烘焙映像檔,該套件將不會存在於較新的伺服器映像檔中,因此不需要編寫任何程式碼來移除它。
伺服器映像檔的版本控制
對於使用伺服器映像檔和從中建立的伺服器的每個人來説,能夠追蹤版本至關重要。他們應該能夠瞭解:
- 用於建立任何給定伺服器執行個體的版本
- 給定映像檔的最新版本
- 用於建立映像檔的來源內容和設定程式碼
許多團隊使用不同的伺服器映像檔。例如,可能為應用伺服器、容器主機節點和通用Linux作業系統映像檔建置單獨的映像檔。在這種情況下,每個映像檔都作為單獨的元件進行管理,各自有單獨的版本歷史記錄。
大多數基礎設施平台不直接支援伺服器映像檔的版本編號。在許多情況下,可以在伺服器映像檔的名稱中嵌入版本號。例如,可能有名為appserver-3
、basic-linux-2
和container-node-3
的映像檔。
另一個選項是在標籤中放置版本號和映像檔名稱(如果平台支援)。映像檔可以有一個名為Name=appserver
的標籤和另一個名為Version=3
的標籤。
使用最容易搜尋、發現和報告映像檔名稱和版本的機制。大多數團隊同時使用這兩種方法,因為標籤易於搜尋,而名稱易於人類檢視。
可以使用不同的版本編號方案。語義版本控制是一種流行的方法,使用三部分版本號(如1.0.4)的不同欄位來指示從一個版本到下一個版本的變更有多重要。我喜歡在版本中增加日期和時間戳(例如,1.0.4-20200229_0420),以便輕鬆檢視特定版本的建置時間。
除了在伺服器映像檔本身上放置版本號外,還可以使用於建立它的伺服器映像檔名稱和版本標記或標籤伺服器執行個體。這樣可以將每個執行個體映射回用於建立它的映像檔,這對於推出新的映像檔版本很有用。
映像檔變更時的伺服器執行個體更新策略
當建置新版本的伺服器映像檔時,可以選擇替換所有根據該映像檔的伺服器執行個體,或等待它們隨著時間自然替換。
主動替換策略
重建現有伺服器以替換舊映像檔版本的政策可能具有破壞性與耗時。但它也確保了伺服器的一致性,並持續鍛煉系統的彈性。良好的管道使這個過程更容易管理,而零停機時間變更使其不那麼具有破壞性。因此,許多具有成熟和普遍自動化的團隊都喜歡這種政策。
被動替換策略
當伺服器因其他原因重建時,等待用新映像檔版本替換伺服器更容易。如果透過重建伺服器執行個體來佈署軟體更新或其他變更,這可能是這種情況。
等待用新映像檔版本更新伺服器的缺點是這可能需要一段時間,並使您的環境中有從各種映像檔版本建置的伺服器。
這種情況會造成不一致。例如,可能有具有不同版本的作業系統套件更新和設定的應用伺服器,導致神秘的不一致行為。在某些情況下,較舊的映像檔版本和從中建置的伺服器可能存在安全漏洞或其他問題。
混合策略與監控
有幾種策略可以緩解這些問題。一種是根據用於建立它們的映像檔版本追蹤執行的執行個體。這可以是儀錶板或報告,顯示每個映像檔版本的執行個體數量。
如果這些訊息隨時可用,並且可以深入檢視特定伺服器的列表,那麼可以識別迫切需要重建的伺服器執行個體。例如,如果發現Linux發行版最新更新中修復的安全漏洞,並在映像檔中包含了該修補程式,報告會顯示需要重建多少伺服器執行個體。
還可以設定年齡限制。例如,可以制定一項政策,替換任何從超過三個月的伺服器映像檔建置的執行伺服器執行個體。報告或儀錶板應顯示超過此日期的執行個體數量。
跨團隊提供和使用伺服器映像檔
在許多組織中,中央團隊建置伺服器映像檔並使其可供其他團隊使用。這種情況為管理伺服器映像檔更新增加了一些複雜性。
版本相容性挑戰
使用映像檔的團隊需要確保它已準備好使用映像檔的新版本。例如,內部應用團隊可能在計算團隊提供的基本Linux映像檔上安裝錯誤追蹤軟體。計算團隊可能會生成一個具有與錯誤追蹤軟體不相容的更新的基本Linux映像檔的新版本。
理想情況下,伺服器映像檔會進入每個團隊的基礎設施管道。當擁有映像檔的團隊透過其管道發布新版本時,每個團隊的基礎設施管道會提取該版本並更新其伺服器執行個體。內部團隊的管道應該在重建其使用者依賴的伺服器之前,自動測試錯誤追蹤軟體是否與新映像檔版本一起工作。
版本固定策略
一些團隊可能採取更保守的方法,固定他們使用的映像檔版本號。內部應用團隊可以將其基礎設施固定為使用基本Linux映像檔的版本1。當計算團隊發布映像檔的版本2時,內部應用團隊繼續使用版本1,直到他們準備好測試和推出版本2。
許多團隊在測試和交付伺服器基礎設施變更的自動化不夠成熟時使用固定方法。這些團隊需要做更多的手動工作來確保映像檔變更。
即使有成熟的自動化,一些團隊也會固定變更風險較高的映像檔(和其他依賴項)。依賴項可能更脆弱,因為團隊佈署到映像檔上的軟體對作業系統的變更敏感。或者提供映像檔的團隊(可能是外部團隊)有發布有問題版本的記錄,因此信任度低。
處理映像檔的重大變更
對伺服器映像檔的一些變更為重要,因此更可能需要手動努力來測試和修改下游依賴項。例如,應用伺服器映像檔的新版本可能包括應用伺服器軟體的主要版本升級。
語義版本控制的應用
可以使用語義版本控制來指示它是一個更重要的變更,或者甚至完全建置不同的伺服器映像檔。
當使用語義版本控制時,大多數變更會增加版本的最低位數,例如,從1.2.5到1.2.6。透過增加第二位或第一位數字來指示重大變更。對於不應該為應用程式建立相容性問題的次要應用伺服器軟體更新,可能會將伺服器映像檔的版本1.2.6增加到1.3.0。對於可能破壞應用程式的重大變更,增加最高位數,因此1.3.0將被替換為2.0.0。
建立全新映像檔
在某些情況下,特別是當預期團隊會使用較舊的映像檔版本一段時間時,可能會完全建立一個新映像檔。例如,如果基本Linux映像檔使用Centos 9.x,但想開始測試和推出Centos 10.x,而不是增加映像檔的版本號,可以建立一個新映像檔,basic-linux10-1.0.0。這使得遷移到新的作業系統版本比例行映像檔更新更明確的任務。
伺服器映像檔是現代基礎設施即程式碼實踐的核心元件。透過選擇適當的建置方法、工具和管理策略,團隊可以實作更高效、更一致的基礎設施佈署。
無論選擇線上還是離線建置方法,重要的是要建立清晰的版本控制策略,並制定適當的執行個體更新計劃。對於跨團隊協作,明確的版本相容性測試和溝通至關重要。
透過將伺服器映像檔納入自動化管道,團隊可以確保基礎設施的一致性、安全性和可靠性,同時減少手動工作和人為錯誤的風險。隨著組織的成熟,伺服器映像檔管理策略也應該演進,以支援更快速、更可靠的基礎設施變更。