您須要瞭解的有關調試Docker容器的知識

調試Docker容器多是一個很是具備挑戰性的過程。在這裏,我將分享一些調試容器的基本技術,主要是Docker的技術,可是這些技術也適用於許多其餘類型的Linux容器引擎。我將在此處詳細介紹的方法適用於基於Linux的系統。html

撰寫此博客文章的靈感來自於externalsecret-operator 的開發團隊在實施1password後端期間遇到的一些近期問題,該庫提供了與1password API進行通訊的機制。linux

提供一些背景信息:externalsecret-operator是一個很棒的Kubernetes operator,它使secret管理的挑戰性下降,並幫助您未來自第三方憑證存儲的祕密直接注入到Kubernetes集羣中。 (若是您尚未據說過,那麼絕對值得嘗試一下。咱們的團隊正在努力開發它,而且每週都會添加新功能。)git

可是回到調試。在如下狀況下,若是咱們在主機上運行operator,那麼一切都會按預期進行,而且能夠登陸到1password後端:github

docker-debugging-1.png

可是在容器中運行時,咱們會看到如下錯誤消息:docker

docker-debugging-2.png

看起來沒有正常運行,可是咱們應該如何以及在哪裏開始調試?shell

從代碼分析開始

最好的起點老是源代碼,而且由於externalsecret-operator是開源的,因此咱們能夠很容易地看到問題出在哪裏。我建議使用Sourcegraph工具,該工具可直接在瀏覽器中工做而且能夠進行代碼分析。使用Sourcegraph識別代碼中有問題的部分的示例:segmentfault

source.jpg

這種快速的代碼分析顯示出一個好消息和一個壞消息:幸運的是,由於咱們的代碼不是問題的根源。但也很不幸,由於1password客戶端二進制文件(op)用於直接從1password祕密存儲區中獲取憑證-不幸的是,這兩個都不是開源的。後端

這纔是真正的樂趣開始的地方。瀏覽器

調試在主機系統上有效但在容器中不起做用的那些東西的線索是瞭解什麼是容器。容器是一種在同一主機上運行時將進程彼此隔離的機制,這意味着其管理員能夠直接從主機系統訪問任何容器。網絡

有了這些知識,讓咱們看看1password二進制文件是否損壞。首先,咱們必須驗證咱們的1password二進制文件不適用於容器的理論是否有效。讓咱們手動使用它,使用僞造的登陸數據:

docker-debugging-3.png

答對了!咱們的理論獲得證明。 1password二進制文件不適用於該容器;恐慌而不是優雅地退出。如今咱們有了這些信息,咱們應該確認問題是二進制自己仍是容器環境形成的。最好的方法是從新使用與容器鏡像中徹底相同的二進制文件。開始吧!

假設咱們對正在運行容器的主機具備root訪問權,那麼咱們可使用docker top <container id>來查看主機上有問題的容器的PID(進程標識符)是什麼:
docker-debugging-4.png

咱們肯定了容器PID,所以如今能夠在Linux系統進程表中找到此進程。進入process目錄後,咱們應該查看根文件夾,由於它是包含正在運行的容器的文件系統的根文件夾:
docker-debugging-5.png

檢查operator

咱們能夠訪問容器中的全部二進制文件,並在主機名稱空間中執行它們。

所以,讓咱們看看operator的問題是否來自使用錯誤的1password二進制文件:
docker-debugging-6.png

1password op二進制文件的行爲正確:因爲咱們提供了虛假數據,所以沒法登陸1password域,但最終並無收到緊急消息。所以,問題不在1password二進制文件以內。

咱們能夠看到主機名稱空間中的執行錯誤消息提到了有關無效請求的內容。咱們可能會懷疑容器中的網絡是否存在問題,以及操做二進制的panic,若是它沒法到達某些外部服務時,這是另外一個須要測試的理論。

如前所述,1password二進制文件不是開源的,所以咱們沒法知道它在哪裏嘗試鏈接。咱們能夠嘗試使用Wireshark或tcpdump等網絡嗅探器捕獲流量。但…

docker-debugging-7.png

…容器鏡像不包含任何這些二進制文件。咱們能夠將它們安裝在Docker鏡像中。可是,因爲咱們具備對主機的root訪問權限,所以能夠經過使用nsenter來更輕鬆地進行操做。

nsenter工具容許咱們輸入特定的進程名稱空間-所以,例如,咱們能夠輸入容器的網絡名稱空間,而且仍然能夠訪問咱們的宿主工具。讓咱們看看實際狀況:
docker-debugging-8.png

咱們位於容器網絡名稱空間中,能夠從主機系統訪問全部工具。

在另外一個shell中,咱們可使用容器中的op二進制文件再次登陸1password。可是,即便已鏈接到互聯網,也沒有生成任何數據包:

docker-debugging-9.png

從新排查1Password Binary

所以,在這一點上,咱們能夠假設op二進制panic甚至在創建與外部服務的鏈接以前就已出現。

如今,咱們能夠嘗試使用GDB(GNU項目調試器)調試op二進制文件,以查看執行失敗的時間。可是1password可能不包含調試符號,所以GBD沒法爲咱們提供有關執行的任何信息。經過檢查操做二進制文件中是否存在調試符號來進行確認:

docker-debugging-10.png

如所假定的,op二進制根本沒有調試符號。若是它具備這些符號,那麼在幾行中將顯示除零之外的數字,如在運算符中同樣。使用GDB沒有任何意義。

另外,GDB不支持跨命名空間調試,所以不可能從主機命名空間中對其進行調試。咱們將必須在Docker映像中安裝GDB或從源代碼編譯GDB

咱們沒法使用GDB,但能夠在此過程當中「strace」或跟蹤系統調用和信號:查看執行二進制文件中op二進制文件調用了哪些系統調用。爲此,咱們運行另外一個具備相同鏡像的容器,但修改後的入口點將直接指向op二進制文件,並使用先前使用的參數:
docker-debugging-11.png

在另外一個Shell窗口中,咱們將附加到該容器的PID並輸入密碼:
docker-debugging-12.png

咱們發現它存在一些嚴重的問題。二進制文件嘗試在僅容許超級用戶的文件系統的根目錄/中建立.op目錄:

mkdirat(AT_FDCWD,「 /.op」,0700)= -1 EACCES(權限被拒絕)

讓咱們檢查一下若是以root用戶身份運行此容器會發生什麼狀況:

run-as-root copy.png

Binary並無panic,而strace代表op實際上試圖在超級用戶主目錄而不是/中建立.op二進制文件。

strace-as-root.png

這使咱們得出結論,即默認用戶可能在Docker鏡像中配置錯誤。讓咱們檢查一下:

docker-debugging-13.png

答對了! / etc / passwd中缺乏默認用戶,系統沒法識別該默認用戶,所以op binary沒法肯定其主目錄,並嘗試在當前工做目錄中建立目錄。這是不容許的。所以,它會panic。

咱們永遠不會忘記Docker容器只是進程,大多數Linux標準調試工具均可以在它們上使用,並消除猜想驅動的調試。

我想再次強調,這些技術主要適用於Linux系統。可是對於那些在Mac上運行容器的人,我建議您研究其餘技術,例如使用全部調試工具運行sidecar容器。不管使用什麼系統,祝您調試偵探工做順利!

相關文章
相關標籤/搜索