如何確定程序是否在LXC/Docker容器內執行?
簡介
本文的主要目標是確定程序是否在容器中執行。我們討論了幾種方法,可以幫助我們將非容器機器從容器中過濾出來。我們使用簡單的命令和一些特殊的核心檔案來總結我們的觀點。
先決條件
要在您的設定機器上實現本文的完整內容,您需要具備以下列出的先決條件:
Linux作業系統:Ubuntu
Docker守護程序和客戶端
方法
下面列出了一些有助於識別機器的方法。該機器可能是容器或非容器。
使用環境變數
使用.dockerenv檔案
使用控制組資訊
使用CPU資訊
使用程序ID。
使用Docker環境
環境變數用於儲存/儲存資訊。資訊可以是特定檔案的路徑、使用者名稱、密碼等。
在這裡,我們將建立一個儲存文字“DockerContainer”的環境變數。執行時,此環境變數將傳遞到容器映象。
步驟1:建立Dockerfile
在這裡,我們建立了一個Dockerfile的最小版本,這是滿足我們建立帶有環境變數的Docker映象的要求所需的。
# the bash image we are using is Busybox:latest FROM busybox:latest #create an environment variable needed when starting this image as a container ENV TEST_ENV="Docker-Container"
步驟2:構建映象
現在為這個Dockerfile構建一個Docker映象。
示例
$ docker build -t env_test:latest.
輸出
Sending build context to Docker daemon 2.048kB Step 1/2 : FROM busybox:latest ---> 9d5226e6ce3f Step 2/2 : ENV TEST_ENV="Docker-Container" ---> Running in b993407fa937 Removing intermediate container b993407fa937 ---> c9e931c275be Successfully built c9e931c275be Successfully tagged env_test:latest
步驟3:執行容器
在這裡,我們運行了容器,並傳遞了環境變數。
$docker run -itd -e TEST_ENV="Docker-Container" --name cont env_test:latest
步驟4:檢查您現在是否在容器中
$echo $TEST_ENV
現在讓我們進入容器並再次檢查
$docker exec -it cont sh /# echo $TEST_ENV
輸出
Docker-Container
因此,這證明了我們位於Docker容器內。
使用.dockerenv檔案
建立Docker容器時,會在容器的根目錄下建立一個“.dockerenv”檔案。因此,搜尋此檔案可以幫助我們瞭解我們是在Docker容器內還是容器外。
在非容器機器上:
$ ls -la | grep ./dockerenv
這沒有輸出,因此檔案不存在。
現在嘗試在容器機器上:
/ # ls -la | grep .dockerenv
輸出
-rwxr-xr-x 1 root root 0 Dec 18 14:00 .dockerenv
因此,這證明我們位於容器中。
使用proc檔案系統
特殊檔案是Linux檔案系統的重要組成部分。其中一個特殊系統是proc檔案系統。它用於儲存核心的狀態。
我們在proc檔案系統中具有控制組和CPU排程。控制組的資訊儲存在特定位置。這些組對於非容器和容器機器具有不同的資料。控制組的路徑是 /proc/1/cgroup,CPU排程的路徑是 /proc/1/sched
步驟1:非容器機器
非容器機器(例如Ubuntu)上這兩個位置的資料:
示例
$ cat /proc/1/sched | head -n 1
輸出
systemd (1, #threads: 1)
在控制組中。
示例
$ cat /proc/1/cgroup | head -n 1
輸出
0::/init.scope
步驟2:容器機器
現在在容器中。
示例
/# cat /proc/1/sched | head -n 1
輸出
bash (1, #threads: 1)
上述輸出顯示第一個排程程式是用於bash或容器中的入口點命令。但對於非容器機器,它是systemd(Ubuntu)。
對於控制組:
示例
/ # cat /proc/1/cgroup | head -n 1
輸出
0::/
使用程序ID
Linux中的每個程序都有一個唯一的ID,稱為PID。有一個程序kthread,它僅存在於基於非容器的機器上。它的PID固定為2。因此,透過檢查PID 2,我們可以識別我們是否在容器中。
在非容器機器上
示例
$ ps 2
輸出
PID TTY STAT TIME COMMAND 2 ? S 0:00 [kthreadd]
在容器機器上,它可能不會顯示任何程序。除了kthread之外的程序也是可能的。
結論
使用核心檔案被認為是上述所有方法中最好的方法。有時,對於Docker容器,.dockerinit檔案用於瞭解您是否在容器中。