天天看點

5 種快速查找容器系統中檔案的方法

作者:Docker中文社群
5 種快速查找容器系統中檔案的方法

如果你經常使用容器,那麼你很有可能希望在某個時刻檢視正在運作的容器的檔案系統。也許容器無法正常運作,你想讀取一些日志,也許你想檢查容器内部的一些配置檔案…或者,你可能像我一樣,想在該容器中的二進制檔案上放置一些 eBPF 探針(稍後将詳細介紹)。

不管原因是什麼,在這篇文章中,我們将介紹一些可以用來檢查容器中的檔案的方法。

我們将從研究容器檔案系統的簡單和通常推薦的方法開始,并讨論為什麼它們不能總是工作。接下來,我們将對 Linux 核心如何管理容器檔案系統有一個基本的了解,我們将利用這一了解以不同但仍然簡單的方式檢查檔案系統。

如果你快速搜尋如何檢查容器的檔案系統,你會發現一個常見的解決方案是使用 Docker 指令:

這是一個很好的開始。如果它能滿足你的所有需求,你應該繼續使用它。

然而,這種方法的一個缺點是,它需要在容器中存在一個 shell。如果容器中沒有/bin/bash、/bin/sh 或其他 shell,那麼這種方法将不起作用。例如,我們為 Pixie 項目建構的許多容器都是基于無 distroless 的,并且沒有包含一個 shell 來保持鏡像較小。在這些情況下,這種方法不起作用。

即使 shell 可用,你也無法通路所有你習慣使用的工具。是以,如果容器中沒有安裝 grep,那麼你也不能通路 grep。這是另一個找更好工作的理由。

如果你再深入一點,就會意識到容器程序與 Linux 主機上的其他程序一樣,隻是在命名空間中運作,以使它們與系統的其他部分隔離。

是以你可以使用 nsenter 指令來輸入目标容器的命名空間,使用類似這樣的東西:

它進入目标程序的挂載(-m)命名空間(-t $PID),并運作/bin/bash。進入挂載命名空間本質上意味着我們獲得容器所看到的檔案系統視圖。

這種方法似乎比 docker 的 exec 方法更有前途,但也遇到了類似的問題:它要求目标容器中包含/bin/bash(或其他 shell)。如果我們輸入的不是挂載命名空間,我們仍然可以通路主機上的檔案,但是因為我們是在執行/bin/bash(或其他 shell)之前輸入挂載命名空間,是以如果挂載命名空間中沒有 shell,我們就不走運了。

解決這個問題的另一種方法是簡單地将相關檔案複制到主機,然後使用複制的檔案。

要從正在運作的容器中複制標明的檔案,可以使用:

也可以用以下方法來快照整個檔案系統:

這些指令使你能夠檢查檔案,當容器可能沒有 shell 或你需要的工具時,這些指令比前兩種方法有了很大的改進。

複制方法解決了我們的許多問題,但是如果你試圖監視日志檔案呢?或者,如果你試圖将 eBPF 探針部署到容器中的檔案中,又該怎麼辦呢?在這些情況下,複制是不起作用的。

我們希望直接從主機通路容器的檔案系統。容器的檔案應該在主機的檔案系統中,但是在哪裡呢?

Docker 的 inspect 指令給了我們一個線索:

這給我們:

讓我們來分析一下:

LowerDir:包含容器内所有層的檔案系統,最後一層除外

UpperDir:容器最上層的檔案系統。這也是反映任何運作時修改的地方。

MergedDir:檔案系統所有層的組合視圖。

WorkDir:用于管理檔案系統的内部工作目錄。

5 種快速查找容器系統中檔案的方法

基于 overlayfs 的容器檔案系統結構。

是以,要檢視容器中的檔案,隻需檢視 MergedDir 路徑。

如果你想了解檔案系統工作的更多細節,你可以檢視 Martin Heinz 關于 overlay 檔案系統的部落格文章:https://martinheinz.dev/blog/44。

把最好的留到最後,還有一種從主機找到容器檔案系統的更簡單的方法。使用容器内程序的宿主 PID,你可以簡單地運作:

Linux 已經為你提供了程序挂載命名空間的視圖。

此時,你可能會想:為什麼我們不采用這種方法,并将其變成一篇隻有一行字的部落格文章呢?但這都是關于旅程,對吧?

出于好奇,方法四中讨論的關于容器 overlay 檔案系統的所有資訊也可以直接從 Linux /proc 檔案系統中發現。如果你檢視/proc/<pid>/mountinfo,你會看到如下内容:

在這裡,你可以看到容器已經挂載了一個覆寫檔案系統作為它的根。它還報告與 docker inspect 報告相同類型的資訊,包括容器檔案系統的 LowerDir 和 UpperDir。它沒有直接顯示 MergedDir,但你可以直接使用 UpperDir 并将 diff 改為 merged,這樣你就可以看到容器的檔案系統了。

在本部落格的開頭,我提到了 Pixie 項目需要如何在容器上放置 eBPF 探針。為什麼和如何?

Pixie 内部的 Stirling 子產品負責收集可觀察資料。由于是 k8s 原生的,是以收集的很多資料都來自于在容器中運作的應用程式。Stirling 還使用 eBPF 探針從它監視的程序中收集資料。例如,Stirling 在 OpenSSL 上部署 eBPF 探針來跟蹤加密的消息(如果你想了解更多有關這方面的細節,請參閱SSL 跟蹤部落格[1])。

由于每個容器都捆綁了自己的 OpenSSL 和其他庫,是以 Stirling 部署的任何 eBPF 探針都必須位于容器内的檔案上。是以,Stirling 使用本文中讨論的技術在 K8s 容器中找到感興趣的庫,然後從主機将 eBPF 探針部署到這些二進制檔案上。

下圖概述了在另一個容器中部署 eBPF 探針的工作方式。

5 種快速查找容器系統中檔案的方法

Stirling 通過挂載主機檔案系統在其他容器上部署 eBPF 探針,然後在主機上找到目标容器檔案系統。

下次當你需要檢查容器中的檔案時,希望你能嘗試一下這些技巧。一旦你體驗到不再受容器有沒有 shell 限制的自由,你可能就再也不會回去了。隻需要通路/proc/<pid>/root!

[1]

SSL 跟蹤部落格: https://blog.px.dev/ebpf-openssl-tracing/

英文原文位址: https://blog.px.dev/container-filesystems/
本文轉載自:「CNCF」,原文:https://tinyurl.com/56nu8xra,版權歸原作者所有。

繼續閱讀