使用docker的過程中,我們會有多重情況需要訪問容器。比如希望直接進入MySql容器執行命令,或是希望查看容器環境,進行某些操作或訪問。這時就會用到這個命令:docker exec。
命令:
docker container exec
描述:
在運行的容器中執行命令。
您使用 docker exec 指定的命令只會在容器的首要進程(PID 1)運行時執行,如果容器重啟,該命令不會被重新啟動。
該命令在容器的默認工作目錄中運行。
該命令必須是一個可執行程序。鏈式命令或引號內的命令不起作用。
這樣是有效的:docker exec -it my_container sh -c “echo a && echo b”?
這樣是無效的:docker exec -it my_container “echo a && echo b”
用法:
docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]
別名:
docker exec(docker的一些命令可以簡寫,docker exec和docker container exec是等價的)
選項:
選項 | 描述 |
---|---|
-d, –detach | 分離模式:在后臺運行命令 |
–detach-keys | 覆蓋用于分離容器的鍵序列 |
-e, –env | API 1.25+ 設置環境變量 |
–env-file | 讀取的環境變量文件 |
-i, –interactive | 即使未附著也保持 STDIN 打開 |
–privileged | 為命令提供擴展權限 |
-t, –tty | 分配一個偽TTY |
-u, –user | 用戶名或用戶ID(格式:<name|uid>[:<group|gid>]) |
-w, –workdir | 容器內的工作目錄 |
示例1:選項-d, –detach、-i, –interactive、-t, –tty
-d相當于后臺運行,使用這個選項,不影響終端的進一步操作。-i和-t兩個選項通常一起使用,在【Docker學習】docker run之黃金搭檔-it選項 – 筑天兄的清凈小站 (skycreator.top)有詳細介紹。
關于這三個選項,官方給出的例子挺好。我就直接使用官方例子,在我的阿里云上操作,借花獻佛了。
使用exec,首先要確保有一個運行著的容器。使用以下命令創建并啟動一個名為mycontainer的基于alpine的容器,該容器以sh shell作為其主進程。其中,-d選項(–detach的簡寫形式)會讓容器以后臺運行的方式啟動,即分離模式,并附加一個偽TTY(-t)。-i選項設置為保持STDIN附加(-i),這可以防止sh進程立即退出。
docker run --name mycontainer -d -i -t alpine /bin/sh
執行之后,使用ps來查看一下:
在這之后,我們使用-d選項,在運行的mycontainer容器中運行一個命令touch /tmp/execWorks。該命令在容器的根目錄tmp下創建execWorks文件。
docker exec -d mycontainer touch /tmp/execWorks
這條命令執行之后沒效果,需要進入容器的sh下查看。使用-it選項(-i加-t選項),直接與容器交互。
docker exec -it mycontainer sh
在容器的終端進入tmp文件夾查看,發現execWorks被創建。
示例2:選項–detach-keys
這個選項說起來比較復雜,在【Docker學習】docker start深入研究 – 筑天兄的清凈小站 (skycreator.top)中有詳細講解,大家可以對照著來學習。
示例3:選項-e, –env和選項–env-file
這兩個選項都是設置環境變量的,前者是直接設置,后者是通過一個文件設置。在【Docker學習】docker run的環境變量相關選項(-e, –env, –env-file) – 筑天兄的清凈小站 (skycreator.top)中有詳細講解,這個不再贅述了。
示例4:–privileged
這個選項用于提升容器權限,它為容器提供了以下功能:
- 啟用所有Linux內核功能
- 禁用默認的seccomp配置文件
- 禁用默認的AppArmor配置文件?
- 禁用SELinux進程標簽?
- 授予訪問所有主機設備的權限?
- 使/sys變為可讀寫?
- 使cgroups掛載變為可讀寫?
換句話說,容器幾乎可以做主機能做的任何事情。這個標志的存在是為了允許特殊用途,比如在Docker中運行Docker。
這個選項很強大,未來詳細講解,這里只簡要介紹。
我們使用剛才的容器作測試,進入容器的終端,執行命令
docker exec -it mycontainer sh
在終端輸入以下命令,將一個tmpfs
文件系統掛載到/mnt
目錄,允許在這個目錄下存儲臨時數據,這些數據在系統重啟后不會保留。
/ # mount -t tmpfs none /mnt
這個命令具體作用如下:
mount
:這是用來掛載文件系統的命令。-t tmpfs
:這指定了要掛載的文件系統類型為tmpfs
,這是一種基于內存的文件系統,也稱為臨時文件系統。數據存儲在內存中,而不是寫入磁盤,這意味著它的讀寫速度非常快,但數據在系統重啟后會丟失。none
:這里指定了設備的源,none
表示沒有實際的設備或文件名與tmpfs
關聯。因為tmpfs
不依賴于具體的設備,所以使用none
作為占位符。/mnt
:這是掛載點,即文件系統在目錄樹中的位置。在這個例子中,tmpfs
將被掛載到/mnt
目錄下。
看看運行結果。顯示permission denied,說明沒有權限。默認情況下,Docker會丟棄大多數可能危險的核心功能,包括CAP_SYS_ADMIN(掛載文件系統所必需的)。
那么我們執行–privileged選項看看。
居然沒有效果!!!好吧,看來只能放大招了。
官網講解–privileged選項時,也講解了docker run 的–cap-add選項,該選項可以為容器添加linux功能。而SYS-ADMIN是linux系統管理必備的功能。因此我使用該選項,先給mycontainer加入這個功能。
docker run --cap-add SYS_ADMIN --name mycontainer -dit alpine /bin/sh
執行之后,我嘗試進行掛載,這次成功了。通過df -h命令查看文件系統磁盤空間使用情況。可以看到最下面一行,文件系統是none的就是我進行的掛載。不過這么做也用不著–privileged選項了。
官網的例子使用的并不是alpine,而是ubuntu。通過對比–privileged使用與否的情況,可以看到ubuntu的/dev目錄發生了明顯的變化:
上面是不使用–privileged選項的/dev目錄。
上面是使用–privileged選項的/dev目錄。
可以明顯看出兩者的不同,說明使用–privileged選項,為/dev目錄增加了不少特性。
回過頭再來看alpine,使用不使用/dev的目錄是相同的。如下圖所示:
也就是說,alpine這個鏡像并沒有為–privileged選項預留功能。畢竟alpine是閹割版的linux系統,它的大小只有4m多。下面是幾個linux官方鏡像的大小對比。
另外,docker run的–cap-add選項,沒有加入到docker exec中,可能是因為這只能是創建時加入,運行中的容器是不能直接設置的。
示例5:-u, –user選項
這個選項用于以某個用戶身份進入容器。
還是使用alpine這個鏡像的mycontainer容器,進入容器的shell下,添加一個普通用戶zl
adduser zl
然后exit退出,重新使用docker exec進入,這次加入-u選項
docker exec -it -u zl mycontainer sh
在shell中輸入id,查看當前用戶的信息
可以看出,當前用戶是zl,uid,gid和groups均顯示出來了。
示例6:-w, –workdir選項
該選項用于設置容器的工作目錄。不指定的情況下,工作目錄就是/,如下圖所示:
下面指定了工作目錄為/etc,使用pwd查看當前工作目錄,即是/etc。
關于alpine
Alpine是一個輕量級的Linux發行版,它基于musl libc和 BusyBox,旨在提供一個小巧、安全、簡單且高效的操作系統。Alpine特別適合用于容器和云環境,因為它的大小很小,啟動速度快,同時提供了一個包管理器工具apk,可以用來安裝、更新和管理軟件包。
在Docker等容器平臺中,Alpine經常被用作基礎鏡像,因為它可以創建出非常小的容器鏡像,這對于開發和部署都非常有利。由于它的體積小,Alpine在資源有限的場景下也非常受歡迎,比如在嵌入式設備或者需要快速部署的應用中。
Alpine
?官網:https://www.alpinelinux.org/Alpine
?官方倉庫:https://github.com/alpinelinux
Alpine
?官方鏡像:https://hub.docker.com/_/alpine/
Alpine
?官方鏡像倉庫:https://github.com/gliderlabs/docker-alpine
關于–privileged
請謹慎使用–privileged標志。帶有–privileged的容器并不是一個安全沙箱化的進程。在此模式下的容器可以在主機上獲取root權限的shell并控制系統。
對于大多數用例來說,這個標志不應該是首選解決方案。如果您的容器需要提升的權限,您應該更愿意明確授予必要的權限,例如通過使用–cap-add添加單個內核功能。
關于df -h
命令
在Linux和類Unix操作系統中,df -h
是一個常用的命令,用于顯示文件系統的磁盤空間使用情況。df
代表disk free,即磁盤空閑空間。-h
選項表示human-readable,它會以更易于閱讀的格式顯示大小,例如將字節轉換為千字節、兆字節或吉字節,并附加適當的單位(K、M、G)。
df -h
命令的輸出通常包括以下信息:
- 文件系統的掛載點(Mounted on)
- 文件系統的總大小(Size)
- 已使用的空間大小(Used)
- 可用的空閑空間(Avail)
- 使用百分比(Use%)
- 文件系統的標識(Filesystem)