1. 概述

TTY(Teletypewriter)指的是任何可以发送和接收输入输出的终端设备。Docker 是一种操作系统级的虚拟化平台,常用于开发、打包、分发和运行容器化应用。我们可以通过一个交互式的伪 TTY 连接到正在运行的 Docker 容器,从而访问其内部的操作系统。

本文将介绍几种方式通过 TTY 进入一个正在运行的 Docker 容器。前提是你已经在支持的系统(如 Linux、Windows)上安装了 Docker。

我们会介绍几种常见的方法,你可以根据具体场景选择最合适的一种。

2. 启动容器时进入 TTY

我们可以在启动容器时使用 docker run 命令并加上 -it 参数来打开一个交互式 TTY 终端。-i 表示保持标准输入打开,-t 表示分配一个伪终端。

以 MySQL 容器为例,启动时直接进入 bash:

$ docker run \
--name mysql \
-it \
-e MYSQL_ALLOW_EMPTY_PASSWORD=yes \
mysql:8.4 bash

进入后会看到类似如下提示:

bash-5.1#

小贴士:这种方式适合在容器启动时就希望立即进入交互环境调试的场景。


3. 容器已运行时进入 TTY

如果容器已经在运行,我们可以使用 docker exec -it 命令连接到该容器的 TTY。

先启动一个后台运行的 MySQL 容器:

$ docker run \
--name mysql \
-e MYSQL_ALLOW_EMPTY_PASSWORD=yes \
-d \
mysql:8.4

输出是容器的 ID:

0b48ce54a9b409a291072fd9d517ccf77267f24a528a2894cb213d1201bf0029

确认容器正在运行:

$ docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                 NAMES
0b48ce54a9b4   mysql:8.4   "docker-entrypoint.s…"   17 seconds ago   Up 17 seconds   3306/tcp, 33060/tcp   mysql

然后连接到容器:

$ docker exec -it mysql bash

进入后会看到 bash 提示符:

bash-5.1#

我们可以在这个终端中执行 MySQL 命令:

bash-5.1# mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.4.4 MySQL Community Server - GPL

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

适用场景:适合调试、查看日志、临时执行命令等操作。


4. 对于运行后立即退出的容器使用 TTY

有些容器在启动后会立即退出,比如基于 Ubuntu 的镜像,执行完 echo "Hello World" 后就会退出。

例如:

$ docker run \
--name ubuntu-demo \
ubuntu \
echo "Hello World"

我们可以使用 -it 参数配合 /bin/bash 启动一个交互终端:

$ docker run \
-it \
--name ubuntu-demo \
ubuntu \
/bin/bash -c "echo 'Hello World'; /bin/bash"
Hello World
root@0e4625c6d38d:/#

这样就能在容器退出前进入交互终端。


5. 使用 sleep 命令让容器保持运行

如果我们希望容器运行一段时间以便我们连接,可以使用 sleep 命令让它“休眠”一段时间。

启动一个 Ubuntu 容器并让它运行 10000 秒:

$ docker run \
-d \
--name ubuntu-demo \
ubuntu \
/bin/bash -c "echo 'Hello World'; sleep 10000"

确认容器运行状态:

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
84726b32ca27   ubuntu    "/bin/bash -c 'echo …"   7 seconds ago   Up 6 seconds             ubuntu-demo

然后连接 TTY:

$ docker exec -it ubuntu-demo bash

进入后可以执行 Linux 命令,比如列出目录:

root@84726b32ca27:/# ls -l
total 48
lrwxrwxrwx   1 root root    7 Apr 22  2024 bin -> usr/bin
drwxr-xr-x   2 root root 4096 Apr 22  2024 boot
drwxr-xr-x   5 root root  340 Jan 27 13:03 dev

技巧sleep 命令非常适合用于临时保持容器运行状态,方便调试。


6. 使用 cat 命令监听输入

我们也可以使用 cat 命令来监听用户输入并回显。适合测试终端交互。

例如启动一个 Ubuntu 容器并进入 TTY:

$ docker run \
-it \
--name ubuntu-demo \
ubuntu \
/bin/bash -c "echo 'Hello World'; cat"

容器输出:

Hello World

然后你可以输入一些内容,它会直接回显:

Hello
Hello

Hi
Hi

7. 使用 tail -f /dev/null 监听输入

我们也可以使用 tail -f /dev/null 让容器持续监听输入,适合保持终端打开。

启动容器:

$ docker run \
-it \
--name ubuntu-demo \
ubuntu \
/bin/bash -c "echo 'Hello World'; tail -f /dev/null"

输出:

Hello World

然后输入内容会被显示:

Hello
Hi

踩坑提醒:如果你只是想让容器保持运行,tail -f /dev/null 是一个很常用的技巧。


8. 在 Windows 容器中使用 TTY

在 Windows 容器中也可以使用 TTY,只是终端程序不再是 bash,而是 cmd.exe

例如启动一个 Windows Nano Server 容器并进入 TTY:

$ docker run \
-it \
mcr.microsoft.com/windows/nanoserver:ltsc2022 \
cmd.exe

你会看到 Windows 命令行提示:

Microsoft Windows [Version 10.0.20348.2849]
(c) Microsoft Corporation. All rights reserved.

C:\>

注意:Windows 容器需要 Windows 系统作为宿主机,并且 Docker 需要切换到 Windows 容器模式。


9. 总结

本文介绍了多种方式通过 TTY 进入 Docker 容器,包括:

  • 启动容器时直接进入 TTY
  • 容器运行后通过 docker exec 进入
  • 对于自动退出的容器使用 -it + bash
  • 使用 sleepcattail -f /dev/null 等命令保持容器运行
  • 在 Windows 容器中使用 TTY

这些方法可以根据不同的调试和运维场景灵活使用。

所有示例命令都可以在 GitHub 上找到。


原始标题:How to Enter a Running Docker Container With a TTY