docker 是一種容器化工具,可幫助開發人員創建和管理可移植、一致的 Linux 容器。 開發或部署容器時,您經常需要查看正在運行的容器內部以檢查其當前狀態或調試問題。為此,Docker 提供了 docker exec 命令來運行已經運行的容器中的程序。
先決條件
本教程假設您已經擁有 Docker已安裝并且您的用戶有權運行 docker。如果您需要以 root 用戶身份運行 docker,請記住在本教程中的命令前添加 sudo。
有關在沒有 sudo 訪問權限的情況下使用 Docker 的更多信息,請參閱在沒有 sudo 訪問權限的情況下執行 Docker 命令部分我們的如何安裝 Docker 教程。
啟動測試容器
要使用 docker exec 命令,您將需要 跑步 Docker 容器。如果您還沒有容器,請開始測試 使用以下 docker run 命令創建容器:
此命令從官方高山圖像。這是一個流行的 Linux 容器映像,它使用 Alpine Linux,這是一種輕量級、最小化的 Linux 發行版。
我們使用 -d 標志將容器與終端分離并在后臺運行。 –namecontainer-name將命名容器container-name。 您可以在這里選擇任何您喜歡的名稱,或者完全將其保留給 讓 Docker 自動為新容器生成唯一的名稱。
接下來我們有 alpine,它指定我們要用于容器的鏡像。
最后,我們觀看“date > > /var/log/date.log”。這是我們要在容器中運行的命令。默認情況下,watch 會重復運行您給出的命令,每兩秒一次。在這種情況下,watch 將運行的命令是 date >> /var/log/date.log。 date 打印當前日期和時間,如下所示:
OutputFri Jul 23 14:57:05 UTC 2021
>> /var/該命令的 log/date.log 部分重定向 date 的輸出并將其附加到文件 /var/log/date.log。每兩秒就會在文件中添加一個新行,幾秒鐘后它將如下所示:
OutputFri Jul 23 15:00:26 UTC 2021Fri Jul 23 15:00:28 UTC 2021Fri Jul 23 15:00:30 UTC 2021Fri Jul 23 15:00:32 UTC 2021Fri Jul 23 15:00:34 UTC 2021
在 下一步,我們將學習如何查找 Docker 容器的名稱。 如果您已經有一個目標容器,但是這會很有用 不確定它的名字是什么。
查找 Docker 容器的名稱
我們需要向 docker exec 提供我們想要工作的容器的名稱(或容器 ID)和。我們可以使用 docker ps 命令找到此信息:
docker ps
此命令列出了所有Docker 容器在服務器上運行,并提供一些高級信息它們:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES76aded7112d4alpine "watch 'date >> /var…" 11 seconds ago Up 10 secondscontainer-name
在此示例中,容器 ID 和名稱突出顯示。您可以使用其中之一來告訴 docker exec 要使用哪個容器。
如果您想重命名容器,請使用 docker rename 命令:
docker rename container-namenew-name
接下來,我們運行幾個使用 docker exec 在 Docker 容器中執行命令的示例。
在 Docker 容器中運行交互式 Shell
如果您需要在 Docker 容器內啟動交互式 shell, 也許要探索文件系統或調試正在運行的進程,請使用帶有 -i 和 -t 標志的 docker exec。
-i 標志使輸入保持對容器開放,而 -t 標志創建一個偽終端外殼可以連接。這些標志可以像這樣組合:
docker exec -itcontainer-namesh
這將在指定的位置運行 sh shell容器,為您提供基本的 shell 提示。要退出容器,請輸入 exit,然后按 ENTER:
exit
如果您的容器鏡像包含更高級的 shell,例如 bash,您可以將 sh 替換為 bash
在 Docker 容器中運行非交互式命令
如果您需要在正在運行的 Docker 容器中運行命令,但不需要任何交互性,請使用 docker exec 命令沒有任何flags:
docker exec container-nametail /var/log/date.log
此命令將在container-name 容器,并輸出結果。默認情況下,尾部 命令將打印出文件的最后十行。如果你正在跑步 我們在第一部分中設置的演示容器,您將看到 像這樣的東西:
OutputMon Jul 26 14:39:33 UTC 2021Mon Jul 26 14:39:35 UTC 2021Mon Jul 26 14:39:37 UTC 2021Mon Jul 26 14:39:39 UTC 2021Mon Jul 26 14:39:41 UTC 2021Mon Jul 26 14:39:43 UTC 2021Mon Jul 26 14:39:45 UTC 2021Mon Jul 26 14:39:47 UTC 2021Mon Jul 26 14:39:49 UTC 2021Mon Jul 26 14:39:51 UTC 2021
這本質上與為Docker 容器(如上一步中使用 docker 所做的那樣) exec-itcontainer-namesh),然后運行 tail /var/log/date.log 命令。但是,不是打開 shell,而是運行命令, 然后關閉 shell,此命令在 a 中返回相同的輸出 單個命令,無需打開偽終端。
在 Docker 容器的備用目錄中運行命令
要在容器的某個目錄中運行命令,請使用 –workdir 標志指定目錄:
docker exec --workdir /tmpcontainer-namepwd
此示例命令將 /tmp 目錄設置為工作目錄,然后運行pwd 命令,打印出當前的工作狀態目錄:
Output/tmp
pwd 命令已確認工作目錄為 /tmp。
在 Docker 中以不同用戶身份運行命令容器
要在容器內以不同用戶身份運行命令,請添加 –user 標志:
docker exec --user guestcontainer-namewhoami
這將使用 guest 用戶在容器中運行 whoami 命令。 whoami 命令打印出當前用戶的用戶名:
Outputguest
whoami 命令確認容器的當前用戶是 guest。
將環境變量傳遞到 Docker容器
有時您需要將環境變量與要運行的命令一起傳遞到容器中。 -e 標志允許您指定環境變量:
docker exec -e TEST=sammycontainer-nameenv
此命令設置 TEST 環境變量等于 sammy,然后在容器內運行 env 命令。然后 env 命令打印出所有環境變量:
OutputPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=76aded7112d4TEST=sammyHOME=/root
TEST 變量設置為sammy.
要設置多個變量,請為每個變量重復 -e 標志一:
docker exec -e TEST=sammy -e ENVIRONMENT=prod container-nameenv
如果您想傳入一個充滿環境變量的文件,您可以可以使用 –env-file 標志來做到這一點。
首先,使用文本編輯器創建文件。我們將在此處使用 nano 打開一個新文件,但您可以使用任何您喜歡的編輯器:
nano .env
我們使用 .env 作為文件名,因為這是使用此類文件進行管理的流行標準版本控制之外的信息。
將 KEY=value 變量寫入文件,每行一個,如下所示:
TEST=sammyENVIRONMENT=prod
保存并關閉文件。要保存文件并退出 Nano,請按 CTRL O,然后按 ENTER 保存,然后按 CTRL X 退出。
現在運行 docker exec 命令,在后面指定正確的文件名–env-file:
docker exec --env-file .envcontainer-nameenv
OutputPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=76aded7112d4TEST=sammyENVIRONMENT=prodHOME=/root
文件中的兩個變量被設置。
您可以使用多個 –env-file 指定多個文件 旗幟。如果文件中的變量相互重疊,則以哪個文件為準 在命令中最后列出的文件將覆蓋以前的文件。
常見錯誤
使用 docker exec 命令時,您可能會遇到一些常見錯誤錯誤:
Error: No such container:container-name
No such container 錯誤表示指定的容器不存在,并且可能指示拼寫錯誤的容器名稱。使用 docker ps 列出正在運行的容器并仔細檢查名稱。
Error response from daemon: Container2a94aae70ea5dc92a12e30b13d0613dd6ca5919174d73e62e29cb0f79db6e4abis not running
這不是running 消息表示容器存在但已停止。您可以使用 docker startcontainer-name
Error response from daemon: Containercontainer-nameis paused, unpause the container before exec
啟動容器容器已暫停錯誤很好地解釋了這個問題。在繼續之前,您需要使用 docker unpausecontainer-name.
取消暫停容器。