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