在容器化應用程式中,資料儲存是個不容忽視的議題。容器本身的生命週期是短暫的,如果沒有妥善的儲存機制,容器內的資料將隨著容器的停止而消失。本文將探討 Podman 提供的三種主要儲存方式:Volume、Bind Mount 和 Tmpfs,並分析它們的特性、使用場景和組態方法,幫助你選擇最合適的方案。

Podman 提供了多種儲存管理機制,讓使用者可以根據應用程式的需求選擇最合適的方案。理解這些機制的差異和使用方法,對於構建穩定可靠的容器化應用程式至關重要。podman volume create 指令可以建立一個獨立的 Volume,這個 Volume 與容器的生命週期無關,即使容器停止或刪除,Volume 中的資料依然存在。這對於需要持久化儲存資料的應用程式非常有用。podman run -v 指令可以將主機目錄掛載到容器中,實作資料分享。這種方式稱為 Bind Mount,它允許容器直接存取主機檔案系統,方便開發和除錯。需要注意的是,Bind Mount 的安全性較低,需要謹慎使用。最後,podman run --tmpfs 指令可以建立一個根據記憶體的檔案系統,稱為 Tmpfs。Tmpfs 的讀寫速度非常快,適合儲存臨時檔案或敏感資料。由於 Tmpfs 的資料儲存在記憶體中,因此容器停止後資料將會消失。

Podman容器日誌管理:告別複雜指令,掌握日誌分析技巧

在使用Podman管理容器時,日誌分析是不可或缺的一環。本文將探討如何透過Podman指令輕鬆取得容器日誌,並分享如何設定日誌大小限制,避免日誌檔案過度膨脹。

告別繁瑣:podman logs指令的妙用

過去,要分析容器日誌,可能需要執行一連串複雜的指令。但有了podman logs指令,一切變得簡單許多。例如,要檢視特定容器的日誌,只需執行以下指令:

# podman logs c6afe22eac7c22c35a303d5fed45bc1b6442a4cec4a9060f392362bc4cecb25d
=> sourcing 10-set-mpm.sh ...
=> sourcing 20-copy-config.sh ...
=> sourcing 40-ssl-certs.sh ...
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.9. Set the 'ServerName' directive globally to suppress this message
[Mon Sep 27 15:42:46.996748 2021] [ssl:warn] [pid 1:tid 139708367605120] AH01882: Init: this version of mod_ssl was compiled against a newer library (OpenSSL 1.1.1b FIPS 26 Feb 2019, version currently loaded is OpenSSL 1.1.1 FIPS 11 Sep 2018) - may result in undefined or erroneous behavior
...
[Mon Sep 27 15:42:47.099445 2021] [core:notice] [pid 1:tid 139708367605120] AH00094: Command line: 'httpd -D FOREGROUND'

其中,c6afe22eac7c22c35a303d5fed45bc1b6442a4cec4a9060f392362bc4cecb25d是容器的完整ID。

內容解密:

  • 此指令會直接從容器撈取最新的日誌訊息。
  • 顯示了Apache HTTP Server啟動過程中的日誌輸出。

除了完整ID,你也可以使用容器的短ID來執行podman logs指令:

# podman ps
CONTAINER ID IMAGE                                          COMMAND               CREATED        STATUS        PORTS               NAMES
c6afe22eac7c  registry.fedoraproject.org/f29/httpd:latest  /usr/bin/run-http...  40 minutes ago  Up 40 minutes ago                       gifted_allen
# podman logs --tail 2 c6afe22eac7c
[Mon Sep 27 15:42:47.099403 2021] [mpm_event:notice] [pid 1:tid 139708367605120] AH00489: Apache/2.4.39 (Fedora) OpenSSL/1.1.1 configured -- resuming normal operations
[Mon Sep 27 15:42:47.099445 2021] [core:notice] [pid 1:tid 139708367605120] AH00094: Command line: 'httpd -D FOREGROUND'

內容解密:

  • podman ps 用於列出正在執行的容器,顯示容器ID、映像、狀態等訊息。
  • --tail 2 引數讓 podman logs 只顯示最新的兩行日誌。

精準控制:--tail引數的奧妙

有時候,我們只需要檢視最新的幾行日誌,這時--tail引數就派上用場了。透過指定行數,可以快速定位到關鍵訊息。

日誌瘦身:設定log_size_max引數

預設情況下,Podman儲存的容器日誌大小沒有限制,長期執行的容器可能會產生大量的日誌檔案。為了避免這種情況,可以透過設定log_size_max引數來限制日誌檔案的大小。

首先,編輯Podman的全域設定檔/etc/containers/containers.conf

# vim /etc/containers/containers.conf
[containers]
log_size_max=10000000

內容解密:

  • log_size_max=10000000 表示將每個容器的日誌檔案大小限制為10MB。

請注意: 修改設定後,需要重新啟動容器才能生效。

進階應用:podman exec指令

Podman另一個強大的功能是能夠在正在執行的容器中執行程式。這可以透過podman exec指令實作,對於除錯、測試或與現有容器互動非常有用。

# podman run -d -i -t registry.fedoraproject.org/f29/httpd
47fae73e4811a56d799f258c85bc50262901bec2f9a9cab19c01af89713a1248
# podman exec -ti 47fae73e4811a56d799f258c85bc50262901bec2f9a9cab19c01af89713a1248 /bin/bash
bash-4.4$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
default      1  0.6  0.6  20292 13664 pts/0    Ss+  13:37   0:00 httpd -D FOREGROUND
...

內容解密:

  • 首先,使用 podman run 在後台啟動一個 httpd 容器。
  • 然後,使用 podman exec 連線到正在執行的容器,並啟動一個新的 bash shell。
  • 在容器的 shell 中,可以執行 ps aux 檢視容器內正在執行的行程。

podman exec 指令提供許多選項,類別似於 podman run 指令。例如,-t 選項用於分配一個偽終端,-i 選項用於保持標準輸入流開啟。

容器群組:在 Podman 中駕馭容器協同作戰

在容器管理的旅程中,我們將探討 Podman 提供的強大功能,特別是如何在 Kubernetes 的容器協調世界中實作容器化的工作負載。

從 Docker 到 Podman:邁向 Kubernetes 的第一步

正如我們在《Podman 與 Docker 的比較》一章中所提到的,Podman 提供了一些功能,可以輕鬆地開始採用 Kubernetes 的基本概念。Pod 概念是 Kubernetes 引入的,它代表了 Kubernetes 叢集中最小的執行單元。透過 Podman,使用者可以建立空的 Pod,然後輕鬆地在其中執行容器。

Pod 的優勢:分享資源,協同作戰

將兩個或多個容器組合在一個 Pod 中,可以帶來許多好處,例如:

  • 分享網路名稱空間:包含相同的 IP 位址。
  • 分享儲存卷:用於儲存永續性資料。
  • 分享組態:簡化管理和佈署。

此外,將兩個或多個容器放在同一個 Pod 中,實際上可以讓它們分享相同的程式間通訊(IPC)Linux 名稱空間。這對於需要使用分享記憶體相互通訊的應用程式來說非常有用。

實戰演練:建立與管理 Pod

建立 Pod 並開始使用它的最簡單方法是使用以下命令:

# podman pod create --name myhttp
3950703adb04c6bca7f83619ea28c650f9db37fd0060c1e263cf7ea34dbc8dad
# podman pod ps
POD ID        NAME    STATUS   CREATED        INFRA ID      # OF CONTAINERS
3950703adb04  myhttp  Created  6 seconds ago  1bdc82e77ba2  1

正如前面的範例所示,我們建立了一個名為 myhttp 的新 Pod,然後檢查 Pod 在主機系統上的狀態:只有一個 Pod 處於 created 狀態。

啟動 Pod:幕後功臣 pause 容器

我們可以像這樣啟動 Pod 並檢查會發生什麼:

# podman pod start myhttp
3950703adb04c6bca7f83619ea28c650f9db37fd0060c1e263cf7ea34dbc8dad
# podman pod ps
POD ID        NAME    STATUS   CREATED        INFRA ID      # OF CONTAINERS
3950703adb04  myhttp  Running  About a minute ago  1bdc82e77ba2  1

Pod 現在正在執行,但 Podman 實際上在執行什麼? 我們建立了一個空的 Pod,裡面沒有容器! 讓我們透過執行 podman ps 命令來看看正在執行的容器,如下所示:

# podman ps
CONTAINER ID  IMAGE         COMMAND   CREATED         STATUS         PORTS   NAMES
1bdc82e77ba2  k8s.gcr.io/pause:3.5  About a minute ago  Up 6 seconds ago         3950703adb04-infra

podman ps 命令顯示一個名為 pause 的映像正在執行的容器。 預設情況下,Podman 會將此容器作為基礎結構容器執行。 這種容器什麼也不做——它只是儲存名稱空間,並讓容器引擎連線到 Pod 內任何其他正在執行的容器。

多容器 Pod:協同工作的力量

在揭開了這個特殊容器在我們的 Pod 中的作用之後,我們現在可以簡單地看看啟動多容器 Pod 所需的步驟。

首先,讓我們首先在前面範例中建立的現有 Pod 中執行一個新容器,如下所示:

# podman run --pod myhttp -d -i -t registry.fedoraproject.org/f29/httpd
Cb75e65f10f6dc37c799a3150c1b9675e74d66d8e298a8d19eadfa125dffdc53

然後,我們可以檢查現有的 Pod 是否已更新了它包含的容器數量,如下面的程式碼片段所示:

# podman pod ps
POD ID        NAME    STATUS   CREATED        INFRA ID      # OF CONTAINERS
3950703adb04  myhttp  Running  21 minutes ago  1bdc82e77ba2  2

最後,我們可以要求 Podman 提供一個正在執行的容器列表,以及相關的 Pod 名稱,如下所示:

# podman ps -p
CONTAINER ID  IMAGE                                         COMMAND               CREATED        STATUS         PORTS   NAMES                POD ID        PODNAME
1bdc82e77ba2  k8s.gcr.io/pause:3.5                          22 minutes ago  Up 20 minutes ago         3950703adb04-infra  3950703adb04  myhttp
cb75e65f10f6  registry.fedoraproject.org/f29/httpd:latest  /usr/bin/run-http...  4 minutes ago Up 4 minutes ago          determined_driscoll  3950703adb04  myhttp

正如您所看到的,執行的兩個容器都與名為 myhttp 的 Pod 相關聯!

玄貓提醒:

請考慮在完成本章中包含的所有範例後,定期清理實驗環境。 這可以幫助您節省資源,並避免在轉到下一章的範例時出現任何錯誤。 因此,您可以參考本章 GitHub 儲存函式庫中 AdditionalMaterial 資料夾中提供的程式碼:https://github.com/PacktPublishing/Podman-for-DevOps/tree/main/AdditionalMaterial

透過相同的方法,我們可以向同一個 Pod 增加越來越多的容器,讓它們分享我們之前描述的所有資料。

Pod 的反思:權衡利弊

請注意,在某些情況下,將容器放在同一個 Pod 中可能是有益的,但這代表了容器技術的反模式。 事實上,正如前面提到的,Kubernetes 認為 Pod 是在一個叢集的分散式節點之上執行的最小計算單元。 這意味著一旦您將兩個或多個容器分組在同一個 Pod 下,它們將在同一個節點上一起執行,並且協調器無法平衡或將它們的工作負載分配到多個機器上。

我們將在後面的章節中探索更多 Podman 的功能,這些功能可以讓您透過 Kubernetes 進入容器協調世界!

玄貓說:容器管理的下一步

在本章中,我們開始開發管理容器的經驗,從容器映像開始,然後使用正在執行的容器。 一旦我們的容器開始執行,我們還探索了 Podman 中可用的各種命令來檢查和檢查日誌並對我們的容器進行疑難排解。 監控和照顧正在執行的容器所需的操作對於任何容器管理員來說都非常重要。 最後,我們還簡要地瞭解了 Podman 中可用的 Kubernetes 概念,這些概念讓我們可以在同一個 Linux 名稱空間下對兩個或多個容器進行分組。 我們剛才經歷的所有概念和範例將幫助我們開始我們作為容器技術系統管理員的經驗。

我們現在準備好在下一章中探索另一個重要的主題:管理容器的儲存!

容器資料儲存:玄貓的技術解析

在探討容器儲存的奧秘之前,讓玄貓先點明一個核心概念:沒有儲存,就沒有靈魂。想像一下,如果你的網站每次重新啟動,所有使用者上傳的圖片、設定檔都消失了,那會是什麼災難?容器儲存,正是為了避免這種情況發生。

為何容器需要儲存?玄貓的深度解析

容器技術的核心理念是輕量、可拋棄式。但現實世界中,許多應用程式需要持久化儲存資料。這就引出了兩種容器儲存方式:

  • 外部儲存:連線到執行中的容器,用於儲存需要持久化的資料。即使容器重新啟動,資料依然存在。
  • 底層儲存:用於儲存容器映像檔和容器的根檔案系統。

玄貓認為,理解這兩種儲存方式的差異至關重要。

還記得第一章提到的嗎?容器是無狀態、短暫的,並且通常具有唯讀檔案系統。這是因為容器技術背後的理論指出,容器應用於產生可擴充套件和分散式應用程式,這些應用程式必須水平擴充套件而不是垂直擴充套件。

水平擴充套件應用程式意味著,如果我們需要額外的資源來執行服務,我們不會增加單個執行中容器的 CPU 或 RAM,而是啟動一個全新的容器,該容器將與現有容器一起處理傳入的請求。這與公有雲中採用的著名範例相同。原則上,容器應該是短暫的,因為現有容器映像檔的任何額外副本都應該隨時執行,以增強現有執行服務。

當然,也存在例外情況,並且可能會發生執行中的容器無法水平擴充套件,或者它只需要分享組態、快取或與啟動時或執行時的相同容器映像檔的其他副本相關的任何其他資料。

讓玄貓用一個實際的例子來說明。使用汽車分享服務在城市內的每個目的地獲得一輛新車,這可能是一種有用與聰明的方式,可以在不擔心停車費、燃料和其他事情的情況下四處走動。但是,同時,這項服務不能讓您將東西儲存或留在停放的汽車內。因此,當使用汽車分享服務時,我們可以在進入汽車後開啟我們的東西,但在離開汽車之前必須將其封裝回去。這同樣適用於容器,我們必須將一些儲存附加到容器,以便我們的容器可以將資料寫下來,但是一旦我們的容器停止,我們應該分離該儲存,以便全新的容器可以在需要時使用它。

讓玄貓再舉一個更技術性的例子:讓我們考慮一個標準的三層應用程式,其中包含 Web、後端和資料函式庫服務。此應用程式的每一層都可能需要儲存,它將以各種方式使用它。Web 服務可能需要一個地方來儲存快取、儲存呈現的網頁、執行時的一些自訂映像檔等等。後端服務將需要一個地方來儲存組態和執行中的其他後端服務(如果有的話)之間的同步資料等等。資料函式庫服務肯定需要一個地方來儲存資料函式庫資料。

儲存通常與低階基礎架構相關聯,但在容器中,儲存甚至對於開發人員來說也變得重要,開發人員應該規劃在哪裡附加儲存以及其應用程式所需的功能。

如果我們將主題擴充套件到容器協調,那麼儲存繼承了戰略角色,因為它應該像我們可能使用的 Kubernetes 協調器一樣具有彈性和可行性。在這種情況下,容器儲存應該更像軟體定義的儲存 - 能夠以自助服務的方式向開發人員和一般的容器提供儲存資源。

儘管本章將討論本地儲存,但重要的是要注意,這對於 Kubernetes 協調器來說是不夠的,因為容器應該可以根據定義的可用性和擴充套件規則從一個主機移植到另一個主機。這就是軟體定義的儲存可能成為解決方案的地方!

正如我們可以從前面的例子中推斷的那樣,外部儲存在容器中很重要。使用方式可能因容器內執行的應用程式而異,但這是必需的。同時,另一個關鍵角色是由底層容器儲存驅動的,它負責處理容器和容器映像檔根檔案系統的正確儲存。選擇正確、穩定與效能良好的底層本地儲存將確保更好地和正確地管理我們的容器。

因此,讓我們先探索一下容器儲存的一些理論,然後討論如何使用它。

玄貓的儲存選型建議

選擇合適的儲存方案,需要根據應用程式的特性來決定。例如:

  • Web 服務:可以使用網路檔案系統(NFS)或物件儲存服務,用於儲存靜態資源和使用者上傳的檔案。
  • 資料函式庫服務:可以使用區塊儲存或雲端提供的資料函式庫服務,確保資料的永續性和效能。

玄貓建議,在選擇儲存方案時,需要考慮以下因素:

  • 效能:儲存的讀寫速度是否滿足應用程式的需求?
  • 永續性:資料是否需要持久化儲存?
  • 可擴充套件性:儲存方案是否能夠隨著應用程式的成長而擴充套件?
  • 成本:儲存方案的成本是否合理? 身為玄貓(BlackCat),我將根據提供的內容,撰寫一篇關於容器儲存技術的文章,著重於其實作細節與組態,並融入我個人的經驗與見解。