5.4 進入容器
5.4.1 為什麼需要進入容器
使用 -d 引數啟動容器後,容器在後台執行。以下場景需要進入容器內部操作:
| 場景 | 範例 |
|---|---|
| 除錯問題 | 檢視日誌、檢查設定、排查錯誤 |
| 臨時操作 | 執行資料庫遷移、清理快取 |
| 檢查狀態 | 檢視程序、網路連線、檔案系統 |
| 開發測試 | 互動式測試指令、驗證環境 |
5.4.2 兩種進入方式
Docker 提供兩種進入容器的指令:
| 指令 | 推薦程度 | 特點 |
|---|---|---|
docker exec |
✅ 推薦 | 啟動新進程,退出不影響容器 |
docker attach |
⚠️ 謹慎使用 | 附加到主程序,退出可能停止容器 |
5.4.3 docker exec:推薦
docker exec 基本用法
## 進入容器並啟動互動式 shell
$ docker exec -it 容器名 /bin/bash
## 或使用 sh(適用於 Alpine 等精簡映象)
$ docker exec -it 容器名 /bin/sh
引數說明
| 引數 | 作用 |
|---|---|
-i |
保持標準輸入開啟 (interactive) |
-t |
分配偽終端 (TTY) |
-it |
兩者組合,獲得完整互動體驗 |
-u |
指定使用者 (如 -u root) |
-w |
指定工作目錄 |
-e |
設定環境變數 |
docker exec 範例
## 啟動一個後台容器
$ docker run -dit --name myubuntu ubuntu
69d137adef7a...
## 進入容器(互動式 shell)
$ docker exec -it myubuntu bash
root@69d137adef7a:/# ls
bin boot dev etc home lib ...
root@69d137adef7a:/# exit
## 容器仍在執行!
$ docker ps
CONTAINER ID IMAGE STATUS NAMES
69d137adef7a ubuntu Up 2 minutes myubuntu
執行單條指令
不進入互動模式,直接執行指令:
## 檢視容器內程序
$ docker exec myubuntu ps aux
## 檢視設定檔案
$ docker exec myubuntu cat /etc/nginx/nginx.conf
## 以 root 使用者執行
$ docker exec -u root myubuntu apt update
只用 -i 不用 -t 的區別
## 只用 -i:可以執行指令,但沒有提示符
$ docker exec -i myubuntu bash
ls # 輸入指令
bin # 輸出結果
boot
dev
...
## 用 -it:有完整的終端體驗
$ docker exec -it myubuntu bash
root@69d137adef7a:/# # 有提示符
💡 通常使用
-it組合。只有在指令碼中需要透過通道傳入指令時才只用-i。
5.4.4 docker attach:謹慎使用
docker attach 基本用法
$ docker attach 容器名
工作原理
attach 會附加到容器的 主程序 (PID 1) 的標準輸入輸出:
flowchart LR
subgraph Container ["容器"]
direction TB
subgraph Process ["主程序"]
P1["PID 1: /bin/bash
(你的輸入直接傳送到主程序)"] end end Attach["docker attach"] -->|"附加到這裡"| P1
(你的輸入直接傳送到主程序)"] end end Attach["docker attach"] -->|"附加到這裡"| P1
docker attach 範例
## 啟動容器
$ docker run -dit --name myubuntu ubuntu
243c32535da7...
## 附加到容器
$ docker attach myubuntu
root@243c32535da7:/#
⚠️ 重要警告
從 attach 會話中輸入 exit 或按 Ctrl+D 會導致容器停止!
$ docker attach myubuntu
root@243c32535da7:/# exit # 這會停止容器!
$ docker ps
CONTAINER ID IMAGE STATUS NAMES
243c32535da7 ubuntu Exited (0) 2 seconds ago myubuntu
原因:attach 附加到主程序,退出主程序就等於退出容器。
安全退出 attach
使用 Ctrl+P 然後 Ctrl+Q 可以從 attach 會話中 分離,而不停止容器:
$ docker attach myubuntu
root@243c32535da7:/#
## 按 Ctrl+P 然後 Ctrl+Q
read escape sequence
$ docker ps # 容器仍在執行
CONTAINER ID IMAGE STATUS NAMES
243c32535da7 ubuntu Up 5 minutes myubuntu
5.4.5 exec vs attach 對比
| 屬性 | docker exec | docker attach |
|---|---|---|
| 工作方式 | 在容器內啟動新進程 | 附加到主程序 |
| 退出影響 | 不影響容器 | 可能停止容器 |
| 多終端 | 可以開多個 | 共享同一個會話 |
| 適用場景 | 除錯、臨時操作 | 檢視主程序輸出 |
| 推薦程度 | ✅ 推薦 | ⚠️ 特殊場景使用 |
flowchart LR
subgraph Exec ["docker exec"]
direction TB
subgraph Container1 ["容器"]
E_PID1["PID 1: nginx"]
E_PID50["PID 50: bash"]
end
NewProc["新進程"] -- 附加到 --> E_PID50
end
subgraph Attach ["docker attach"]
direction TB
subgraph Container2 ["容器"]
A_PID1["PID 1: bash"]
end
MainProc["附加到主程序"] --> A_PID1
end
note1["退出 bash 不影響 nginx"]
note2["退出 bash 容器停止"]
Container1 -.-> note1
Container2 -.-> note2
5.4.6 最佳實踐
1. 首選 docker exec
## 進入容器除錯
$ docker exec -it myapp bash
## 檢視日誌
$ docker exec myapp tail -f /var/log/app.log
## 執行資料庫遷移
$ docker exec myapp python manage.py migrate
2. 生產環境避免進入容器
筆者建議:生產環境應儘量避免進入容器直接操作,而是透過:
- 日誌系統檢視日誌 (如
docker logs或集中式日誌) - 監控系統檢視狀態
- 重新部署而非手動修改
3. 無 shell 映象的處理
某些精簡映象 (如基於 scratch 或 distroless) 沒有 shell:
## 這會失敗
$ docker exec -it myapp bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found
## 解決方案:使用除錯容器(需要 Docker Desktop Pro/Team/Business 訂閱)
$ docker debug myapp
注意:
docker debug是 Docker Desktop 4.33+ 提供的功能,需要 Pro、Team 或 Business 訂閱。它會附加一個包含常用除錯工具(vim、curl、htop 等)的工具箱到目標容器,即使目標映象基於scratch也能使用。
5.4.7 常見問題
Q:exec 進入後看不到其他終端的操作
這是正常的。exec 啟動的是獨立程序,多個 exec 會話互不影響。
Q:容器沒有 bash
嘗試使用 sh:
$ docker exec -it myapp /bin/sh
Q:需要 root 許可權
$ docker exec -u root -it myapp bash