容器化應用程式開發過程中,選擇合適的基礎映像檔至關重要。這不僅影回應用程式的效能和大小,更直接關係到應用程式的安全性與穩定性。本文從 Open Container Initiative (OCI) 映像檔格式出發,解析容器映像檔的組成與規範,接著探討 Docker Hub、Quay 和 Red Hat 生態系統目錄等主流容器映像檔來源,比較它們的特性與安全性。最後,文章著重介紹了 Universal Base Image (UBI) 的優勢以及如何管理可信任的登入中心,以構建更安全的容器化環境。
選擇容器基礎映像檔
在前面的章節中,我們已經瞭解瞭如何使用預先建置的容器映像檔來快速學習和獲得容器經驗。在探討容器管理後,我們發現有時可用的服務、其組態或甚至應用程式版本並不符合專案需求。因此,我們引入了Buildah及其用於建置自定義容器映像檔的功能。在本章中,我們將討論在社群和企業專案中經常被質疑的另一個重要課題:選擇容器基礎映像檔。
選擇正確的容器基礎映像檔是容器旅程中的重要任務:容器基礎映像檔是我們的系統服務、應用程式或程式碼所依賴的底層作業系統層。因此,我們應該根據最佳實踐選擇一個符合安全性和更新需求的映像檔。
在本章中,我們將涵蓋以下主要主題:
- Open Container Initiative 映像檔格式
- 容器映像檔的來源
- 可信賴的容器映像檔來源
- 介紹 Universal Base Image
技術需求
要完成本章,您需要一台安裝了Podman的機器。如同第三章「執行第一個容器」所述,本文中的所有範例都是在Fedora 34系統或更高版本上執行的,但可以在您選擇的作業系統上重現。
對第四章「管理執行中的容器」中涵蓋的主題有良好的理解,將有助於您輕鬆掌握有關容器映像檔的概念。
Open Container Initiative 映像檔格式
正如我們在第一章「容器技術簡介」中所述,早在2013年,Docker就被引入容器領域,並迅速變得非常流行。
在高層次上,Docker團隊引入了容器映像檔和容器登入的概念,這是一個遊戲規則的改變者。另一個重要的步驟是能夠從Docker中提取containerd專案並將其捐贈給Cloud Native Computing Foundation(CNCF)。這促使開源社群開始認真研究可以注入到諸如Kubernetes之類別的協調層中的容器引擎。
同樣,在2015年,Docker在許多其他公司(Red Hat、AWS、Google、Microsoft、IBM等)的幫助下,在Linux Foundation的支援下啟動了Open Container Initiative(OCI)。
這些貢獻者開發了Runtime Specification(runtime-spec)和Image Specification(image-spec),以描述未來新容器引擎的API和架構應該如何建立。
經過幾個月的努力,OCI團隊發布了其第一個符合OCI規範的容器引擎實作;該專案被命名為runc。
值得詳細檢視容器映像檔規範,並回顧我們在第二章「比較Podman和Docker」中介紹的一些理論。
該規範定義了一個OCI容器映像檔,它由以下部分組成:
- 清單(Manifest):這包含映像檔內容和依賴項的元資料。這也包括識別一個或多個檔案系統存檔的功能,這些存檔將被解壓縮以取得最終的可執行檔案系統。
// 使用buildah_rs函式庫建立一個新的容器映像檔
use buildah_rs::container::Container;
fn main() {
// 從nginx:1.21建立一個新的容器
let mut container = Container::from("nginx:1.21");
// 將本地html目錄複製到容器映像檔中的/usr/share/nginx/html
container.copy("html", "/usr/share/nginx/html").unwrap();
// 提交更改並建立一個名為nginx_rust的新容器映像檔
container.commit("nginx_rust").unwrap();
}
內容解密:
上述程式碼展示瞭如何使用Rust語言中的buildah_rs函式庫來建立一個新的容器映像檔。首先,我們從nginx:1.21建立一個新的容器。然後,我們將本地html目錄複製到容器映像檔中的/usr/share/nginx/html。最後,我們提交更改並建立一個名為nginx_rust的新容器映像檔。
這個範例演示瞭如何使用Buildah和Rust來建立自定義的容器映像檔。我們可以根據自己的需求修改這個範例,例如更改基礎映像檔、複製不同的檔案或目錄等。
可信賴的容器映像檔來源
在選擇容器基礎映像檔時,我們需要考慮安全性、穩定性和更新等因素。因此,選擇可信賴的容器映像檔來源非常重要。
一些流行的可信賴容器映像檔來源包括:
- Docker Hub
- Red Hat Quay
- Google Container Registry
- Amazon Elastic Container Registry
這些來源提供了大量的官方和社群維護的映像檔,可以滿足不同的需求。
Universal Base Image
Universal Base Image(UBI)是Red Hat提供的一個特殊的容器基礎映像檔。它旨在提供一個穩定、安全和可預測的基礎,用於建置應用程式容器。
UBI具有以下特點:
- 穩定性:UBI根據Red Hat Enterprise Linux(RHEL),提供了穩定的基礎。
- 安全性:UBI包含了最新的安全更新和修復。
- 可預測性:UBI提供了可預測的行為和相容性。
總之,選擇正確的容器基礎映像檔對於確保容器的安全性和穩定性至關重要。透過瞭解OCI映像檔格式、可信賴的容器映像檔來源和UBI,我們可以做出明智的選擇,以滿足我們的專案需求。
深入理解OCI映像檔格式與容器映像檔來源
OCI映像檔格式解析
Open Container Initiative(OCI)映像檔格式是容器技術中的核心標準之一,它定義了容器映像檔的結構和內容。OCI映像檔格式主要包含以下幾個關鍵元素:
- 映像檔索引(Image Index):這是一個可選的元素,提供不同平台下的映像檔實作。
- 檔案系統層(Filesystem Layers):這是構成容器最終檔案系統的實際層集合。
- 組態(Configuration):包含執行應用程式所需的資訊,如引數、環境變數等。
OCI映像檔清單(Image Manifest)
OCI映像檔清單定義了單一容器映像檔的層和組態,適用於特定的架構和作業系統。以下是一個OCI映像檔清單的範例:
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
"digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7"
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 32654,
"digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0"
}
],
"annotations": {
"com.example.key1": "value1",
"com.example.key2": "value2"
}
}
內容解密:
schemaVersion:此屬性必須設為2,以確保與Docker的向後相容性。config:此屬性透過摘要(digest)參照容器的組態。mediaType:定義實際的組態格式,目前僅有一種格式。
layers:提供一個描述符物件陣列。mediaType:描述符應該是層描述符允許的媒體型別之一。
annotations:為映像檔清單定義額外的元資料。
OCI映像檔清單的主要目標是實作容器映像檔的互操作性工具,用於建置、傳輸和準備容器映像檔以供執行。
容器映像檔的來源
在前面的章節中,我們使用了預先建置的映像檔來執行、建置或管理容器,但這些容器映像檔究竟從何而來?
容器註冊中心
Docker引入了容器映像檔和容器註冊中心的概念,用於儲存這些映像檔,甚至是公開儲存。最著名的容器註冊中心是Docker Hub,但Docker之後,其他雲端容器註冊中心也相繼推出。
我們可以在以下雲端容器註冊中心之間進行選擇:
- Docker Hub:由Docker公司提供的託管註冊中心解決方案,也託管了一些流行的開源專案的官方倉函式庫和安全驗證映像檔。
- Quay:最初由CoreOS公司開發,現屬於Red Hat。它提供私有和公有倉函式庫、自動安全掃描、映像檔建置以及與流行的Git公有倉函式庫的整合。
- Linux發行版註冊中心:流行的Linux發行版通常提供公有容器註冊中心,但這些註冊中心通常只適用於已經作為系統套件提供的專案或套件。
- 公有雲註冊中心:Amazon、Google、Microsoft等公有雲提供商為其客戶提供私有的容器註冊中心。
Docker Hub容器註冊中心服務
Docker Hub是最著名的容器註冊中心服務。它託管了多個社群和企業產品的容器映像檔。
透過檢視容器映像檔的詳細頁面,我們可以輕鬆發現有關該專案及其容器映像檔的所有必要資訊。下面的截圖顯示了Alpine Linux在Docker Hub上的頁面:
此圖示說明瞭Alpine Linux容器映像檔在Docker Hub上的呈現方式。
內容解密:
- Docker Hub提供了豐富的容器映像檔資源,但下載和執行未經審查的容器映像檔可能存在安全風險。
- 使用者應該檢查映像檔的來源和更新記錄,以確保其安全性和可靠性。
容器映像檔的來源與選擇
容器映像檔是容器技術的核心組成部分,瞭解其來源與選擇方法對於確保容器化應用的安全性和可靠性至關重要。本章節將探討容器映像檔的來源,包括Docker Hub、Quay容器註冊服務以及Red Hat生態系統目錄等,並分析如何選擇合適的容器基礎映像檔。
Docker Hub:容器映像檔的主要來源
Docker Hub是目前最為廣泛使用的容器登入檔,它提供了豐富的容器映像檔資源。在Docker Hub上,使用者可以輕鬆找到官方映像檔以及由社群貢獻的映像檔。官方映像檔是由Docker團隊與上游專案維護者共同維護的,這些映像檔經過嚴格審核,能夠確保其安全性和穩定性。
在Docker Hub的頁面上,使用者可以找到有關映像檔的最新標籤、支援的架構以及相關檔案和問題回報系統的連結。當使用者點選某個映像檔的標籤時,可以檢視用於建立該映像檔的Dockerfile內容。例如,對於Alpine Linux映像檔,使用者可以透過點選標籤20210804, edge來檢視其對應的Dockerfile:https://github.com/alpinelinux/docker-alpine/blob/edge/x86_64/Dockerfile。
Quay容器註冊服務:提供安全掃描功能
Quay是另一個重要的容器註冊服務,它在2014年被CoreOS收購,現已成為Red Hat生態系統的一部分。Quay提供了安全掃描軟體,幫助使用者評估所選容器映像檔的安全性。Quay採用了Clair專案,一款領先的容器漏洞掃描器,在儲存函式庫標籤網頁上顯示掃描報告。
透過Quay,使用者可以點選"Security Scan"來檢查安全掃描的詳細資訊。例如,存取https://quay.io/repository/openshift-release-dev/ocp-release?tab=tags,可以瞭解更多關於該功能的資訊。使用提供安全掃描功能的公共登入檔,有助於確保使用者選擇正確且最安全的容器映像檔。
Red Hat生態系統目錄:綜合性容器登入檔
Red Hat生態系統目錄是Red Hat Enterprise Linux(RHEL)和Red Hat OpenShift Container Platform(OCP)使用者預設的容器登入檔。雖然大多數提供的映像檔是為付費使用者保留的,但其網頁介面對所有使用者開放。該目錄結合了之前提到的所有功能,為使用者提供了以下內容:
- Red Hat官方容器映像檔
- ContainerFile/Dockerfile來源以檢查映像檔內容
- 每個容器映像檔的安全報告(索引)
在Red Hat生態系統目錄的頁面上,使用者可以檢視所選容器映像檔的描述、版本、可用架構以及可供選擇的各種標籤。透過點選"Security"標籤,使用者可以檢視針對該映像檔標籤執行的漏洞掃描狀態。同時,透過點選"Dockerfile"標籤,使用者可以檢視用於建立該容器映像檔的源ContainerFile。
重點觀察:Universal Base Image(UBI)
在Red Hat生態系統目錄中,有一個特殊的容器基礎映像檔值得注意:Universal Base Image(UBI)。UBI是Red Hat推出的一項計畫,允許所有使用者(無論是否為Red Hat客戶)使用Red Hat容器映像檔。這使得Red Hat生態系統得以擴充套件,利用之前提到的所有服務以及直接來自Red Hat的更新套件。
UBI的優勢
- 提供了一個穩定且安全的基礎映像檔
- 允許使用者利用Red Hat的更新套件和安全修復
- 擴充套件了Red Hat生態系統,使其更具吸引力
選擇容器基礎映像檔
可信任的容器映像檔來源
在上一節中,我們定義了映像檔登入(image registry)作為有效、可用的映像檔的真實來源的核心角色。在本文中,我們將強調採用來自可信來源的可信映像檔的重要性。
OCI 映像檔用於將二進位制檔案和執行環境封裝在結構化的檔案系統中,以提供特定的服務。當我們提取該映像檔並在系統上執行它,而沒有任何控制時,我們默默地信任作者沒有透過使用惡意元件竄改其內容。但現在,信任是不能輕易被授予的。
正如我們將在第11章「容器安全」中看到的那樣,有許多攻擊案例和惡意行為可以從容器中進行:特權提升、資料外洩和挖礦只是幾個例子。當在 Kubernetes 叢集(成千上萬個叢集)內執行的容器可以輕易地跨基礎架構產生惡意 Pod 時,這些行為可能會被放大。
為了幫助安全團隊緩解這種情況,MITRE Corporation 定期釋出 MITRE ATT&CK 矩陣,以識別所有可能的攻擊策略及其相關技術,並提供實際案例以及檢測和緩解的最佳實踐。其中一個矩陣專門針對容器,其中許多技術是根據不安全的映像檔實作的,在這些映像檔中可以成功實施惡意行為。
重點提示
您應該優先選擇來自支援漏洞掃描的登入中心的映像檔。如果掃描結果可用,請仔細檢查並避免使用具有關鍵漏洞的映像檔。
考慮到這一點,建立安全的雲原生基礎架構的第一步是什麼?答案是選擇僅來自可信來源的映像檔,而第一步是組態可信的登入中心和模式以阻止不允許的登入中心。我們將在下一小節中介紹這一點。
管理可信登入中心
如第3章「執行第一個容器」中的「準備環境」一節所示,Podman 可以透過設定檔管理可信登入中心。
/etc/containers/registries.conf 設定檔
/etc/containers/registries.conf 檔案(如果存在,則由使用者相關的 $HOME/.config/containers/registries.conf 檔案覆寫)管理 Podman 可以安全接觸以搜尋和提取映像檔的可信登入中心清單。
讓我們看一下這個檔案的例子:
unqualified-search-registries = ["docker.io", "quay.io"]
[[registry]]
location = "registry.example.com:5000"
insecure = false
這個檔案幫助我們定義 Podman 可以使用的可信登入中心,因此值得詳細分析。
Podman 接受不合格和完全合格的映像檔。兩者的區別很簡單,可以說明如下:
- 完全合格的映像檔包括登入伺服器 FQDN、名稱空間、映像檔名稱和標籤。例如,
docker.io/library/nginx:latest是一個完全合格的映像檔。它有一個完整的名稱,不會與其他 Nginx 映像檔混淆。 - 不合格的映像檔只包含映像檔的名稱。例如,
nginx映像檔可以在搜尋的登入中心中擁有多個例項。大多數由基本的podman search nginx命令產生的映像檔不是官方的,應該詳細分析以確保它們是可信的。輸出可以透過OFFICIAL旗標和星級數(越多越好)進行篩選。
登入檔組態檔案的第一個全域設定是 unqualified-search-registry 陣列,它定義了不合格映像檔的登入檔搜尋清單。當使用者執行 podman search <image_name> 命令時,Podman 將在該清單中定義的登入檔中進行搜尋。
透過從清單中刪除登入檔,Podman 將停止搜尋該登入檔。但是,Podman 仍然能夠從外部登入檔中提取完全合格的映像檔。
使用 [[registry]] 表格管理單一登入檔
要管理單一登入檔並為特定映像檔建立匹配模式,我們可以使用 [[registry]] TOML 表格。這些表格的主要設定如下:
prefix:用於定義映像檔名稱,可以支援多種格式。通常,我們可以按照host[:port]/namespace[/namespace...]/repo(:tag|@digest)模式定義映像檔,但也可以套用更簡單的模式,如host[:port]、host[:port]/namespace,甚至[*.]host。按照這種方法,使用者可以為登入檔定義一個通用的字首,也可以定義一個更詳細的字首來匹配特定的映像或標籤。給定一個完全合格的映像,如果兩個[[registry]]表格的字首部分匹配,則將使用最長的匹配模式。insecure:這是一個布林值(true 或 false),允許未加密的 HTTP 連線或根據不受信任憑證的 TLS 連線。blocked:這是一個布林值(true 或 false),用於定義被封鎖的登入檔。如果設為 true,則與字首匹配的登入檔或映像將被封鎖。location:此欄位定義了登入檔的位置。預設情況下,它等於字首,但可以具有不同的值。在這種情況下,與自訂字首名稱空間匹配的模式將解析為位置值。
除了主要 [[registry]] 表格外,我們還可以定義一個 [[registry.mirror]] TOML 表格陣列,以提供到主要登入檔或登入檔名稱空間的其他路徑。
當提供多個映象時,Podman 將首先在它們之間進行搜尋,然後回退到主要 [[registry]] 表格中定義的位置。
下面的例子擴充套件了前面的例子,定義了一個名稱空間登入檔條目及其映象:
unqualified-search-registries = ["docker.io", "quay.io"]
[[registry]]
location = "registry.example.com:5000/foo"
insecure = false
[[registry.mirror]]
location = "mirror1.example.com:5000/bar"
[[registry.mirror]]
location = "mirror2.example.com:5000/bar"
程式碼解密:
此範例展示如何組態 Podman 的登入檔設定檔 /etc/containers/registries.conf。首先,我們設定了 unqualified-search-registries,它定義了搜尋未完全合格映像檔(如 nginx)時要查詢的註冊表列表。這裡指定了 "docker.io" 和 "quay.io" 為預設搜尋位置。
接著,我們使用 [[registry]] 表格來定義特定的登入檔。在這個例子中,登入檔的位置是 "registry.example.com:5000/foo",並且設定為使用安全的連線(insecure = false),表示該登入檔需要使用加密連線(如 HTTPS)進行通訊。
此外,我們還定義了兩個映象(mirror)位置,分別是 "mirror1.example.com:5000/bar" 和 "mirror2.example.com:5000/bar"。當 Podman 需要從 "registry.example.com:5000/foo" 提取映像檔時,它會首先嘗試從這些映象位置取得,如果映象位置不可用或找不到所需的映像檔,才會回退到原始登入檔位置。
這種組態方式提高了系統的可擴充套件性和容錯性,因為它允許多個來源提供相同的內容,從而減少對單一登入檔的依賴,並在原始登入檔不可用時提供備用方案。
重點整理
- 組態可信登入中心和模式以阻止不允許的登入中心,是建立安全的雲原生基礎架構的第一步
- Podman 可以透過設定檔管理可信登入中心,如
/etc/containers/registries.conf - 使用
[[registry]]表格可以管理單一登入檔,並為特定映像建立匹配模式 - 可以定義映象(mirror)位置,以提供到主要登入檔或其他名稱空間的其他路徑,提高系統的可擴充套件性和容錯性