- Docker 教程
- Docker - 首页
- Docker - 概述
- Docker - 在 Linux 上安装
- Docker - 安装
- Docker - Hub
- Docker - 镜像
- Docker - 容器
- Docker - 仓库
- Docker - Compose
- Docker - 操作容器
- Docker - 架构
- Docker - 层
- Docker - 容器与主机
- Docker - 配置
- Docker - 容器与Shell
- Docker - Dockerfile
- Docker - 构建文件
- Docker - 公共仓库
- Docker - 管理端口
- Docker - Web 服务器
- Docker - 命令
- Docker - 容器链接
- Docker - 数据存储
- Docker - 卷
- Docker - 网络
- Docker - 安全
- Docker - 工具箱
- Docker - 云
- Docker - 构建云
- Docker - 日志
- Docker - 持续集成
- Docker - Kubernetes 架构
- Docker - Kubernetes 的工作原理
- Docker - 生成式 AI
- Docker - 托管
- Docker - 最佳实践
- Docker 设置服务
- Docker - 设置 Node.js
- Docker - 设置 MongoDB
- Docker - 设置 NGINX
- Docker - 设置 ASP.Net
- Docker - 设置 MySQL
- Docker - 设置 Go
- Docker - 设置 Rust
- Docker - 设置 Apache
- Docker - 设置 MariaDB
- Docker - 设置 Jupyter
- Docker - 设置 Portainer
- Docker - 设置 Rstudio
- Docker - 设置 Plex
- Docker 设置 - Flame
- Docker 设置 - PostgreSql
- Docker 设置 - Mosquitto
- Docker 设置 - Grafana
- Docker 设置 - Nextcloud
- Docker 设置 - Pawns
- Docker 设置 - Ubuntu
- Docker 设置 - RabbitMQ
- Docker - 设置 Python
- Docker - 设置 Java
- Docker - 设置 Redis
- Docker - 设置 Alpine
- Docker - 设置 BusyBox
- Docker 设置 - Traefik
- Docker 设置 - WordPress
- Docker 有用资源
- Docker - 快速指南
- Docker - 有用资源
- Docker - 讨论
Docker - 容器与Shell
Shell 在 Docker 容器中至关重要;它们充当接口,通过它们在容器中执行命令。通常,当容器启动时,它必须运行一个 Shell 来解释和执行在 Dockerfile 中描述或在运行容器时传递的命令。
Shell 执行几个重要的功能 -
- 命令执行 - Shell 解释和执行在脚本中编写的或用户交互式输入的命令。这包括软件安装、环境配置和应用程序执行。
- 脚本自动化 - Shell 脚本在 Dockerfile 中扮演的最大角色之一是容器环境设置的自动化。它确保所有必要步骤都自动且一致地执行。
- 交互访问 - Shell 允许交互访问容器,允许开发人员和管理员调试、管理和检查容器的环境。这是通过运行命令(例如,docker exec)来针对正在运行的容器交互地完成的,以在其中打开 Shell 会话。
Docker 中常用的 Shell 类型
Docker 容器中使用了相当多的 Shell 类型,它们具有不同的特性和优势 -
Bash(Bourne Again Shell)
- 默认 Shell - Bash 是大多数 Linux 发行版的默认 Shell,并且在 Docker 容器中使用最为广泛。
- 脚本 - 它具有广泛的脚本功能,从变量和循环到条件和函数。
- 丰富的功能 - Bash 提供了命令历史记录、作业控制和制表符完成等功能,增强了交互式使用。
Sh(Bourne Shell)
- 简单性 - 与 Bash 相比,Sh 是一个非常简单的 Shell。它是原始的 Unix Shell,几乎所有类 Unix 系统上都可用。
- 可移植性 - Sh 脚本具有很强的可移植性,几乎可以在任何类 Unix 操作系统上运行。
- 功能较少 - 它不像 bash 那样功能丰富,但这使得脚本通常更容易编写成可移植的。
Zsh(Z Shell)
- 高级功能 - 它拥有 Bash 中不存在的大多数高级功能,例如更好的制表符补全、广泛的脚本功能和高度可定制的提示。
- 自定义 - 它高度可定制,允许用户根据自己的喜好定制 Shell 环境。
- 流行度 - 凭借其强大的功能和自定义功能,Zsh 在开发人员中尤其受欢迎。
访问 Docker 容器中的 Shell
让我们了解访问 Docker 容器内 Shell 的不同方法。
Docker exec 命令(交互式和分离模式)
访问和交互正在运行的 Docker 容器的最佳方法之一是通过 docker exec 命令。它允许在现有容器内启动一个新进程,从而允许执行命令甚至打开交互式 Shell 会话。
交互模式
docker exec 命令与 -it 标志一起使用,以交互方式访问正在运行的容器中可用的 Shell。在这种情况下,-i 表示交互式,-t 分配伪终端。通过这种方式,用户可以与 Shell 交互,就像他们真的登录了一样。
运行正在运行的容器内的 Bash Shell 的示例命令 -
$ docker exec -it <container_id> /bin/bash
在上面的示例中,用实际的运行容器 ID 或名称替换 <container_id>。这会将用户放入容器内的实时 Bash Shell 中,以进行交互和命令执行。
分离模式
除此之外,docker exec 还可以接受以分离方式执行操作的选项 - 执行命令但不将用户附加到进程。这非常适合容器内的所有后台处理或非交互式命令。
分离进程命令示例 -
$ docker exec -d <container_id> <command>
在此示例中,<command> 是您希望在容器内运行的命令,并且由于我们使用了 -d,因此该命令将在后台运行,并且您的命令行与该进程分离。
docker run -it(在容器启动时交互式终端)
当您想要启动一个新容器并以交互方式打开其中的终端会话时,可以使用docker run -it 命令。这在调试、测试或交互式配置新容器时非常实用。
使用 Bash 启动带有交互式 Shell 的新容器的示例命令 -
$ docker run -it <image_name> /bin/bash
在上面的示例中,在 <image_name> 中,您必须包含您想要从中创建容器的 Docker 镜像的名称。然后,选项 -it 使交互式和伪终端分配模式,允许用户直接与容器交互。
nsenter 和其他低级工具
nsenter 是一个低级 Linux 实用程序,用于访问正在运行的进程的命名空间。Docker 容器使用 Linux 命名空间作为隔离;nsenter 用于进入这些命名空间,从而访问容器内部的环境。
使用 nsenter 进入容器命名空间的示例命令 -
1. 首先,获取容器中正在运行的主进程的 PID -
$ docker inspect --format "{{.State.Pid}}" <container_id>
2. 使用 nsenter 访问容器的命名空间 -
$ nsenter --target <pid> --mount --uts --ipc --net --pid /bin/bash
在此示例中,用您在第一步中获得的 PID 替换 <pid>。这将在容器的命名空间内打开一个 bash,并完全访问容器的环境。
使用 Docker Desktop 访问 Shell(GUI)
Docker Desktop 对于 macOS 和 Windows 操作系统来说是一种便利,因为它提供了一个图形用户界面来处理 Docker 容器。因此,Docker CLI 中许多可能很复杂的工作,例如打开容器中的 Shell,都通过其 GUI 简化了。
要使用 Docker Desktop 访问 Shell -
- 打开 Docker Desktop - 从您的应用程序菜单启动 Docker Desktop 应用程序。
- 查看容器 - 点击“容器/应用”选项卡以查看正在运行的容器列表。
- 打开终端 - 只需点击您要连接到的容器,然后点击“CLI”或“终端”按钮。这将打开一个连接到容器的新终端窗口,通常在其中包含一个 Bash Shell。
以非 root 用户身份运行容器
以非 root 用户身份运行容器是一种必要的安全实践。默认情况下,Docker 容器以 root 用户身份运行。这样做会导致如果攻击者进入容器,则会产生高度风险。在容器内运行最低必要的权限有助于减少潜在的损害。
最佳实践
创建非 root 用户 - 使用 USER 指令在您的 Dockerfile 中定义非 root 用户。例如 -
FROM ubuntu:latest RUN useradd -m nonrootuser USER nonrootuser
限制功能 - 通过使用 Docker 的 --cap-drop 和 --cap-add 选项来删除不必要的权限,从而限制容器的功能。
文件系统权限 - 确保文件系统权限设置正确,以防止未经授权访问敏感文件和目录。
结论
在本章中,我们讨论了如何访问容器 Shell。我们查看了不同类型的 Shell 以及访问每个 Shell 的命令。如果您想检查 Docker 容器内部发生了什么,或者如果您想在容器中运行命令,这些命令将非常有用。
关于 Docker 容器与 Shell 的常见问题
1. 如果 Docker 容器没有 Shell,我该怎么办?
有时容器镜像会故意不带 Shell 以保持镜像大小较小。在这种情况下,您可以执行以下操作:使用安装了 Shell 的新层提交正在运行的容器,然后基于此修改后的镜像启动一个新容器。
您可以使用Docker cp 命令或以其他方式将 Shell 二进制文件复制到容器中。更高级的是使用nsenter 相对直接地访问现有容器的命名空间。
2. 访问 Docker 容器 Shell 是否有任何替代方法?
是的,除了直接访问之外,还有其他方法可以与容器交互。例如,可以使用 docker logs 查看容器输出,使用 docker inspect 检查容器详细信息,或使用 docker stats 检查资源使用情况。
专用的工具(例如带有调试器附加的 docker exec)可以实现这种调试可能性,或者当需要深入分析正在运行的进程时,可以通过 strace 和 gdb 实现。最终,最佳方法将取决于您的需求以及您的任务需要多少访问权限。