docker debug

描述獲取任何容器或映象的 shell。`docker exec` 除錯的替代方案。
用法debug [選項] {容器|映象}
訂閱: 專業版 團隊版 商業版
要求: Docker Desktop 4.33.0 及更高版本

描述

Docker Debug 是一個 CLI 命令,透過保持映象精簡和安全來幫助您遵循最佳實踐。使用 Docker Debug,您可以在映象只包含執行應用程式所需的最少內容時除錯它們。它透過讓您建立和使用通常難以除錯的精簡映象或容器來做到這一點,因為所有工具都已被移除。例如,雖然像 `docker exec -it my-app bash` 這樣的典型除錯方法可能不適用於精簡容器,但 `docker debug` 可以。

使用 `docker debug`,您可以獲取任何容器或映象的除錯 shell,即使它們不包含 shell。您無需修改映象即可使用 Docker Debug。但是,使用 Docker Debug 仍然不會修改您的映象。Docker Debug 帶來自己的工具箱,您可以輕鬆自定義。該工具箱預裝了許多標準 Linux 工具,例如 `vim`、`nano`、`htop` 和 `curl`。使用內建的 `install` 命令可以新增 https://search.nixos.org/packages 上提供的其他工具。Docker Debug 支援 `bash`、`fish` 和 `zsh`。預設情況下,它會嘗試自動檢測您的 shell。

自定義內建工具

  • install [工具1] [工具2]:從 https://search.nixos.org/packages 新增 Nix 軟體包,請參閱示例
  • uninstall [工具1] [工具2]:解除安裝 Nix 軟體包。
  • entrypoint:列印、檢查或執行入口點,請參閱示例
  • builtins:顯示自定義內建工具。
注意

對於映象和已停止的容器,離開 shell 時所有更改都將被丟棄。在任何時候,更改都不會影響實際的映象或容器。當訪問正在執行或已暫停的容器時,所有檔案系統更改對容器直接可見。`/nix` 目錄對實際的映象或容器永遠不可見。

選項

選項預設值描述
--shellauto選擇一個 shell。支援:`bash`、`fish`、`zsh`、`auto`。
-c, --command評估指定的命令而不是啟動互動式會話,請參閱示例
--host要連線的守護程式 docker socket。例如:`ssh://root@example.org`、`unix:///some/path/docker.sock`,請參閱示例

示例

除錯沒有 shell 的容器(精簡容器)

`hello-world` 映象是非常簡單的,只包含 `/hello` 二進位制檔案。這是精簡映象的一個很好的例子。沒有其他工具,也沒有 shell。

從 `hello-world` 映象執行容器

$ docker run --name my-app hello-world

容器立即退出。要獲取內部除錯 shell,請執行

$ docker debug my-app

除錯 shell 允許您檢查檔案系統

docker > ls
dev  etc  hello  nix  proc  sys

檔案 `/hello` 是執行容器時執行的二進位制檔案。您可以透過直接執行它來確認這一點

docker > /hello

執行二進位制檔案後,它會產生相同的輸出。

除錯(精簡)映象

您可以透過直接執行來除錯映象

$ docker debug hello-world
...
docker > ls
dev  etc  hello  nix  proc  sys

您甚至不需要拉取映象,因為 `docker debug` 會像 `docker run` 命令一樣自動執行此操作。

修改正在執行的容器的檔案

Docker debug 允許您修改任何正在執行的容器中的檔案。工具箱預裝了 `vim` 和 `nano`。

執行一個 nginx 容器並更改預設的 `index.html`

$ docker run -d --name web-app -p 8080:80 nginx
d3d6074d0ea901c96cac8e49e6dad21359616bef3dc0623b3c2dfa536c31dfdb

要確認 nginx 正在執行,請開啟瀏覽器並導航到 https://:8080。您應該會看到預設的 nginx 頁面。現在,使用 vim 更改它

vim /usr/share/nginx/html/index.html

將標題更改為“Welcome to my app!”並儲存檔案。現在,在瀏覽器中重新載入頁面,您應該會看到更新後的頁面。

使用 `install` 命令管理您的工具箱

內建的 `install` 命令允許您將 https://search.nixos.org/packages 中的任何工具新增到工具箱中。請記住,新增工具永遠不會修改實際的映象或容器。工具只會新增到您的工具箱中。執行 `docker debug` 然後安裝 `nmap`

$ docker debug nginx
...
docker > install nmap
Tip: You can install any package available at: https://search.nixos.org/packages.
installing 'nmap-7.93'
these 2 paths will be fetched (5.58 MiB download, 26.27 MiB unpacked):
/nix/store/brqjf4i23fagizaq2gn4d6z0f406d0kg-lua-5.3.6
/nix/store/xqd17rhgmn6pg85a3g18yqxpcya6d06r-nmap-7.93
copying path '/nix/store/brqjf4i23fagizaq2gn4d6z0f406d0kg-lua-5.3.6' from 'https://cache.nixos.org'...
copying path '/nix/store/xqd17rhgmn6pg85a3g18yqxpcya6d06r-nmap-7.93' from 'https://cache.nixos.org'...
building '/nix/store/k8xw5wwarh8dc1dvh5zx8rlwamxfsk3d-user-environment.drv'...

docker > nmap --version
Nmap version 7.93 ( https://nmap.org )
Platform: x86_64-unknown-linux-gnu
Compiled with: liblua-5.3.6 openssl-3.0.11 libssh2-1.11.0 nmap-libz-1.2.12 libpcre-8.45 libpcap-1.10.4 nmap-libdnet-1.12 ipv6
Compiled without:
Available nsock engines: epoll poll select

您可以透過獲取不同映象的除錯 shell 來確認 `nmap` 現在是您工具箱的一部分

$ docker debug hello-world
...
docker > nmap --version

Nmap version 7.93 ( https://nmap.org )
Platform: x86_64-unknown-linux-gnu
Compiled with: liblua-5.3.6 openssl-3.0.11 libssh2-1.11.0 nmap-libz-1.2.12 libpcre-8.45 libpcap-1.10.4 nmap-libdnet-1.12 ipv6
Compiled without:
Available nsock engines: epoll poll select

docker > exit

`nmap` 仍在其中。

瞭解容器的預設啟動命令(入口點)

Docker Debug 附帶一個內建工具 `entrypoint`。進入 `hello-world` 映象並確認入口點是 `/hello`

$ docker debug hello-world
...
docker > entrypoint --print
/hello

`entrypoint` 命令評估底層映象的 `ENTRYPOINT` 和 `CMD` 語句,並允許您列印、檢查或執行結果入口點。但是,理解 理解 CMD 和 ENTRYPOINT 如何互動 中的所有邊緣情況可能很困難。在這種情況下,`entrypoint` 可以提供幫助。

使用 `entrypoint` 來調查當您從 Nginx 映象執行容器時實際發生了什麼

$ docker debug nginx
...
docker > entrypoint
Understand how ENTRYPOINT/CMD work and if they are set correctly.
From CMD in Dockerfile:
 ['nginx', '-g', 'daemon off;']

From ENTRYPOINT in Dockerfile:
 ['/docker-entrypoint.sh']

By default, any container from this image will be started with following   command:

/docker-entrypoint.sh nginx -g daemon off;

path: /docker-entrypoint.sh
args: nginx -g daemon off;
cwd:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Lint results:
 PASS: '/docker-entrypoint.sh' found
 PASS: no mixing of shell and exec form
 PASS: no double use of shell form

Docs:
- https://docs.docker.net.tw/reference/dockerfile/#cmd
- https://docs.docker.net.tw/reference/dockerfile/#entrypoint
- https://docs.docker.net.tw/reference/dockerfile/#understand-how-cmd-and-entrypoint-interact

輸出告訴您,在 nginx 映象啟動時,會執行一個指令碼 `/docker-entrypoint.sh`,並帶引數 `nginx -g daemon off;`。您可以使用 `--run` 選項測試入口點

$ docker debug nginx
...
docker > entrypoint --run
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/01/19 17:34:39 [notice] 50#50: using the "epoll" event method
2024/01/19 17:34:39 [notice] 50#50: nginx/1.25.3
2024/01/19 17:34:39 [notice] 50#50: built by gcc 12.2.0 (Debian 12.2.0-14)
2024/01/19 17:34:39 [notice] 50#50: OS: Linux 5.15.133.1-microsoft-standard-WSL2
2024/01/19 17:34:39 [notice] 50#50: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/01/19 17:34:39 [notice] 50#50: start worker processes
2024/01/19 17:34:39 [notice] 50#50: start worker process 77
...

這會在您的除錯 shell 中啟動 nginx,而無需實際執行容器。您可以透過按 `Ctrl`+`C` 來關閉 nginx。

直接執行命令(例如,用於指令碼編寫)

使用 `--command` 選項直接評估命令而不是啟動互動式會話。例如,這類似於 `bash -c "arg1 arg2 ..."`。以下示例在 nginx 映象中執行 `cat` 命令,而不啟動互動式會話。

$ docker debug --command "cat /usr/share/nginx/html/index.html" nginx

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

使用 --host 選項進行遠端除錯

以下示例展示瞭如何使用 `--host` 選項。第一個示例使用 SSH 連線到 `example.org` 上的遠端 Docker 例項作為 `root` 使用者,並獲取 `my-container` 容器的 shell。

$ docker debug --host ssh://root@example.org my-container

以下示例連線到不同的本地 Docker Engine,並獲取 `my-container` 容器的 shell。

$ docker debug --host=unix:///some/path/docker.sock my-container